To save/load works correct in games with AI, it must support save/load.
Since 0.75b1 in C++ AI interface was added 2 methods:Save and Load.
When game saves Save method is called(for all AI's). It's parameter is savegame file stream.
When game loads engine calls IsLoadSupported. If it returns false engine creates AI, calls Init and adds all units. If returns true it creates AI but calls Load instead Init. Load's parameters is savegame file stream and ai callback.
In IsLoadSupported in GlobalAI:
DLL_EXPORT bool IsLoadSupported();
In IsLoadSupported in GroupAI:
DLL_EXPORT bool IsLoadSupported(unsigned aiNumber);
Save/load in AI
Moderators: hoijui, Moderators
Also creg can be used in AI(It is licenseed under GPL):
First replace C-style dynamic arrays(type *) to vector<type> , find and remove all uninitialized pointers
To add creg to AI first add all cpp files in rts\system\creg and rts\system\float3.cpp to build and include rts\system\creg\creg.h to all files.
Add rts\system\creg\Serializer.h and rts\system\creg\cregex.h to you main cpp(where Load and Save will be defined)
Call creg::System::InitializeClasses when first instance of you ai is created and creg::System::FreeClasses when last destroyed(see how this realized in standard group ais - revision 3834)
Add this code:
Add CR_DECLARE(ClassName) for all classes(to class declaration in .h file) that need be saved.
For subclasses add CR_DECLARE_Sub(SubClassName) to base class and CR_DECLARE(SubClassName) to subclass.
Add this code for all classes with CR_DECLARE(in .cpp)
For abstract classes use CR_BIND_INTERFACE
For subclasses
If class is derived from serializable class use CR_BIND_DERIVED
Declare class members(including pointers to serializeble classes) that need to save with CR_MEMBER(MemberName)
If member is set include creg/STL_Set.h , if map - creg/STL_Map.h ,if list - creg/STL_List.h ,for deque - creg/STL_Deque.h
For custom member types use CR_SERIALIZER(SerializeFunc)
Add reserved space(for compatibility with new versions) with CR_RESERVED(Size)
For initialization after load use CR_POSTLOAD(PostLoadFunc)
Compile and fix errors.
First replace C-style dynamic arrays(type *) to vector<type> , find and remove all uninitialized pointers
To add creg to AI first add all cpp files in rts\system\creg and rts\system\float3.cpp to build and include rts\system\creg\creg.h to all files.
Add rts\system\creg\Serializer.h and rts\system\creg\cregex.h to you main cpp(where Load and Save will be defined)
Call creg::System::InitializeClasses when first instance of you ai is created and creg::System::FreeClasses when last destroyed(see how this realized in standard group ais - revision 3834)
Add this code:
Code: Select all
CREX_REG_STATE_COLLECTOR(YourAIName,AIClassName);
void AIClassName::Load(IGroupAICallback* callback,std::istream *ifs)
{
this->callback=callback;
===Initialization before load===
CREX_SC_LOAD(YourAIName,ifs);
}
void AIClassName::Save(std::ostream *ofs)
{
CREX_SC_SAVE(YourAIName,ofs);
}
For subclasses add CR_DECLARE_Sub(SubClassName) to base class and CR_DECLARE(SubClassName) to subclass.
Add this code for all classes with CR_DECLARE(in .cpp)
Code: Select all
CR_BIND(ClassName, ConstructorParamsAsInOperatorNew);
CR_REG_METADATA(ClassName,(
===Members===
));
For subclasses
Code: Select all
CR_BIND(ClassName::SubClass, ConstructorParamsAsInOperatorNew);
CR_REG_METADATA_SUB(ClassName,SubClass,(
===Members===
));
Declare class members(including pointers to serializeble classes) that need to save with CR_MEMBER(MemberName)
If member is set include creg/STL_Set.h , if map - creg/STL_Map.h ,if list - creg/STL_List.h ,for deque - creg/STL_Deque.h
For custom member types use CR_SERIALIZER(SerializeFunc)
Code: Select all
void SerializeFunc(creg::ISerializer& s);
For initialization after load use CR_POSTLOAD(PostLoadFunc)
Code: Select all
void PostLoadFunc();
Last edited by Viktor on 20 Jul 2007, 09:50, edited 3 times in total.
Can you clar that up a bit? There's numerous parts that make no real sense as they're ambiguous or just lack details.
Examples would help greatly.
In NTai I create all my objects etc in Init()does this mean Init wont be called if a savegame is loaded? Or will the game be loaded and then all that data destroyed in one great memory leak when it then calls Init()? =s now I'm totally at a loss to explain what that means. Ambiguity for the loose.
huh?
CR_BIND(MyClass::MyClass,int,String,float);
CR_BIND(MyClass::MyClass,a,b,c);
CR_BIND(MyClass::MyClass,int a,String b,float c);
CR_BIND(MyClass::MyClass,new MyClass(int a,String b,float c));
etc....
Yet more ambiguity. Zero examples.
Can someone with a better grasp of English grammar rewrite this? This isn't much use as is. It needs examples very very very badly, and it needs far better explanations.
Examples would help greatly.
You mean calling Init etc?For initialization after load use CR_POSTLOAD(PostLoadFunc)
void SerializeFunc();
In NTai I create all my objects etc in Init()does this mean Init wont be called if a savegame is loaded? Or will the game be loaded and then all that data destroyed in one great memory leak when it then calls Init()? =s now I'm totally at a loss to explain what that means. Ambiguity for the loose.
huh?ConstructorParamsAsInOperatorNew
Code: Select all
MyClass::MyClass(int a, String b, float c){
}
CR_BIND(MyClass::MyClass,int,String,float);
CR_BIND(MyClass::MyClass,a,b,c);
CR_BIND(MyClass::MyClass,int a,String b,float c);
CR_BIND(MyClass::MyClass,new MyClass(int a,String b,float c));
etc....
Yet more ambiguity. Zero examples.
Can someone with a better grasp of English grammar rewrite this? This isn't much use as is. It needs examples very very very badly, and it needs far better explanations.
This means that PostLoad initialize struct where it declared.AF wrote: You mean calling Init etc?
If use Class1 *obj1 in your struct and declare it in creg(CR_DECLARE(obj1)) creg automaticaly creates new class.
if you have many links to one object creg allocs only one instance(for examle CGlobalAI class and links to it in other classes)
If IsLoadSupported return true Init woud not be called.AF wrote: In NTai I create all my objects etc in Init()does this mean Init wont be called if a savegame is loaded? Or will the game be loaded and then all that data destroyed in one great memory leak when it then calls Init()? =s now I'm totally at a loss to explain what that means. Ambiguity for the loose.
See how initalization after load works in KAI: in GlobalAI.cpp CGlobalAI::Load initalize callback and AIClasses(and serialize it as embedded object), Non-serialized objects is initialized in PostLoad(path find,unit table)
AF wrote: huh?huh?Code: Select all
MyClass::MyClass(int a, String b, float c){ }
CR_BIND(MyClass::MyClass,int,String,float);
CR_BIND(MyClass::MyClass,a,b,c);
CR_BIND(MyClass::MyClass,int a,String b,float c);
CR_BIND(MyClass::MyClass,new MyClass(int a,String b,float c));
etc....
Yet more ambiguity. Zero examples.
Code: Select all
class MyClass {
CR_DECLARE(MyClass)
MyClass(int a, String b, float c);
}
Code: Select all
CR_BIND(MyClass, (0,String(""),0.0f));//String is class?
Code: Select all
obj = new MyClass(0,String(""),0.0f)