Page 4 of 5

Re: Common Serialization (Saving) Pitfalls

Posted: Fri Apr 01, 2016 1:27 am
by AndakRainor
I got this trace, after the game crashing while saving during an active spell which makes several delayCalls (but other similar spells are ok, I don't get it...)

=== Software Failure ===

invalid key to 'next'
stack traceback:
[C]: in function 'writeValue'
[string "MessageSystem.lua"]: in function 'saveState'
[string "GameMode.lua"]: in function 'saveGame'
[string "GameMode.lua"]: in function 'quickSave'
[string "GameMode.lua"]: in function 'keyPressed'
[string "Grimrock.lua"]: in function 'pollEvents'
[string "Grimrock.lua"]: in function 'display'
[string "Grimrock.lua"]: in main chunk

Any hint what this "next" key refers to? I did not find any key with this name in my code...

Re: Common Serialization (Saving) Pitfalls

Posted: Fri Apr 01, 2016 2:47 am
by minmay
next() is the Lua function for iterating through tables. It will be a lot easier to fix the bug if you tell us which of your 105 spells this is.

Re: Common Serialization (Saving) Pitfalls

Posted: Fri Apr 01, 2016 2:53 am
by AndakRainor
It concerns 2 spells: Wind Blow and Fierce Storm. Both have the cleanAir effect which fade out the objects with CloudSpell components around the party.

Re: Common Serialization (Saving) Pitfalls

Posted: Fri Apr 01, 2016 3:37 am
by minmay
I see the problem. You are passing tables to delayedCall(). delayedCall() only supports number and string arguments, even if you manage to pass something else it probably won't serialize/unserialize correctly.

Re: Common Serialization (Saving) Pitfalls

Posted: Fri Apr 01, 2016 3:45 am
by AndakRainor
Ok I will try without tables, but what is odd is that the oracle spell also use tables and does not crash when saving.

Re: Common Serialization (Saving) Pitfalls

Posted: Fri Apr 01, 2016 4:34 am
by minmay
I don't see such a delayedCall() anywhere related to that spell, just in the original two you mentioned and in All Shall Fall. A quick grep shows these as the only delayedCalls containing table literals:

Code: Select all

spells_functions.lua:      delayedCall("spells_functions", i, "zoneEffects", {{"cleanAir", true}}, "party", range, 1)
spells_functions.lua:      delayedCall("spells_functions", i, "zoneEffects", {"fire_aura_blast", "knockback", {"cleanAir", true}}, "party", range, 0, power, ordinal)
spells_functions.lua:      delayedCall("spells_functions", i, "zoneEffects", {"allShallFall", "fire_aura_blast", "knockback"}, "party", range, 0, power, ordinal)

Re: Common Serialization (Saving) Pitfalls

Posted: Fri Apr 01, 2016 12:07 pm
by AndakRainor
You're right, the Oracle spell uses the zoneEffects function without delayedCall, and All Shall Fall crashes the game with the same error.

I thought Oracle should lead to the same result because zoneEffects also generates delayed calls, but it does it differently; the parameters are stored in a table in spells_functions.script and only the index in this table is passed to generated delayed calls. (when used, the value at this index is set to nil so the table should not grow infinitely).

So I think I have two options to remove the bug: also use this table in the context of those 3 spells (and pass only the index to delayed calls), or merge the table parameters into one string with some special separator character...

edit: used the table solution as it was already available ;)

Re: Common Serialization (Saving) Pitfalls

Posted: Sat Sep 24, 2016 7:43 pm
by AndakRainor
Oh, I guess functions can not be serialized either, as they are not numbers, strings, booleans or tables ?

Re: Common Serialization (Saving) Pitfalls

Posted: Sat Sep 24, 2016 7:57 pm
by minmay
Functions can be serialized as long as they do not have upvalues - that's what section 2 of the OP is about. The devs just forgot to include functions in the modding guide's list of serializable types.

I recommend not trying to pass functions to delayedCall(), though.

Re: Common Serialization (Saving) Pitfalls

Posted: Sat Sep 24, 2016 8:04 pm
by AndakRainor
In my case there is no delayedCall() at all. I store a time stamp, a function and its arguments in a sorted linked list in the spells_functions script. I then consume it each frame with a 0 interval timer. So, this is safe ?