Not logged inOpenClonk Forum
Up Topic Development / Developer's Corner / Effects, Proplists, Arrays, Savegames
- - By Günther [de] Date 2010-12-18 22:11
Effects are currently the last holdout of numbered variables. It's time to replace that with named variables. The fix is easy - every effect will also be a proplist, so that you can just do var effect = ...; effect.oldWalkSpeed = clonk.ActMap.Walk.Speed;. There are just two problems. One is what the ... in that example stands for, I'll talk about that later. The other is how to save the contents of that effect variable. Arrays currently have a similar problem. There are various possibilities, none of them particularly inspiring:
- Use the ObjectNumber system like Objects and dynamically created Proplists. Would mean that every effect (array) is stored in the global list and we'd burn through the available object numbers that much more quickly. That's probably not a problem, in a ten-hour-game we can still use 1612 numbers per frame.
- Store Object number of the target object and effect number. Would need a temporary effect reference object during load to store the two numbers until denumeration.
- Save the effect in place at first reference, and a number assigned during save on subsequent references. Keep a temporary map from these numbers to the effects (arrays), and use that either during load or denumeration. The former would only work if save and load order is the same, and I think that's the case.
- Something else?
Reply
Parent - By PeterW [gb] Date 2010-12-19 00:40
Just a note, I don't have any further ideas: I don't think we should depend on the load order not changing. Sooner or later we will have engine updates that change it.
Parent - By Günther [de] Date 2010-12-19 03:03

> Use the ObjectNumber system like Objects and dynamically created Proplists. Would mean that every effect (array) is stored in the global list and we'd burn through the available object numbers that much more quickly. That's probably not a problem, in a ten-hour-game we can still use 1612 numbers per frame.


I'll use this for now, as it's reusing existing infrastructure the most.

> Store Object number of the target object and effect number. Would need a temporary effect reference object during load to store the two numbers until denumeration.


Would also require storing the target object in the effect, which I don't feel like adding.

> Save the effect in place at first reference, and a number assigned during save on subsequent references. Keep a temporary map from these numbers to the effects (arrays), and use that either during load or denumeration. The former would only work if save and load order is the same, and I think that's the case.


I think I'll end up writing this. Only creating the numbers and global map during save/load is somewhat of a premature optimization, but arrays need a new list anyway, so I might as well write something more general and use it for everything. For the moment, arrays will remain known buggy but mostly working.
Reply
Parent - - By Günther [de] Date 2011-03-19 01:39
Okay, thinking about this again, out loud (well, as loud as my keyboard is, which is not very.)

Requirements:
- I want arrays, pure proplists, objects, effects, and ideally everything else that has an identity stored in a similar way
- I don't want to store everything in a global list during the game just for the sake of savegames. While scripts occasionally profit from being able to serialize these things, we should replace APIs that require that with better ones.
- Not break in case the savegame gets loaded in a different order is nice, but we don't change the order often enough for that to be a must
- I'd like to avoid having to instantiate lots of tiny helper objects to hold the serialization in memory until denumeration

I think this pretty much requires a temporary map of number to data during load and data to number during save. And that the number is stored in the value until denumeration, in case the order got changed. One remaining question is whether to save the data inline or in a toplevel list. And if inline, whether all instances should have the data, with all but one instance ignored during load. Hm, no, recursive structures make that impractical. Also, if the data is stored inline, what format that should use. I'm now leaning slightly towards the everything-on-top-level method, because it makes the data format more uniform. Hm, but it does make putting the data into the map during serialization slightly more awkward, because the map would grow while it gets serialized. Well, that's probably easily solvable by using a queue in addition.

Last question is where to put the map. The "right" place is probably the StdCompiler, but that class structure is already complicated enough as it is...
Reply
Parent - By Günther [de] Date 2011-03-26 01:08
First, since now's the time to do incompatible changes to the savegame format, I'd like to consolidate the various pieces into as few files as reasonable, and make the formats as similar as possible. There are a few leftovers from the constraints of the old Clonk Planet savegame code that aren't necessary anymore. The challenge is to find them before we are again locked into compatibility with existing content. Does anybody want to help with that? You do not need to know C++: Simply open a few rounds in the editor, save them, unpack the savegame with c4group, read through the contents, and report anything that seems odd.

I've now started writing the new c4value serialization code. Quick overview:
There's a new class C4ValueNumbers, which stores a list of objects to be saved or which were loaded from the savegame, and the number<->objects map. The StdCompiler stores a pointer to an instance of this class. (Though I'm now considering passing this through via arguments so that it's statically ensured that it always exists when needed.) During save, arrays and proplists are stored in that, and each gets a number assigned. This number is written to the savegame. At the end of the save, the stored contents get written out. During load, the numbers are stored in the C4Values, and the contents are read in again. Later, everything is denumerated.

Now, where to store that list? If it were only for savegames, the answer would be easy: Somewhere convenient, after everything else involving C4Values has been written out. The problem is, there are other considerations: Runtime joins, "Scenario saves" and Scenario Sections. The first and Scenario saves with objects are nearly identical to savegames for this purpose. But scenario saves without objects do not have an Objects.txt, but do save global effects and variables, so they need to save the list. (At least a comment implies that, I didn't check.) Scenario sections, on the other hand, do not save the latter, but do save the former. For sanity, I'd like to change no-objects scenario saves: They should ideally be indistinguishable from a scenario that was handwritten, so that one can use the editor on them without leaving unwanted traces. So global effects and variables would only be saved if objects are, and the list could be stored in the Objects.txt.
Reply
- - By Günther [de] Date 2011-03-27 17:59
Okay, the first draft is done. Yay!

I've split it into three patches. It probably should be more, but I've written the main parts of the last one first, and then worked my way through the engine to make the necessary interface changes in a big modify-compile-loop, so finding splits that left the engine in one piece wasn't easy. I'd really appreciate if someone could do at least a cursory review.
Add C4ValueNumbers helper class and pass it through to C4Value::CompileFunc
Store Objects in the Game.txt instead of a separate Objects.txt
Arrays with multiple references are stored just once
Reply
Parent - By Günther [de] Date 2011-04-01 00:00
Second version. I've done a little testing and fixed some bugs, not all of them strictly savegame related, some of them pointed out by the new gcc 4.6. (it now detects that in void foo() { int bar; bar = baz(); } bar isn't really used, and sometimes actually doing something with bar fixes a bug.) It's again on bitbucket, and I'll push it to hg.openclonk.org soonish.
Reply
Up Topic Development / Developer's Corner / Effects, Proplists, Arrays, Savegames

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill