[SCRIPTING] Save games and Lua, Homeworld RPG

Do save games store all the Lua variables currently in memory? Or does it just store object positions, the build queue, orders, etc.?

I’m thinking of reviving my Mission Grid mod that acts more like an RPG and has a galactic map that you can travel around. The mod currently writes its own state information to disk in order to keep track of your current location, quests, etc… But having this file interferes (I think) with the existing save function.

1 Like

There’s already a script system doing so, the one used in Trading Mode of Fairy Empire Mod

In the upcoming patch the ability to do many file/system functions is greatly restricted (no exec, no file open/close with an arbitrary path). However, now if you use a file it will be based in the user’s current profile sub-folder - making ‘per user’ status for custom code, campaigns, state - much MUCH easier. Working with Profiles isn’t exactly the same thing as working with Save Games, but I can actually imagine way to make it work really well. I’ve never looked at the Fairy Empire Mod or this extended data system - but I may be able to help prototype some ‘best practice’ systems for a hybrid profiles & save-games system that would make RPGs (and similar) well behaved.

I suppose it’s what you were telling me when we briefly talked about my UI thingies. From what I understand, we will still be able to create files, but only in the current profile sub-folder ? This is PERFECT for me, as there was no other way before other than by hack to find the current folder. Thumb up if that’s the case :slight_smile:
Edit : is the “dir” function still available or not ? Just asking mainly to know if it will still be possible to find files in the badge folder for example ?

I think ‘dir’ was done via exec - so no. No DOS or similar commands of any sort function - it was a rather serious security hole when you think about it. Ditto for files - they’re forced into the user’s profile path for security - with the additional plus of making Mods now ‘per profile’ was used to be nearly impossible.

Basically, the system used in Fairy Empire MOD uses stargate to connect different maps. The game will use writeto() function to write all the information about how much money do you have, how many ships and goods in your fleet and which map you are going to into a single lua file when you click a stargate ingame. Then the game will reload, dofilepath() that lua file, determine which map file to load and restore your fleet.
I think if the new system allows us to create files into current profile sub-folder, we can still do what we did just in a similar way using those new functions.

Well, though I don’t know what you mean by “hack”, we have a very simple function to help find which profile sub folder the player is using.

function LW_getProfileID()
	if (ProfileID==nil) then
		_ALERT("Creating ProfileID.lua ...")
		ProfileID = -1
		local iProfileID = 1
		while ((ProfileID+1)~=iProfileID) do
			o_handle = writeto("../Profiles/Profile"..iProfileID.."/ProfileID.lua")
			if (o_handle~=nil) then
				write(o_handle, "ProfileID = "..iProfileID)
				_ALERT("Created ProfileID.lua for Profile"..iProfileID)
			iProfileID = iProfileID + 1
		_ALERT("using ProfileID="..ProfileID)

Couple of comments.

506933395: I don’t understand how you determined which is the correct profile in use, in case there are multiple profiles? Your example is confusing because you have three identifiers and one file that are named nearly the same.

bitvenom: the problem is that if you are saving data in two places (normal save game and profile) they will quickly go out of sync if the player starts/saves/loads missions a lot. If we could define stuff that for sure gets saved in the same place, it would help. Also, here’s the demo I created for HW2 that demonstrates what I had in mind:


Basically, you write a file named “ProfileID.lua” into Profiles/Profile1/, which contains “ProfileID = 1”, then try dofilepath(“Player:ProfileID.lua”), to see if you get the ProfileID variable read correctly. If ProfileID become not nil, then it means the player is using profile1. If ProfileID is still nil, it means the player is not using profile1. So then we create a “ProfileID.lua” in Profiles/Profile2/ which contains “ProfileID = 2”, then try dofilepath(“Player:ProfileID.lua”), to see if you get the ProfileID variable read correctly.
So finally, you will get a variable named ProfileID which is the profile number the player is using.

And as for the saved files getting out of sync, we choose to only allow player save the game when he/she jumps from one map to another using a stargate, which means we have much less information to store (only number and type of all ships, which map to load the next time, plus things like money and goods, no need to save ships’ positions in the map)

And you can have a look at Fairy Empire mod to see how it does all those things:

What if multiple profiles have the flag set? How do you tell that the player is currently using Profile2 or Profile3 when at some point in the past he played the mod using Profile1?

If the player has played my mod using profile1, and now he want to use profile2 to play again, then the mod will first dofilepath(“Player:ProfileID.lua”). Since he is using profile2 now and there’s not a file named ProfileID.lua in his Profiles/Profile2/, the variable named ProfileID will still be nil. So the mod will still try to create a ProfileID.lua containing “ProfileID = 1” in Profiles/Profile1/, then dofilepath(“Player:ProfileID.lua”). And ProfileID is still nil. So then create a ProfileID.lua containing “ProfileID = 2” in Profiles/Profile2/, dofilepath(“Player:ProfileID.lua”). Now you get a ProfileID whose value is 2.

The only problem will happen if a player copy his “profile1” folder from his another computer and rename it to “profile2” to his new computer. This makes our mod thinks he is using profile1 since the ProfileID.lua in his profile2 indeed contain “ProfileID = 1”.

Ok, thanks for the confirmation. I have another way to do it, with a text file listing the badges.
I thought about your concern for security after our first discussion, and it was effectively very dangerous…

I use something even simplier : I read the local.ini file :slight_smile:
(the first read() is just here to “eliminate” the [] on the first line)

    sui_currentprofilefolder = gsub(read(), "currentprofile=", "");

@Bitvenom : is the read method (standard lua command) still available ?

Oh, that’s really cool code! Never think about using the standard read() function!

feel free to use it if you need to :wink:

No - you can ONLY read/write/create from the current Profile folder.

so you’ve created some specific commands/functions for us to be able to do those kind of things I suppose ?

No, just all of the pathing logic inside of things like readfrom/open forces that - or fails.