Jump to content

Any way to attach persistent data to objects?


Recommended Posts

So, followed by this topic I managed to add some extra custom data to objects, and later on read and use them.

Now here's the problem. These data are lost whenever a server is restarted ( not regenerated ) or even rolled back. So basically they seem to only exist on host's RAM. is there anyway to force them to be stored in snapshots? Or do I have to create new custom files and save the data there ( I might just give up on the mod! )

Any clue is appreciated.

Edited by JackJohnsn
Link to comment
Share on other sites

Every data is reset when loading the game. Only the stuff directly added in master/common post init is added again.
To save/load stuff there are OnSave and OnLoad functions for instances and also for components.
They save and load some data. Saving whole instances it not possible, instead you are saving the GUID and a reference. Everyhting else, like strings, numbers, lists are easy to save and load.

So first of all decide if you want something to be saved within the inst or within a component.
The code looks a bit different, for whatever reason.

Code to save load more stuff within a component:

AddComponentPostInit("thecomponentyouwanttochange",function(self)    
    local old_OnSave = self.OnSave
    local function new_OnSave(self,...)
        local data = {}
        if old_OnSave~=nil then 
            data = old_OnSave(self,...) -- call the old onsave to get the already saved data
        end
        data.mycustomdata = self.mycustomdata -- simply add your data (currently within the component) to the data list
        return data 
    end
    self.OnSave = new_OnSave
    
    local old_OnLoad = self.OnLoad
    local function new_OnLoad(self,data,...) -- "..." is used to also load also all other parameters we are currently not interested in, if there are any.
        if data~=nil then -- if something was loaded
            self.mycustomdata = data.mycustomdata
        end 
        if old_OnLoad~=nil then 
            return old_OnLoad(self,data,...)
        end 
    end
    self.OnLoad = new_OnLoad

end)

And for instances the OnSave looks a bit different:

AddPrefabPostInit("yourprefab",function(inst)
    
    local old_OnSave = inst.OnSave
    local function new_OnSave(inst,data,...)
        data.mycustomdata = inst.mycustomdata -- simply add your data (currently within the instance) to the data list
        if old_OnSave~=nil then old_OnSave(inst,data,...) end -- call the old, if there is one. no need to return data
    end
    inst.OnSave = new_OnSave
    
    local old_OnLoad = inst.OnLoad
    local function new_OnLoad(inst,data,...) -- "..." is used to also load also all other parameters we are currently not interested in, if there are any.
        if data~=nil then -- if something was loaded
            inst.mycustomdata = data.mycustomdata
        end 
        if old_OnLoad~=nil then 
            return old_OnLoad(inst,data,...)
        end 
    end
    inst.OnLoad = new_OnLoad
    
end)

I just wrote this without testing, so test if it works and report back :D

Edited by Serpens
Link to comment
Share on other sites

Thanks for the answer. Just one question. Let's say I plant a berry bush ( talking about this topic ) and I attach some data to that berry bush instant. Now I want to restore that data while loading the game. You mentioned something about GUID and reference, so how can I access those data so I can only restore that specific data for that specific individual bush that I've planted? ( not every bush in the world )

Link to comment
Share on other sites

8 hours ago, JackJohnsn said:

Thanks for the answer. Just one question. Let's say I plant a berry bush ( talking about this topic ) and I attach some data to that berry bush instant. Now I want to restore that data while loading the game. You mentioned something about GUID and reference, so how can I access those data so I can only restore that specific data for that specific individual bush that I've planted? ( not every bush in the world )

you need the GUID only, if you eg want to save the whole bush with all of its data within something else, eg. in your character.
If you only want to save a number or string inside the bush, you dont need GUID and such stuff and the code above should work for every bush (or anything else).
If it does not work, test the code with your character or attach sth to a bush with console and test if your code can save it. Because the "ondeploy" thing we already mentioned that it might not work. So first find out why it does not work.

Link to comment
Share on other sites

Sorry that I'm bothering too much, but I'm really confused what do onSave and onLoad do. If it runs under AddPrefabPostInit, Doesn't it mean that it will run only once when the bush's code is loaded into the world? Or does it run for each single bush?

Let's say I have 2 bushes, BushA and BushB. I can save different data for each of these? It means that using

local function new_OnLoad(inst,data)
  inst.mycustomdata = data.mycustomdata
end

will load different values for each so I can pass them to onDeploy? The reason I can't properly try it is that I don't know how it works :D

Link to comment
Share on other sites

8 hours ago, JackJohnsn said:

Sorry that I'm bothering too much, but I'm really confused what do onSave and onLoad do. If it runs under AddPrefabPostInit, Doesn't it mean that it will run only once when the bush's code is loaded into the world? Or does it run for each single bush?

Let's say I have 2 bushes, BushA and BushB. I can save different data for each of these? It means that using


local function new_OnLoad(inst,data)
  inst.mycustomdata = data.mycustomdata
end

will load different values for each so I can pass them to onDeploy? The reason I can't properly try it is that I don't know how it works :D

AddPrefabPostInit is for every thing executed that has this prefab, after the initializaion, but still part of initalization.
But "inst" is an individual object. And although every inst has the mycustomdata entry, the value of this can be different for every single inst.
OnLoad is executed by the game itself after the initialization. So it does not matter what values are defined within common/masterpostinti and within AddPrefabPostIni, they get overwritten in Onload, if there is code in OnLoad to overwrite them (and it was previously saved in OnSave).

Edited by Serpens
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...