Jump to content

Need SaveGame Help


Slimwaffle
 Share

Recommended Posts

So I grabbed a savegame script from workshop that was an old one from Rick. I have been trying to get it to work within my game. But I am having issues. If the save script finds entities of the same name it only saves one entity and ignores the remaining. And for some reason it is setting the position of all saved entities to the one location. I really need help on this one guys. I will post the 3 scripts here and a video showing what happens. I need each entity regardless of if it has the same name to save and load to its own unique position and rotation. And the video in Ricks link for the script is dead. 

I can't figure out a solution for the naming issue. As for the everything to one location I was thinking some kind of pick might work.

GenericItem.lua

SaveGame.lua

TableSaveLoad.lua

Link to comment
Share on other sites

No need to go with C++ as you can do the same things with just writing to a file using the build in leadwerks commands. Alternatively you can load in a lua to json library to make things a little easier. This one for instance: https://github.com/rxi/json.lua Remember to turn of sandbox lua in the editor settings.

As for the scripts you are using, you can try altering the code so that it doesn't just use the entities name as a key, but also adds a pre/postfix. So if you have 2 oilbarrels, they would be saved as oilbarrel_1, oilbarrel_2. When loading the data, you can remove the _1 etc from the name again.

  • Like 1
Link to comment
Share on other sites

It's been awhile since I created that, but the entity script LoadData() function passes in the table structure that you saved the data in. In your GenericItem you aren't doing that and you aren't using that. You're using entityTable variable which really is a global variable that you created in SaveData() which is a bad idea. Don't use globals like that. So the steps to try to fix would be.

 

1. In SaveData change the creation of entityTable to have local in front of it (local entityTable = {}) so that it's just local to the function instead of global to the entire application.

2. Put a parameter to Script:LoadData() so it looks like Script:LoadData(data). This data parameter is the data that was saved originally. It gets loaded in the same structure you saved it as. This means you don't use entityTable[2]. Instead you'd do data[2]. However, I'd advise you store the data in named variables instead of array indexes for easier reading. So in SaveData() do something like entityTable.name = name, entityTable.pos = pos, etc. Then read it back in data.name, data.pos.

 

function Script:SaveData()

	prefab = self.entity:GetKeyValue("prefab")
	name = self.entity:GetKeyValue("name")
	pos = self.entity:GetPosition()
	rot = self.entity:GetRotation()
	
	local entityTable ={}
	entityTable.name = name
	entityTable.pos = pos
	entityTable.rot = rot
	entityTable.prefab = prefab

	System:Print("Object"..name.. "At" ..rot.x)
	return entityTable
end
function Script:LoadData(data)

	rot = data.rot
	pos = data.pos
	self.entity:SetRotation(rot)
	self.entity:SetPosition(pos)
	System:Print('Entity Loaded')
end

 

But as far as the names go, you have to have unique names. How is it supposed to know the difference between 2 entities if they have the same name?

  • Like 1
Link to comment
Share on other sites

OMG thank you soo much guys. Absolute lifesavers. This has helped me greatly. Getting a working save and load is the last Major thing I have left on this project.

And I will let you guys know how I go with the prefix thing.

I am thinking something along the lines of adding a count variable to the world loop and changing the name of each item in the save using the loop.

So for example; first time it loops it finds entity with name Wood Roof and saves it as Wood Roof 1, second time it loops finds another Wood Roof Entity and saves it as Wood Roof 2 and continues on until the loop is finished.

Or even making a global variable called count1 that increases each time the code for crafting creates an object and then resetting entity name to (name + count1)

  • Like 1
Link to comment
Share on other sites

So I fixed pos and rot using this set up. I still have yet to try the name thing.

function Script:SaveData()

    prefab = self.entity:GetKeyValue("prefab")
    name = self.entity:GetKeyValue("name")
    pos = self.entity:GetPosition()
    rot = self.entity:GetRotation()
    
    local entityTable ={}
    entityTable.name = name
    entityTable.posx = pos.x
    entityTable.posy = pos.y
    entityTable.posz = pos.z
    entityTable.rotx = rot.x
    entityTable.roty = rot.y
    entityTable.rotz = rot.z
    entityTable.prefab = prefab

    System:Print("Object"..name.. "At" ..rot.x)
    return entityTable
end
function Script:LoadData(data)

    r1 = data.rotx
    r2    = data.roty
    r3    = data.rotz
    p1 = data.posx
    p2    = data.posy
    p3    = data.posz
    self.entity:SetRotation(r1,r2,r3)
    self.entity:SetPosition(p1,p2,p3)
    System:Print('Entity Loaded')
end

Link to comment
Share on other sites

Yeah, the Vec3() might not save correctly so breaking them up is probably best or creating your own lua table to store them vs the Vec3 with:

entityTable.pos = { x = pos.x, y = pos.y, z = pos.z }

 

Not 100% sure though. It's been awhile.

  • Like 1
Link to comment
Share on other sites

I have this working perfectly now. Soo Frigging Happy :D Thanks so much guys. Now It is setting a unique name each time it calls the save function. 

Here is what the code looks like in case anyone is wanting to do more with these scripts. You Just need to create a global called count1 somewhere with a value of 0.

function Script:SaveData()
    count1 = (count1 + 1)
    txt1 = (tostring(count1))
    System:Print(txt1)
    prefab = self.entity:GetKeyValue("prefab")
    self.entity:SetKeyValue("name", txt1)
    name = self.entity:GetKeyValue("name")
    pos = self.entity:GetPosition()
    rot = self.entity:GetRotation()
    
    local entityTable ={}
    entityTable.name = name
    entityTable.posx = pos.x
    entityTable.posy = pos.y
    entityTable.posz = pos.z
    entityTable.rotx = rot.x
    entityTable.roty = rot.y
    entityTable.rotz = rot.z
    entityTable.prefab = prefab

    System:Print(name..' Saved')
    return entityTable
end
function Script:LoadData(data)

    r1 = data.rotx
    r2    = data.roty
    r3    = data.rotz
    p1 = data.posx
    p2    = data.posy
    p3    = data.posz
    self.entity:SetRotation(r1,r2,r3)
    self.entity:SetPosition(p1,p2,p3)
    System:Print('Entity Loaded')
end

  • Like 2
Link to comment
Share on other sites

Glad you got it working. I always wondered why LE didn't have this load/save mechanism built in. I know Josh said he didn't want to get into that area because saving is unique per game, but this general idea of Load/Save callbacks per script is flexible enough to let the developer decide what is saved and loaded while still giving some kind of common structure to do it at least. Glad someone got some use from the script.

Link to comment
Share on other sites

One that I think would be a great one to implement. Is a global save and load script. That works similar to WorldUpdate(). To basically get the entire world state on save and then return it when loaded.

And thanks heaps mate. I will definitely get use out of it. I will most likely continue to use it on new projects until a better system is implemented straight into the engine.

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...