Space Station 13

by Exadv1
Space Station 13
Stay alive inside Space Station 13
ID:1327362
 
Applies to:
Status: Open

Issue hasn't been assigned a status value.
Is there a way to save anything that has happens to a station in a server, then boot that altered station in the next round?

Say for instance, a room is built outside the station effectively expanding it, I don't want that change to go away.

Or another example is virology or genetics makes a major break through and creates data backups for preliminary distribution.

I essentially want to be able to Crtl-S a station at the end of a round (or any other time) and load it the next time the server goes up.

Anything?
I don't think that is possible.
It's possible, the LLJK servers have the ability to save and load map regions but it's only used for very small areas such as an admin gimmick tool or a blueprint recording/automatic construction device for player built space bases. Saving the entire station would take several minutes, I don't think your players would appreciate that kind of lag spike at the start and end of every round.

You might be able to make it a little more bearable if you spread out the work somehow but it would be a little tricky. Figure out what important stuff you need to save like walls and floors and research status and pare it down to something manageable and discard the rest.

Basically if you want to do this you're going to write a lot of code and chase a lot of performance issues and bugs.
Hrm... so what your saying is there's no feature already?

Lag doesn't matter, its a private server. Is there any instructions out there? How would I go about saving the entire station.

Just let me know, what you know.
You'd have to code a lot.

Basically what he said
So I cant get any code to start from? Have to go from scratch?
Well I'm not giving you my code that does it and I don't know of any other, so uh

It's just bog standard serialization the idea itself isn't new or complicated. The hard part is implementing serialize and deserialize on every type and thinking about which variables you need to save.

It's not as bad as it sounds since you can get away with most of it by just doing the major root types but it's still a lot of time to get it done.

hmm how do i make a code block in this forum..... i'll make an example in a second

oh figured it out. itd be nice if that dm tag was in that info mouseover



datum/var/list/vars_to_serialize = list("name","desc","x","y","z"/* etc, override this on child types and fill it with the vars you want to save*/)

var/global/changed_vars_cache = list() // save a tiny bit of cpu by reusing a list since byond procs are synchronous by default

proc/datum_to_text(var/datum/A)
if (!A || !A.vars_to_serialize || !A.vars_to_serialize.len)
return

changed_vars_cache.len = 0
var/list/include = A.vars_to_serialize
var/value

for(var/v in include)
if (v in A.vars) // you can save more cpu by removing this sanity check if you're sure you didn't do any of the lists wrong and nobody else will ever change them
value = A.vars[v]
if (isnum(value) || istext(value))
changed_vars_cache[v] = value

if(changed_vars.len)
return list2params(changed_vars_cache)
else
return null

proc/text_to_datum(var/datum/A, var/list/include, var/list/changed_vars)
if (!A || !A.vars_to_serialize || !A.vars_to_serialize.len || !changed_vars || !include)
return

var/list/include = A.vars_to_serialize
var/numeric = 0
var/value = 0

for(var/v in include)
if (!(v in changed_vars))
continue
value = changed_vars[v]
numeric = text2num(value)
if (numeric && isnum(A.vars[v]))
A.vars[v] = numeric
else
A.vars[v] = value

return A


So you could use something like that, you just need to take the atoms you want to save and turn them into text and dump the text into a savefile along with each atom's type. Then when you want it back read from the savefile and create an atom of that type, feed it to the other proc and there's your atom good as new. Sorry if it doesn't compile like that, I just slapped this together real quick.

Of course this only works for simple types, you'll have to have special handling to turn each complex type variable into text but you can use the same procs. Also it doesn't take into account the game's lighting so you need a check for that or it messes the lighting all up, luminosity and opacity can only be set properly with the sd_Set procs. There's a few other pitfalls with trying to save and load stuff in SS13 (and BYOND for that matter, but mostly SS13) but you'll see them pretty quickly.
Appreciate it.
Alternatively, there's a library you can use that does this, but I'm not entirely sure what it was called.
In response to Laser50
Laser50 wrote:
Alternatively, there's a library you can use that does this, but I'm not entirely sure what it was called.

Let the hunt begin!
There is a function that can do this in BS12 code.

However it records the state of EACH and EVERY tile in the area recorded, causing your map file to bloat to unbearably huge sizes.

Essentially it is unworkable.
Well there's one issue I'm having with your responses guys.
If one theoretically wanted to save, say an entire z-level. How is it not just a Copy-Pasting issue of the server-files? Sure it's not a small file, but it most certainly is not so huge that it would take minutes to load.
What all attempts at creating something like this essentially seem to have suggested is to decompile the working map and save it as a map file, then somehow integrate it into the map file that the game uses at startup when it created the maps. Magic mountains version seems to do the same.

However, the server needs to have some form of the entire map stored in memory for it to be able to send information to dozens of different clients at the same time. It might be because of my unfamiliarity with BYOND code, but i fail to grasp why one could not save exatly these files the server is actually working with when the round ends. Again, I'm not familiar with how these things are handled in detail, but the server must have information about all the turfs and the objects on them SOMEwhere. And since normally, between rounds, you would not have to actually save the maps into editable formats, all one would have to do is make the server use the data it was processing just before the world got restarted for the new world, and only replacing certain parts of it with the default map that is loaded on startup.
Sure it would still take a minute or two to save all the data the server was working with if one necessarily wanted a backup to counter griefing, but i don't think anyone who just worked multiple hours on building something in game would actually object to wait two minutes more before the game restarts.

In essence this would be an infinitely extended round but with the stations z level and mobs reset after every round end. That way lag causing offline players, debris, blood and such would be removed and one would still have new antags every round, bypassing the only issues that make infinite rounds unworkable.

Please tell me if this makes any sense
Well, for not being familiar with the concepts you're pretty much right on the money. The map starts out as a file on the server hard drive, it's loaded into memory by BYOND and then player actions mess with the map as it exists in memory.

The trick is in saving and reloading the copy in memory. You need to write some code to save all the relevant data to the hard drive and reload it when the next round begins. It's no small task, SS13 is very complicated and has a lot of code to touch if you want to implement a feature like this.
I tried this, wrote the code and everything. The problem is with the complexity of SS13 once I got to about 60x60 tiles it would crash the server entirely to try and save it. It only will work for chunks at a time, but could still be useful if you wanted to work on something IC then manually copypasta it in with the map editor.
Yeah, that's part of why all we use it for is saving and loading small areas. It's nice as an admin gimmick toolbox, you can spend as much time as you like setting up a cool custom round and then quickly pull out all the stuff you need.

Saving and loading the entire map is just not practical. Even if you spent the time to optimize everything and break it up into chunks it would still take several minutes to save and load. Most people are annoyed when a game locks up for a second, no player is going to sit around for minutes.
I don't get it. I seriously don't. You say it would take several minutes to load and save the entire map.
The total amount of memory used by a SS13 server barely exceeds 1 GB. Why would it take minutes to save that much?

And i'm only talking about saving maps between rounds. Even not counting the ads from BYOND you still have to wait at least 5 minutes between rounds.

I seriously don't get the problem.