Jump to content

(Question) How to save something between server restarts?


Rinart73

Recommended Posts

I can't find anything to write something to the server database. How can I do that?

 

Actually, I just need to attach Lua table to every Entity. And I need to save this tables between server restarts.

I read about 'secure' and 'restore' Entity methods, but I'd like to see some examples. I just can't understand how to attach it.

Link to comment
Share on other sites

There are several options:

 

you can either save values for a specific script instance via this functions (looky here http://avorion.gamepedia.com/Entity_scripts):

- secure()

- restore()

 

HowTo: in secure() just return some variables and define exactly those for your return() function as parameters (have a look at the code of the showdist mod for an example)

 

or you could set and get values via the "property bag" of Server(), Sector(), Player(), Entity():

- setValue(key, value)

- getValue(key)

 

 

Link to comment
Share on other sites

Thanks. I understand how to use 'secure' and 'restore', but I can't understand where to put them.

 

I mean, for example we have a defined class "Person" with some methods and callbacks like "onFirstStep". And if we want to "say hi", when user makes his first step:

1. We will make a new class that extends "Person" and overrides "onFirstStep".

2. Or we'll just change "Person" definition.

 

I'm not very familiar with the Lua, but in our case we don't have definitions for classes and structures, for "Entity".

So, what should I do, just put 'restore' and 'secure' in a random place in a random file and wait it to 'fire'? I don't think  that's a good idea.

Also I don't want to extend and override Entity structure. That's a bad idea too.

-

You gave me link, but showdist mod has nothing to do with 'secure'.

Link to comment
Share on other sites

Thanks. I understand how to use 'secure' and 'restore', but I can't understand where to put them.

 

I mean, for example we have a defined class "Person" with some methods and callbacks like "onFirstStep". And if we want to "say hi", when user makes his first step:

1. We will make a new class that extends "Person" and overrides "onFirstStep".

2. Or we'll just change "Person" definition.

 

I'm not very familiar with the Lua, but in our case we don't have definitions for classes and structures, for "Entity".

So, what should I do, just put 'restore' and 'secure' in a random place in a random file and wait it to 'fire'? I don't think  that's a good idea.

Also I don't want to extend and override Entity structure. That's a bad idea too.

-

You gave me link, but showdist mod has nothing to do with 'secure'.

 

sry, was the wrong link: https://github.com/w00zla/avorion-showdist/blob/master/scripts/player/cmd/showdistjump.lua

 

and for the rest aka LUA coding techniques:

LUA has no (built-in) concept of OOP and therefore overriding of classes/functions is not possible (there arent even classes in the OOP sense!).

Avorion/LUA works by attaching scripts to different game world objects (=entities), which makes those scripts run in the context of the entity (i.e. player scripts are active while player is online, ship scripts are active while ship-entity is not destroyed etc.).

You MUST define the secure() and restore() functions (and lots of others depending on their actual intention) in a script attached to an entity for them to work properly (look here how scripts are attached).

Link to comment
Share on other sites

Avorion/LUA works by attaching scripts to different game world objects (=entities), which makes those scripts run in the context of the entity (i.e. player scripts are active while player is online, ship scripts are active while ship-entity is not destroyed etc.).

You MUST define the secure() and restore() functions (and lots of others depending on their actual intention) in a script attached to an entity for them to work properly (look here how scripts are attached).

 

Ok, thanks, I'm beginning to understand. Probably I should attach scripts to Entities in a callback events like onPlayerLogIn, onEntityCreate e.t.c.?

But now I have another question - When I should attach the script?

 

I mean, for example I want to mess with a stations like factories or trading posts. Where should I attach my script? Earlier (when the sector just loaded) or just before user interacts with Entity.

I mean, how I can be sure that I'll get some data from 'restore' just after I attached script to the Entity?

Or its how it works? When you attach script, game instantly retrieves some data for it?

Link to comment
Share on other sites

I think it depends specifically on what you want to do. My mod, Infinion Irregular Goods Transportation uses a script on the player to register and handle onSectorEntered events.

That event handler searches all ships in the sector and finds any with entity/antismuggle.lua and removes that script and adds a customised version (mods/infinionigta/antismuggle.lua)

 

If I needed to save any data for the military ships, I would do it with secure/restore in the custom antismuggle script. If I needed to save data relevant to the player, I would do it in the player script.

 

 

I don't know exactly what you're trying to achieve but it sounds like you would do something similar. When the player enters a sector, check all of the stations to see if any you're interested in: a) exist , and b) have your custom script.

If not, add the custom script.

In the custom script, save any data relevant to the station.

Link to comment
Share on other sites

Thanks, I'm going to the finish.. gradually.

 

I'm trying to add some custom variables that're accessible after restart to the all Stations and Ships made by players in the sector. So I think I should  do all checkings and attach script in the Sector's "onEntityCreate" callback or in defaultscripts.lua.

But then I need to access this local script variables in some vanilla scripts, that were attached to this ship/station too.

 

I don't think that variables from one attached script are visible to another attached script. Because it shouldn't be. So I think to complete my first mod for this game I just need to understand how people use variables from attached scripts anywhere.

Maybe its something related to 'require', but I don't need to require a whole script again.

 

I'll try to search in existing mods again.

Link to comment
Share on other sites

I don't think that variables from one attached script are visible to another attached script. Because it shouldn't be. So I think to complete my first mod for this game I just need to understand how people use variables from attached scripts anywhere.

Maybe its something related to 'require', but I don't need to require a whole script again.

 

You are able to pass variables from one script to the next IF the first script is adding the second script, for example:

 

--MyFirstScript.lua
local VariableToPass = 1
Player()addScript(MySecondScript.lua,VariableToPass)

--MySecondScript.lua
function Initialize(...)
   local args = {...}
   print(args[1])
   --1
end

 

just FYI, This only works when one script is attaching another.

Link to comment
Share on other sites

Thanks, I'm going to the finish.. gradually.

 

I'm trying to add some custom variables that're accessible after restart to the all Stations and Ships made by players in the sector. So I think I should  do all checkings and attach script in the Sector's "onEntityCreate" callback or in defaultscripts.lua.

But then I need to access this local script variables in some vanilla scripts, that were attached to this ship/station too.

 

I don't think that variables from one attached script are visible to another attached script. Because it shouldn't be. So I think to complete my first mod for this game I just need to understand how people use variables from attached scripts anywhere.

Maybe its something related to 'require', but I don't need to require a whole script again.

 

I'll try to search in existing mods again.

 

you cannot exchange properties/variables of attached scripts, but can use Entity():invokeFunction() to call functions in other attached scripts and get its return values, so you could create a function to invoke which returns your required values from the script!

Link to comment
Share on other sites

Thanks, I'm going to the finish.. gradually.

 

I'm trying to add some custom variables that're accessible after restart to the all Stations and Ships made by players in the sector. So I think I should  do all checkings and attach script in the Sector's "onEntityCreate" callback or in defaultscripts.lua.

But then I need to access this local script variables in some vanilla scripts, that were attached to this ship/station too.

 

I don't think that variables from one attached script are visible to another attached script. Because it shouldn't be. So I think to complete my first mod for this game I just need to understand how people use variables from attached scripts anywhere.

Maybe its something related to 'require', but I don't need to require a whole script again.

 

I'll try to search in existing mods again.

 

You can check my haulgoods.lua script in http://www.avorion.net/forum/index.php/topic,2896.0.html

 

It calls functions in the same script in other objects and has some simple things in there to check/test/set/return values in other objects.

 

Basically you make functions in the object that set or return the values in that object.

 

Example to set or get the debuglevel in an object that's running my script:

function getDebugLevel() return debugLevel end
function setDebugLevel(arg) debugLevel = tonumber(arg) end

 

Which will set the global debugLevel in the script this function is called in.

 

Called like this:

local retval, level = ship:invokeFunction(haulscript, "getDebugLevel")

local retval = ship:invokeFunction(haulscript, "setDebugLevel", debugLevel)

 

You need to let go of the C++ type OOP implementations, where "object" is just the name of a blob of code, and start thinking as objects being *actual* objects, like a ship, or a station, or a sector.

 

To find all ships in a sector, you will call a function in the sector that will return a list of ship objects. Each of these ship objects have a number of scripts attached to them that will have certain functionality. In my example, "haulscript" is the global variable I've defined that contains the definition of the script that provides the setDebugLevel and getDebugLevel functions for JUST that script.

 

local haulscript = "data/scripts/entity/ai/haulgoods.lua"

 

Another script can have exactly the same functions, but will still only work in the context of that script attached to that specific ship object.

 

Within the script, Entity() will be the object it's attached to.

 

There is a lot of function documentation (very unfinished) in the Documentation folder of your Avorion install.

 

 

Link to comment
Share on other sites

Thanks, I'm going to the finish.. gradually.

 

I'm trying to add some custom variables that're accessible after restart to the all Stations and Ships made by players in the sector. So I think I should  do all checkings and attach script in the Sector's "onEntityCreate" callback or in defaultscripts.lua.

But then I need to access this local script variables in some vanilla scripts, that were attached to this ship/station too.

 

I don't think that variables from one attached script are visible to another attached script. Because it shouldn't be. So I think to complete my first mod for this game I just need to understand how people use variables from attached scripts anywhere.

Maybe its something related to 'require', but I don't need to require a whole script again.

 

I'll try to search in existing mods again.

 

You can check my haulgoods.lua script in http://www.avorion.net/forum/index.php/topic,2896.0.html

 

It calls functions in the same script in other objects and has some simple things in there to check/test/set/return values in other objects.

 

Basically you make functions in the object that set or return the values in that object.

 

Example to set or get the debuglevel in an object that's running my script:

function getDebugLevel() return debugLevel end
function setDebugLevel(arg) debugLevel = tonumber(arg) end

 

Which will set the global debugLevel in the script this function is called in.

 

Called like this:

local retval, level = ship:invokeFunction(haulscript, "getDebugLevel")

local retval = ship:invokeFunction(haulscript, "setDebugLevel", debugLevel)

 

You need to let go of the C++ type OOP implementations, where "object" is just the name of a blob of code, and start thinking as objects being *actual* objects, like a ship, or a station, or a sector.

 

To find all ships in a sector, you will call a function in the sector that will return a list of ship objects. Each of these ship objects have a number of scripts attached to them that will have certain functionality. In my example, "haulscript" is the global variable I've defined that contains the definition of the script that provides the setDebugLevel and getDebugLevel functions for JUST that script.

 

local haulscript = "data/scripts/entity/ai/haulgoods.lua"

 

Another script can have exactly the same functions, but will still only work in the context of that script attached to that specific ship object.

 

Within the script, Entity() will be the object it's attached to.

 

There is a lot of function documentation (very unfinished) in the Documentation folder of your Avorion install.

 

Thank you for response and tips. I actually already figured out and implemented some variables system that syncs them when I need it. And my mod is almost ready for the beta-release, I think.

 

Now I just trying to figure out how to uninstall mods properly.

I get this in my logs after reverting to the vanilla scripts: "Loading of sector (x:y) failed. Treating sector as non-exsting. Error: Script 'data/scripts/entity/myScript.lua' not found. Tried the following paths:".

So, as I understand, server saves object with my script attached to them. So right now I'm looking in the mods of other people to understand how they deal with this.

 

UPD: As I see, there is no good ways to uninstall mod that attaches scripts right now. Basically everyone just replaces attached scripts content with "terminate()" and tells users that they need to delete this files when they're 100% sure, that scripts are unattached

Link to comment
Share on other sites

removeScript removed a script that isn't the current one, terminate() removes the script that is the current one.

 

That's exactly the way you're supposed to do it.

 

For commands for example it's best practice to finish the attached script with a terminate() so they don't stay with the player or entity when they're not used.

 

There are a bunch of examples in this mod forum that use that.

Link to comment
Share on other sites

That's exactly the way you're supposed to do it.

 

For example some mod adds a script to every ship. And when server owner will try to delete it, he will need to replace this script file with one that has 'terminate' call in it.

And this file will stay forever. Because there is a bunch of sectors with ships and you can only operate sectors that are loaded in memory.

Link to comment
Share on other sites

Not really. In the case of ships, loading the sector will just invalidate the script in the ship to begin with.

 

Implementing some sort of maintenance mechanic where you can globally remove a script while no one's online would be a good idea, though.

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
×
×
  • Create New...