MediaWiki API result

This is the HTML representation of the JSON format. HTML is good for debugging, but is unsuitable for application use.

Specify the format parameter to change the output format. To see the non-HTML representation of the JSON format, set format=json.

See the complete documentation, or the API help for more information.

{
    "batchcomplete": "",
    "continue": {
        "gapcontinue": "Skill_Format",
        "continue": "gapcontinue||"
    },
    "query": {
        "pages": {
            "104": {
                "pageid": 104,
                "ns": 0,
                "title": "Serialization",
                "revisions": [
                    {
                        "contentformat": "text/x-wiki",
                        "contentmodel": "wikitext",
                        "*": "=Introduction =\nThe serializer translates between objects living in our code (like int or CGameState*) and stream of bytes. Having objects represented as a stream of bytes is useful. Such bytes can send through the network connection (so client and server can communicate) or written to the disk (savegames).\n\nVCMI uses binary format. The primitive types are simply copied from memory, more complex structures are represented as a sequence of primitives.\n\n==Typical tasks==\n===Bumping a version number===\nDifferent major version of VCMI likely change the format of the save game. Every save game needs a version identifier, that loading can work properly. Backward compatibility isn't supported for now. The version identifier is a constant named version in Connection.h and should be updated every major VCMI version or development version if the format has been changed. Do not change this constant if it's not required as it leads to full rebuilds. Why should the version be updated? If VCMI cannot detect \"invalid\" save games the program behaviour is random and undefined. It mostly results in a crash. The reason can be anything from null pointer exceptions, index out of bounds exceptions(ok, they aren't available in c++, but you know what I mean:) or invalid objects loading(too much elements in a vector, etc...) This should be avoided at least for public VCMI releases.\n\n===Adding a new class===\nIf you want your class to be serializable (eg. being storable in a savegame) you need to define a serialize method template, as described in [[#User types]]\n\nAdditionally, if your class is part of one of registered object hierarchies (basically: if it derives from CGObjectInstance, IPropagator, ILimiter, CBonusSystemNode, CPack) it needs to be registered. Just add an appropriate entry in the <code class=\"inline\">RegisterTypes.h</code> file. See [[#Polymorphic serialization]] for more information.\n\n=How does it work=\n==Primitive types==\nThey are simply stored in a binary form, as in memory. Compatibility is ensued through the following means:\n* VCMI uses internally types that have constant, defined size (like si32 - has 32 bits on all platforms)\n* serializer stores information about its endianess\n\nIt's not \"really\" portable, yet it works properly across all platforms we currently support.\n\n==Dependant types==\n===Pointers===\nStoring pointers mechanics can be and almost always is customized. See [[#Additional features]].\n\nIn the most basic form storing pointer simply sends the object state and loading pointer allocates an object (using \"new\" operator) and fills its state with the stored data.\n\n===Arrays===\nSerializing array is simply serializing all its elements.\n\n==Standard library types==\n===STL Containers===\nFirst the container size is stored, then every single contained element.\n\nSupported STL types include:\n vector\n array\n set\n unordered_set\n list\n string\n pair\n map\n\n===Smart pointers===\nSmart pointers at the moment are treated as the raw C-style pointers. \nThis is very bad and dangerous for shared_ptr and is expected to be fixed somewhen in the future.\n\nThe list of supported data types from standard library:\n shared_ptr (partial!!!)\n unique_ptr\n\n===Boost===\nAdditionally, a few types for Boost are supported as well:\n variant\n optional\n\n==User types==\nTo make the user-defined type serializable, it has to provide a template method serialize. The first argument (typed as template parameter) is a reference to serializer. The second one is version number.\n\nSerializer provides an operator& that is internally expanded to << when serialziing or >> when deserializing. \n\nSerializer provides a public bool field <code class=\"inline\">saving</code>that set to true during serialziation and to false for deserialziation.\n\nTypically, serializing class involves serializing all its members (given that they are serializable). Sample:\n<syntaxhighlight lang=\"cpp\">\n/// The rumor struct consists of a rumor name and text.\nstruct DLL_LINKAGE Rumor\n{\n\tstd::string name;\n\tstd::string text;\n\n\ttemplate <typename Handler>\n\tvoid serialize(Handler & h, const int version)\n\t{\n\t\th & name & text;\n\t}\n};\n</syntaxhighlight>\n\n==Backwards compatibility==\nSerializer, before sending any data, stores its version number. It is passed as the parameter to the serialize method, so conditional code ensuring backwards compatibility can be added.\n\nYet, because of numerous changes to our game data structure, providing means of backwards compatibility is not feasible. The versioning feature is rarely used.\n\nSample:\n<syntaxhighlight lang=\"cpp\">\n/// The rumor struct consists of a rumor name and text.\nstruct DLL_LINKAGE Rumor\n{\n\tstd::string name; //introduced in version 1065\n\tstd::string text;\n\n\ttemplate <typename Handler>\n\tvoid serialize(Handler & h, const int version)\n\t{\n\t\tif(version >= 1065)\n\t\t\th & name;\n\t\telse if(!h.saving)    //when loading old savegame\n\t\t\tname = \"no name\"; //set name to some default value  [could be done in class constructor as well]\n\t\n\t\th & text;\n\t}\n};\n</syntaxhighlight>\n\n==Serializer classes==\n===Common information===\nSerializer classes provide iostream-like interface with operator<< for serialization and operator>> for deserialization.\nSerializer upon creation will retrieve/store some metadata (version number, endianess), so even if no object is actually serialized, some data will be passed.\n\n===Serialization to file===\nCLoadFile/CSaveFile classes allow to read data to file and store data to file. They take filename as the first parameter in constructor and, optionally, the minimum supported version number (default to the current version). If the construction fails (no file or wrong file) the exception is thrown.\n\n===Networking===\nCConnection class provides support for sending data structures over TCP/IP protocol. It provides 3 constructors:\n1) connect to given hostname at given port (host must be accepting connection)\n2) accept connection (takes boost.asio acceptor and io_service)\n3) adapt boost.asio socket with already established connection\n\nAll three constructors take as the last parameter the name that will be used to identify the peer.\n\n==Additional features==\nHere is the list of additional custom features serialzier provides. Most of them can be turned on and off.\n* [[#Polymorphic serialization]] \u2014 no flag to control it, turned on by calls to registerType.\n* [[#Vectorized list member serialization]] \u2014 enabled by smartVectorMembersSerialization flag.\n* [[#Stack instance serialization]] \u2014 enabled by sendStackInstanceByIds flag.\n* [[#Smart pointer serialization]] \u2014 enabled by smartPointerSerialization flag.\n\n===Polymorphic serialization===\nSerializer is to recognize the true type of object under the pointer if classes of that hierarchy were previously registered.\n\nThis means that following will work\n<syntaxhighlight lang=\"cpp\">\nDerived *d = new Derived();\nBase *basePtr = d;\nCSaveFile output(\"test.dat\");\noutput << b;\n//\nBase *basePtr = nullptr;\nCLoadFile input(\"test.dat\");\ninput >> basePtr; //a new Derived object will be put under the pointer\n</syntaxhighlight>\n\nClass hierarchies that are now registered to benefit from this feature are mostly adventure map object (CGObjectInstance) and network packs (CPack). See the RegisterTypes.h file for the full list.\n\nIt is crucial that classes are registered in the same order in the both serializers (storing and loading).\n\n===Vectorized list member serialization===\nBoth client and server store their own copies of game state and VLC (handlers with data from config). Many game logic objects are stored in the vectors and possess a unique id number that represent also their position in such vector.\n\nThe vectorised game objects are:\n CGObjectInstance\n CGHeroInstance\n CCreature\n CArtifact\n CArtifactInstance\n CQuest\n\nFor this to work, serializer needs an access to gamestate library classes. This is done by calling a method <code class=\"inline\">CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib)</code>. \n\nWhen the game ends (or gamestate pointer is invaldiated for another reason) this feature needs to be turned off by toggling its flag.\n\nWhen vectorized member serialization is turned on, serializing pointer to such object denotes not sending an object itself but rather its identity. For example:\n<syntaxhighlight lang=\"cpp\">\n//Server code\nCCreature *someCreature = ...;\nconnection << someCreature;\n</syntaxhighlight>\n\nthe last line is equivalent to <syntaxhighlight lang=\"cpp\">connection << someCreature->idNumber;</syntaxhighlight>\n\n//Client code\n<syntaxhighlight lang=\"cpp\">\nCCreature *someCreature = nullptr;\nconnection >> someCreature;\n</syntaxhighlight>\n\nthe last line is equivalent to\n<syntaxhighlight lang=\"cpp\">\nCreatureID id;\nconnection >> id;\nsomeCreature = VLC->creh->creatures[id.getNum()];\n</syntaxhighlight>\n\nImportant: this means that the object state is not serialized. \n\nThis feature makes sense only for server-client network communication.\n\n\n===Stack instance serialization===\nThis feature works very much like the vectorised object serialization. It is like its special case for stack instances that are not vectorised (each hero owns its map). When this option is turned on, sending CStackInstance* will actually send an owning object (town, hero, garrison, etc) id and the stack slot position.\n\nFor this to work, obviously, both sides of the connection need to have exactly the same copies of an armed object and its stacks.\n\nThis feature depends on vectorised member serialization being turned on. (Sending owning object by id.)\n\n\n===Smart pointer serialization===\nNote: name is unfortunate, this feature is not about smart pointers (like shared-ptr and unique_ptr). It is for raw C-style pointers, that happen to point to the same object.\n\nThis feature makes it that multiple pointers pointing to the same object are not stored twice.\n\nEach time a pointer is stored, a unique id is given to it. If the same pointer is stored a second time, its contents is not serialized \u2014 serializer just stores a reference to the id.\n\nFor example:\n<syntaxhighlight lang=\"cpp\">\nFoo * a = new Foo();\nFoo * b = b;\n\n{\n\tCSaveFile test(\"test.txt\");\n\ttest << a << b;\n}\n\nFoo *loadedA, *loadedB;\n{\n\tCLoadFile test(\"test.txt\");\n\ttest >> loadedA >> loadedB;\n\t//now both pointers point to the same object\n\tassert(loadedA == loadedB);\n}\n</syntaxhighlight>\n\nThe feature recognizes pointers by addresses. Therefore it allows mixing pointers to base and derived classes. However, it does not allow serializing classes with multiple inheritance using a \"non-first\" base (other bases have a certain address offset from the actual object). \n\nPointer cycles are properly handled/\n\nThis feature makes sense for savegames and is turned on for them."
                    }
                ]
            },
            "25": {
                "pageid": 25,
                "ns": 0,
                "title": "Server",
                "revisions": [
                    {
                        "contentformat": "text/x-wiki",
                        "contentmodel": "wikitext",
                        "*": "The main purpose of server is to maintain the [[game state]] and to inform clients participating in game about changes. Ideally, all the mechanics should be handled by server in order to avoid cheating on client side.\n\n= Operation =\n\nInformation about changes is sent to all clients with [[netpacks]] from [[GameHandler]] defined in gamehandler.cpp. This way every client receives synchronized information about changes in game state.\nServer receives requests in form of [[netpacks]] from clients entered via [[player interface]] and processes it according to [[game mechanics]].\n\n= [[Game Handler]] ="
                    }
                ]
            }
        }
    }
}