Difference between revisions of "Code structure"

From VCMI Project Wiki
Jump to: navigation, search
(document wrapped namespace used in single-process approach)
(54 intermediate revisions by 4 users not shown)
Line 3: Line 3:
 
= The big picture =
 
= The big picture =
  
VCMI contains three core project: VCMI_lib (dll / so), VCMI_client (executable) and VCMI_server (executable).  
+
[[File:Architektura.png|center]]
Server handles all game mechanics and events. Client presents game state and events to player and collects input from him.
+
 
 +
VCMI contains three core projects: VCMI_lib (dll / so), VCMI_client (executable) and VCMI_server (executable).  
 +
[[Server]] handles all [[game mechanics]] and events. [[Client]] presents [[game state]] and events to player and collects input from him.
  
 
During the game, we have one (and only one) server and one or more (one for each player computer) clients.  
 
During the game, we have one (and only one) server and one or more (one for each player computer) clients.  
Line 10: Line 12:
 
Important: State of the game and its mechanics are synchronized between clients and server. All changes to the game state or mechanics must be done by server which will send appropriate notices to clients.
 
Important: State of the game and its mechanics are synchronized between clients and server. All changes to the game state or mechanics must be done by server which will send appropriate notices to clients.
  
== State of game ==
+
== Game state ==
It's basically CGameState class object and everything that's accessible from it: map (with objects), player statuses, game options, etc.  
+
It's basically CGameState class object and everything that's accessible from it: map (with objects), player statuses, game options, etc.
  
== [[Bonus system]] ==
+
== Bonus system ==
 
One of the more important pieces of VCMI is the [[bonus system]]. It's described in a separate article.
 
One of the more important pieces of VCMI is the [[bonus system]]. It's described in a separate article.
 +
 +
== Configuration ==
 +
 +
Most of VCMI configuration files uses Json format and located in "config" directory
 +
 +
=== [[Json parser and writer]] ===
  
 
= Client =
 
= Client =
Line 20: Line 28:
 
== Main purposes of client ==
 
== Main purposes of client ==
  
Client is responsible for:
+
[[Client]] is responsible for:
 
* displaying state of game to human player
 
* displaying state of game to human player
 
* capturing player's actions and sending requests to server
 
* capturing player's actions and sending requests to server
Line 29: Line 37:
 
Rendering of graphics relies heavily on SDL. Currently we do not have any wrapper for SDL internal structures and most of rendering is about blitting surfaces using SDL_BlitSurface. We have a few function that make rendering easier or make specific parts of rendering (like printing text). They are places in client/SDL_Extensions and client/SDL_Framerate (the second one contains code responsible for keeping appropriate framerate, it should work more smart than just SDL_Delay(miliseconds)). In rendering, Interface object system is quite helpful. Its base is CIntObject class that is basically a base class for our library of GUI components and other objects.
 
Rendering of graphics relies heavily on SDL. Currently we do not have any wrapper for SDL internal structures and most of rendering is about blitting surfaces using SDL_BlitSurface. We have a few function that make rendering easier or make specific parts of rendering (like printing text). They are places in client/SDL_Extensions and client/SDL_Framerate (the second one contains code responsible for keeping appropriate framerate, it should work more smart than just SDL_Delay(miliseconds)). In rendering, Interface object system is quite helpful. Its base is CIntObject class that is basically a base class for our library of GUI components and other objects.
  
=== Primitive controls ===
+
=== Video player ===
  
VCMI provides a set of controls a window can be build from. We have already written basic counterparts of most of standard controls like buttons, labels etc. Here is a list of them:
+
Located in client/VideoHandler.cpp/.h, have several platform-specific versions:
* '''AdventureMapButton''' - standard button class for general use (its name is after its first application). Optimized for buttons having standard .DEF graphics. When it's pressed, all functions from its callback field are called.
+
* For 32-bit Windows - using original 32-bit libraries (binkw32.dll, smackw32.dll)
* '''CHighlightableButton''' - basically a checkbox. Has two callbacks: one for selecting and one for deselecting. It inherits from AdventureMapButton because most of graphics handling is common/
+
* For *nix systems - using ffmpeg libraries.
* '''CHighlightableButtonsGroup''' - a radio button group. It consist of many CHighlightableButtons. Functions from onChange are called when selection is changed (the parameter is the ID of selected button).
+
* Empty player for 64-bit Windows
* '''CSlider''' - a typical slider.
+
 
* '''CLabel''' - a label with custom font and color. It does nothing interesting.
+
=== [[Primitive controls]] ===
* '''CPicture''' - any bitmap.
 
* '''CTextInput''' - a textbox.
 
* '''CGStatusBar''' - a statusbar for general use.
 
  
 
== [[Adventure map interface]] ==
 
== [[Adventure map interface]] ==
Line 49: Line 54:
 
TBD
 
TBD
  
== [[Battle]] ==
+
== [[Battle interface]] ==
 
 
=== Animations of creatures ===
 
All animations of creatures in a battle are handled by storing currently displayed animations in pendingAnims vector. When server tells that an event requiring animation happens, info about it is added to pendingAnims. Every animation needs to be initialized (what indicates that this animation has started). show() function tries to initialize all not initialized animations every frame until it succeeds. Then nextFrame call-ins are called until animation removes itself from pendingAnims. During initialization it is checked if this animation can be played now or we must wait.
 
 
 
=== Showing sequence of stacks, obstacles and wall pieces ===
 
Firstly, all dead stacks are printed on the screen. Then alive stacks, obstacles and wall pieces are printed in order of appearance (number of hex they are placed on). This algorithm works fairly well if no creatures move, but due to the fact that while a creature is moving, its position is the destination, not the hex they are walking on, sometimes it makes some graphical glitches that are not easy to fix.
 
 
 
=== Desynchronization of state of the game and displayed animations ===
 
This problem is not limited to battles but here it is the most problematic. GameState is updated immediately after getting info from server while the player should see smooth transition between initial and final states, e.g. when one creature stack attack another one we should see decreased amount of creatures after the animation of attack is displayed, despite the fact that gameState contains the new amount before any animation is displayed. Sometimes it can even lead to crashes when an action of the user makes the battle finished in gameState but wants to see all remaining actions of stacks - but the engine cannot respond to new inquires and destroys all data about stacks that weren't duplicated by battle interface.
 
 
 
This issue can be partly resolved by stopping the processing of data from server but it's not widely used nor elegant solution.
 
  
= [[Server]] =
+
= Server =
  
 
== Main purposes of server ==
 
== Main purposes of server ==
  
Server is responsible for:
+
[[Server]] is responsible for:
 
* maintaining state of the game
 
* maintaining state of the game
 
* handling requests from all clients participating in game
 
* handling requests from all clients participating in game
 
* informing all clients about changes in state of the game that are visible to them
 
* informing all clients about changes in state of the game that are visible to them
  
= [[Lib]] =
+
= Lib =
  
 
== Main purposes of lib ==
 
== Main purposes of lib ==
Line 77: Line 71:
 
Important: the library code is common for client and server and used by them, but the library instance (in opposition to the library as file) is not shared by them! Both client and server create their own "copies" of lib with all its class instances.
 
Important: the library code is common for client and server and used by them, but the library instance (in opposition to the library as file) is not shared by them! Both client and server create their own "copies" of lib with all its class instances.
  
Lib contains code responsible for:
+
iOS platform pioneered single process build, where server is a static library and not a dedicated executable. For that to work, the lib had to be wrapped into special namespace that is defined by client and server targets on iOS, so that single process is able to contain 2 versions of the library. To make it more convenient, a few macros were introduced that can be found in [https://github.com/vcmi/vcmi/blob/develop/Global.h Global.h]. The most important ones are <code>VCMI_LIB_NAMESPACE_BEGIN</code> and <code>VCMI_LIB_NAMESPACE_END</code> which must be used anywhere a symbol from the lib is needed, otherwise building iOS (or any other platform that would use single process approach) fails. See [[#Wrapped namespace examples]].
 +
 
 +
[[Lib]] contains code responsible for:
 
* handling most of Heroes III files (.lod, .txt setting files)
 
* handling most of Heroes III files (.lod, .txt setting files)
 
* storing information common to server and client like state of the game
 
* storing information common to server and client like state of the game
Line 83: Line 79:
 
* handling general game mechanics and related actions (only adventure map objects; it's an unwanted remnant of past development - all game mechanics should be handled by the server)
 
* handling general game mechanics and related actions (only adventure map objects; it's an unwanted remnant of past development - all game mechanics should be handled by the server)
 
* networking and serialization
 
* networking and serialization
 +
 +
=== [[Serialization]] ===
 +
The serialization framework can serialize basic types, several standard containers among smart pointers and custom objects. Its design is based on the [http://www.boost.org/doc/libs/1_52_0/libs/serialization/doc/index.html boost serialization libraries]. In addition to the basic functionality it provides light-weight transfer of CGObjectInstance objects by sending only the index/id.
 +
 +
See the [[Serialization]] page for all the details.
 +
 +
=== Wrapped namespace examples ===
 +
 +
==== Inside the lib ====
 +
Both header and implementation of a new class inside the lib should have the following structure:
 +
<nowiki><includes>
 +
VCMI_LIB_NAMESPACE_BEGIN
 +
<code>
 +
VCMI_LIB_NAMESPACE_END</nowiki>
 +
 +
Example: [https://github.com/vcmi/vcmi/blob/develop/lib/CBuildingHandler.h header] and [https://github.com/vcmi/vcmi/blob/develop/lib/CBuildingHandler.cpp implementation]
 +
 +
==== Headers outside the lib ====
 +
Forward declarations of the lib in headers of other parts of the project need to be wrapped in the macros:
 +
<nowiki><includes>
 +
VCMI_LIB_NAMESPACE_BEGIN
 +
<lib forward declarations>
 +
VCMI_LIB_NAMESPACE_END
 +
<other forward declarations>
 +
<classes></nowiki>
 +
 +
Example: https://github.com/vcmi/vcmi/blob/develop/server/CGameHandler.h
 +
 +
==== New project part ====
 +
If you're creating new project part, place <code>VCMI_LIB_USING_NAMESPACE</code> in its <code>StdInc.h</code> to be able to use lib classes without explicit namespace in implementation files. Example: https://github.com/vcmi/vcmi/blob/develop/launcher/StdInc.h
  
 
=  [[Artificial Intelligence]] (AI)=
 
=  [[Artificial Intelligence]] (AI)=
  
== Structure of AI (GeniusAI) ==
+
== [[StupidAI]] ==
  
TBD
+
Stupid AI is recent and used battle AI.
 +
 
 +
== [[Adventure AI]] ==
 +
 
 +
VCAI module is currently developed agent-based system driven by goals and heroes.
 +
 
 +
== [[Programming challenge]] ==
 +
 
 +
== [[Fuzzy logic]] ==
 +
 
 +
VCMI includes [http://code.google.com/p/fuzzy-lite/ FuzzyLite] library to make use of fuzzy rule-based algorithms. They are useful to handle uncertanity and resemble human behaviour who takes decisions based on rough observations.
 +
FuzzyLite is linked as separate static library in AI/FuzzyLite.lib file.
 +
 
 +
= [[Utilities]] =
 +
==[[Launcher]]==
 +
==[[Duels]]==
 +
 
 +
[[Mod system proposal]]
 +
 
 +
== [[ERM parser]] ==

Revision as of 15:28, 26 September 2022

The code of VCMI is divided into several main parts: client, server, lib and AIs, each one in a separate binary file.

The big picture

Architektura.png

VCMI contains three core projects: VCMI_lib (dll / so), VCMI_client (executable) and VCMI_server (executable). Server handles all game mechanics and events. Client presents game state and events to player and collects input from him.

During the game, we have one (and only one) server and one or more (one for each player computer) clients.

Important: State of the game and its mechanics are synchronized between clients and server. All changes to the game state or mechanics must be done by server which will send appropriate notices to clients.

Game state

It's basically CGameState class object and everything that's accessible from it: map (with objects), player statuses, game options, etc.

Bonus system

One of the more important pieces of VCMI is the bonus system. It's described in a separate article.

Configuration

Most of VCMI configuration files uses Json format and located in "config" directory

Json parser and writer

Client

Main purposes of client

Client is responsible for:

  • displaying state of game to human player
  • capturing player's actions and sending requests to server
  • displaying changes in state of game indicated by server

Rendering of graphics

Rendering of graphics relies heavily on SDL. Currently we do not have any wrapper for SDL internal structures and most of rendering is about blitting surfaces using SDL_BlitSurface. We have a few function that make rendering easier or make specific parts of rendering (like printing text). They are places in client/SDL_Extensions and client/SDL_Framerate (the second one contains code responsible for keeping appropriate framerate, it should work more smart than just SDL_Delay(miliseconds)). In rendering, Interface object system is quite helpful. Its base is CIntObject class that is basically a base class for our library of GUI components and other objects.

Video player

Located in client/VideoHandler.cpp/.h, have several platform-specific versions:

  • For 32-bit Windows - using original 32-bit libraries (binkw32.dll, smackw32.dll)
  • For *nix systems - using ffmpeg libraries.
  • Empty player for 64-bit Windows

Primitive controls

Adventure map interface

TBD

Town interface

TBD

Battle interface

Server

Main purposes of server

Server is responsible for:

  • maintaining state of the game
  • handling requests from all clients participating in game
  • informing all clients about changes in state of the game that are visible to them

Lib

Main purposes of lib

VCMI_Lib is a library that contains code common to server and client, so we avoid it's duplication. Important: the library code is common for client and server and used by them, but the library instance (in opposition to the library as file) is not shared by them! Both client and server create their own "copies" of lib with all its class instances.

iOS platform pioneered single process build, where server is a static library and not a dedicated executable. For that to work, the lib had to be wrapped into special namespace that is defined by client and server targets on iOS, so that single process is able to contain 2 versions of the library. To make it more convenient, a few macros were introduced that can be found in Global.h. The most important ones are VCMI_LIB_NAMESPACE_BEGIN and VCMI_LIB_NAMESPACE_END which must be used anywhere a symbol from the lib is needed, otherwise building iOS (or any other platform that would use single process approach) fails. See #Wrapped namespace examples.

Lib contains code responsible for:

  • handling most of Heroes III files (.lod, .txt setting files)
  • storing information common to server and client like state of the game
  • managing armies, buildings, artifacts, spells, bonuses and other game objects
  • handling general game mechanics and related actions (only adventure map objects; it's an unwanted remnant of past development - all game mechanics should be handled by the server)
  • networking and serialization

Serialization

The serialization framework can serialize basic types, several standard containers among smart pointers and custom objects. Its design is based on the boost serialization libraries. In addition to the basic functionality it provides light-weight transfer of CGObjectInstance objects by sending only the index/id.

See the Serialization page for all the details.

Wrapped namespace examples

Inside the lib

Both header and implementation of a new class inside the lib should have the following structure:

<includes>
VCMI_LIB_NAMESPACE_BEGIN
<code>
VCMI_LIB_NAMESPACE_END

Example: header and implementation

Headers outside the lib

Forward declarations of the lib in headers of other parts of the project need to be wrapped in the macros:

<includes>
VCMI_LIB_NAMESPACE_BEGIN
<lib forward declarations>
VCMI_LIB_NAMESPACE_END
<other forward declarations>
<classes>

Example: https://github.com/vcmi/vcmi/blob/develop/server/CGameHandler.h

New project part

If you're creating new project part, place VCMI_LIB_USING_NAMESPACE in its StdInc.h to be able to use lib classes without explicit namespace in implementation files. Example: https://github.com/vcmi/vcmi/blob/develop/launcher/StdInc.h

Artificial Intelligence (AI)

StupidAI

Stupid AI is recent and used battle AI.

Adventure AI

VCAI module is currently developed agent-based system driven by goals and heroes.

Programming challenge

Fuzzy logic

VCMI includes FuzzyLite library to make use of fuzzy rule-based algorithms. They are useful to handle uncertanity and resemble human behaviour who takes decisions based on rough observations. FuzzyLite is linked as separate static library in AI/FuzzyLite.lib file.

Utilities

Launcher

Duels

Mod system proposal

ERM parser