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?
> 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.
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...
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.
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
Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill