script state serialization...

Started by
8 comments, last by WitchLord 19 years, 6 months ago
Hello, I think about adding AngelScript to my project although I have some doubts whether it will be possible at all. I want to script my internal game editor so every scene object could have his own script. Also I want to give player possibility of saving game-state including every script state. Haven't found in AngelScript option of serialization (saving and loading) script variables but I think it is not the most important problem (I can make procedures like "setInt, getInt, setFloat, getFloat" and serialize everything without AngelScript help) What I cannot solve at this moment is saving script-state, I mean number of line that is currently being parsed (eg. I’ve added to the scripts api procedure to sleep it and let's say in the script there's line "Sleep(10000)". So I hold script execution for 10 sec but if meanwhile user will save game-state and quit the game I want to make possible loading it after he will run the game again and start the script from the line "Sleep(10000)") As I said I haven't found proper functions in AngelScript to serialize script-state. Please, correct me if am I wrong. Greetings
Advertisement
Unfortunately this is simply not possible. The script stack can hold memory pointers to objects in memory, but doesn't have enough information to serialize these pointers.

If you wish to save everything like you describe, then you'll have to design the scripts so that they are never suspended. That is, any long running loops have to broken into smaller functions that are called in a loop by the main program.

Any global variables declared by the scripts can be accessed with information about their types for serialization.

After a second thought, it might be possible if you can make sure that no pointers are ever stored on the stack, i.e. create special object types that hold indices that are used by the object methods to look up the real object. This would unfortunately require a lot of work to write the necessary wrapper functions. But if you do that then I can help you with writing functions for serializing the script state.

I recognize the usefulness of saving the entire script state for objects. And I would very much like ideas for how something like this can be accomplished, while still keeping the efficiency.

Should you decide to go with another scripting library that have the functionality you describe I would be very grateful if you let me know which one you choose. That would allow me to analyze that scripting library and maybe incorporate some of its solutions into AngelScript.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

WitchLord - Having just made a serialization library for Lua, I can tell you various approaches to scripting serialization that I tried and what did and didn't work, if you're interested.
Hello,

Quote:Should you decide to go with another scripting library that have the functionality you describe I would be very grateful if you let me know which one you choose. That would allow me to analyze that scripting library and maybe incorporate some of its solutions into AngelScript.


Well, currently i don't know which one i will choose.
I have to test dozens of libraries :) Need c-style scripting
(so i'll not choose lua or python) with functionality described above. (I suppose most of games use scripting languages with state-serialization. i'm nearly sure about hitman and doom3. in these games scripts use procedures like Sleep and WaitForEvent and you can save game-state as well. Serialization is also nice when you want to send game-state thru the network) Maybe SpiderMonkey would be a good idea? (i don't know about its speed although js syntax is nice) I'll send you information after i decide on scripting library or creating another one (i made my own scripting library several years ago so i think it's quite possible.)

Greetings
Sneftel:

I don't know much about Lua. I've never used it, and don't really have the time to study it closer. I'm curious as to how it handles references to objects in the application. And how did you solve this with your serialization library.

---

Serialization is easy if knowledge of all objects is available. AngelScript doesn't have the knowledge necessary to serialize references to application objects. I suppose I could change the stack representation slightly so that all memory pointers are stored in a separate location together with information about the type of pointer. The stack would then only need to hold indexes into this location. This would make it possible to serialize the script state.

It would also make it slightly slower to interact with the objects and possibly make it more difficult to interact with the application. I would be able to use it for better memory management and security though. The objects could be serialized by having the application register the necessary serialization methods.

I'm willing to give this a try in the future.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Lua internally stores object references as pointers. All object types include a header at the top that describes (among other things) what type the object is. Lua also kind of has knowledge of all objects (in the form of its garbage collection list), but I never make use of that. Instead, I simply start from a root object, and recursively store it and all its references. As long as an object contains sufficient information about itself for serializing its base data, and information about all the other objects it directly references, that's all you need.

The basic algorithm is:

serialize(obj)    if has-been-serialized(obj)        write-reference(obj) // using the unique integer tag assigned to it    else        write-base-data(obj) // involves a switch statement on the type of the object        add-to-serialized-list(obj) // add the object to the mapping, with a unique integer tag        foreach reference "ref" in obj            serialize(ref)        end foreach    end ifend

And from what I understand Lua also has a way to obtain the type of each value on the stack. Isn't that so?

AngelScript doesn't have that information as its stack works much the same way as the C++ stack. The type of the values are only known at compile time.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Quote:Original post by WitchLord
And from what I understand Lua also has a way to obtain the type of each value on the stack. Isn't that so?
Yes, it does; all objects, even value (non-gc'ed) objects, are tagged with their type. To a certain extent this information is necessary for serialization, because it lets the serializer know what type to treat it as (serializing a number as though it were a function wouldn't work). However, if your VM is type-agnostic it's not necessarily impossible to do this; all you need is the size of the object and a way of resolving its references.

Ultimately, I'm sure you don't want to make AngelScript into Lua, so serialization will be considerably different. Still, I think many of the underlying algorithms will be manifestly the same.
LUA stores the type of the variable on the stack with it, if it's a pointer. If it's a primitive, it's all just bits anyway.

I've been kind of poking at this problem myself, but mostly just putting it off. The solution I came up with was to stick 'void serialize(some_sort_of_file_object)' in every script, along with the accompaning load function. I'm also working under the limitation that a function call to a script (I'm using functions as 'behaviors' - object gets hurt, it calls 'void ouch()'.) are fast and don't do nasty things like sit in infinite loops, because I am NOT stepping. I don't like that the scripts can freeze the game.
If you give us the option of dumping the current stack to disc, with any registers, and the current line, and of course, the ability to load it again, it will be enough. We'll just have to do like you suggested, and not use any pointers.
It would also be a good idea to save the bytecode with the stack. If you changed the script, the loaded stack wouldn't match anymore! Boom!
As always when I'm presented a problem I can't stop thinking about it until I have a possible solution. Which is a good thing for you. [wink]

Although AngelScript doesn't store the type of the value on the stack, it actually do have enough information already. AngelScript has an exception handler that is able to free all the objects currently on the stack. Which it can do by looking at the current program counter and mapping that to a list of objects and their positions. All I have to do is to expand on this and store all objects, not just the ones that must be released by the exception handler. In fact I can probably combine the two so that the information isn't stored multiple times.

Still it's quite a lot of work needed before serialization can be used, so don't expect it for at least a couple of months.

The application can save the bytecode together with the context state if it wishes to do that. Or it could give a version number for the context stack, so that if the version isn't the same then the context stack will not be loaded.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement