Jump to content

Saving tables and variables


Phodex Games
 Share

Recommended Posts

Hi Leadwerkers smile.png,

 

Currently I am figuring out what would be the best way to save my game. What options there are for saving a table or varibles in general, and what options have you come up with?

 

What I am working on at the moment was, to write a savedata table into a file like this and call it back with "dofile":

 

return
{
someData = "Test";
someOtherData = "Tes2t";
}

 

But this method is pretty tricky, not only have do you have to convert the variables into strings to save them, but it also is complicated and I think its no clean and fast solution because you have to work with the stream and filesystem command and "manually" write your data into a lua file.

There is the System:SetProperty() command, but there you only can save strings as well. Are there any other commands Leadwerks offers? Another engine I worked before had a save command, where you can save any lua variable in (tables, strings, numbers everything) and then call it back.

 

So tell me your attempt, what have you come up with? I want a system, where I just say: Save that variable and load that variable back on demand. If leadwerks does not offer such function itself I would be very thankful if you can link me tutorials, ideas or anything else which helps me building my own savesystem.

 

Sorry if the english is not perfect biggrin.png

 

Phoenix

Link to comment
Share on other sites

Not of the actual saving side but I had before code that loops over all loaded entities and would call a LoadData() script function if existed after the map load passing in the table that was saved. Then each entity has the chance to get the data it needs to read and set. You still have to code the logic in LoadData() for each entity but to read and set the variable in that script. Then they had a SaveData() as well that allowed the script to save any data it needed to. Now each script controls what it writes and reads. Passed into these functions is the table that you read from or write to. Then how you do the actual loading to a table or reading from a file to a table can change without affecting your scripts.

Link to comment
Share on other sites

Why can't you make a table of all needed data and loop through it to save each table key and value into file?

Remember that these two lines refer to the same variable:


myTable.abc

myTable["abc"]

 

Try something like this:


for k,v in pairs(myTable) do

stream:WriteLine(k.."="..v)

end

This way you will get a file like this:

health=35

armor=20

magic=110

 

To load this data into the game you need to read each string, separate it by "=" symbol and use left part as key and right as value.


data={}

while (not stream:EOF()) do

local s = stream:ReadLine()

local i = string.find(s,"=")

local k = string.sub(s,1,i-1)

local v = string.sub(s,i+1)

data[k]=v

end

I haven't actually tried this code, so there can be mistakes.

I believe you won't even need to convert value from string to number, it should be converted automatically if used in calculation. But you can also use tonumber function http://www.lua.org/manual/5.1/manual.html#pdf-tonumber

 

You can also use string value to access global table itself because every global variable is an element of _G table. These two lines also refer to the same variable:


myT.a

_G["myT"]["a"]

 

So you can make a header in your save file like this:

[player]

health=10

magic=20

 

And when you read a string that starts with "[" you can use it as a name of table which you are going to fill with data.


if string.sub(s,1,1) == "[" then

local tableName = string.sub(s,2,string.len(s)-1)

...

_G[tableName][k]=v

Link to comment
Share on other sites

Whoa a lot of information. Awesome!. May I ask how to

 

1)Get entity unique id ? If I have 10 crawlers how do we know which is which when saving and loading ?

2)How to get the animation state of a crawler and make it continue playing that animation after loaded. Example the crawler is playing attack animation and at the frame no15 , when loaded it back it should continue playing attack animation at frame no15.

Link to comment
Share on other sites

1)Get entity unique id ? If I have 10 crawlers how do we know which is which when saving and loading ?

Great question, we need a value that is the same each time you load a map, but is unique for every entity. MAYBE if Start execution order is always the same, then you can assign id yourself, but I doubt. This is probably not reliable.


function Script:Start() {

if not IDCounter then IDCounter = 0 end

self.ID = IDCounter + 1

IDCounter = IDCounter + 1

...

Or just by entities order with world:GetEntity() if it's always the same.

 

2)How to get the animation state of a crawler and make it continue playing that animation after loaded. Example the crawler is playing attack animation and at the frame no15 , when loaded it back it should continue playing attack animation at frame no15.

I don't think you can do this with new animation commands. Strange, there is SetAnimationFrame but no GetAnimationFrame.

But you can do it with old AnimationManager script.

Link to comment
Share on other sites

@Genebris, Thank you for your reply. I think the unique Id for the crawler right now is their positions ?But if leadwerks is also exposing the unique id for the entity is better I think. Regarding the GetAnimationFrame, yeah its been bothering me for quite some time.

 

Thanks again.

  • Upvote 1
Link to comment
Share on other sites

When talking about enemies you need to really think them through. Should you really place them at design time or run-time. If placed at design time do they really need to have data saved? Think mario. Those enemies are placed at run-time but they aren't saved between saves. A level starts fresh every time. What example do you have where this would be needed at design time and you can't just have them reset where they were when placed at design time each time?

Link to comment
Share on other sites

Why can't you make a table of all needed data and loop through it to save each table key and value into file?

Remember that these two lines refer to the same variable:


myTable.abc

myTable["abc"]

 

Try something like this:


for k,v in pairs(myTable) do

stream:WriteLine(k.."="..v)

end

This way you will get a file like this:

health=35

armor=20

magic=110

 

To load this data into the game you need to read each string, separate it by "=" symbol and use left part as key and right as value.


data={}

while (not stream:EOF()) do

local s = stream:ReadLine()

local i = string.find(s,"=")

local k = string.sub(s,1,i-1)

local v = string.sub(s,i+1)

data[k]=v

end

I haven't actually tried this code, so there can be mistakes.

I believe you won't even need to convert value from string to number, it should be converted automatically if used in calculation. But you can also use tonumber function http://www.lua.org/manual/5.1/manual.html#pdf-tonumber

 

You can also use string value to access global table itself because every global variable is an element of _G table. These two lines also refer to the same variable:


myT.a

_G["myT"]["a"]

 

So you can make a header in your save file like this:

[player]

health=10

magic=20

 

And when you read a string that starts with "[" you can use it as a name of table which you are going to fill with data.


if string.sub(s,1,1) == "[" then

local tableName = string.sub(s,2,string.len(s)-1)

...

_G[tableName][k]=v

 

Thanks I definetly learnt something new about lua smile.png. I always wondered if it is possible to get a variable by its name per string. However your solution sounds very good, I will try that out for my save script smile.png. The problem I had, was that I needed to also access an element within the table and I struggled figuring out a way to search for a keyword within the file. So for example in the player save table (say there is position, health, rotation, current level etc) I just want to overwrite the healt value.

 

But I have a question. What does string.sub exactly do?

Link to comment
Share on other sites

The problem I had, was that I needed to also access an element within the table and I struggled figuring out a way to search for a keyword within the file.

what's the problem?


local name = "health"

while (not stream:EOF()) do

local s = stream:ReadLine()

local i = string.find(s,"=")

local k = string.sub(s,1,i-1)

if k==name then break end

end

--here is your line

 

But I have a question. What does string.sub exactly do?

You give it string and two indexes, it returns part of the string between them.

Link to comment
Share on other sites

I forget...does loading additional LUA libraries mean you can't use sandbox and can't deploy to player?

 

 

It depends on the library. If it's pure Lua and doesn't use require() or load library then you can use it in sandbox. Since the goal of this post is to write to disk then it pretty much means you can't use sandbox anyway. Technically this library could be used in sandbox but it's fairly worthless to do so since you want to use it to save data to disk which means using it in non sandbox,

 

Unfortunately yes.

 

Not true. Some very useful Lua libraries are pure Lua and don't load dls. The tween library I use and the behavior tree library I use can be used in sandbox. They often need to be edited first as josh has removed the ability to use require() in sandbox which almost all Lua libraries use to get loaded. So in change them so they can use import instead.

  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...