mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-15 20:03:15 +02:00
Updated developer docs
This commit is contained in:
@@ -64,6 +64,12 @@ Please see corresponding installation guide articles for details for your platfo
|
|||||||
|
|
||||||
## Documentation and guidelines for maintainers
|
## Documentation and guidelines for maintainers
|
||||||
|
|
||||||
|
- [Project Infrastructure](maintainers/Project_Infrastructure.md)
|
||||||
|
- [Project Servers Configuration](maintainers/Project_Servers_Configuration.md)
|
||||||
|
- [Release Process](maintainers/Release_Process.md)
|
||||||
|
- [Ubuntu PPA](maintainers/Ubuntu_PPA.md)
|
||||||
|
|
||||||
|
|
||||||
## Copyright and license
|
## Copyright and license
|
||||||
|
|
||||||
VCMI Project source code is licensed under GPL version 2 or later.
|
VCMI Project source code is licensed under GPL version 2 or later.
|
||||||
|
@@ -1,12 +1,6 @@
|
|||||||
The bonus system of VCMI is a set of mechanisms that make handling of
|
The bonus system of VCMI is a set of mechanisms that make handling of different bonuses for heroes, towns, players and units easier. The system consists of a set of nodes representing objects that can be a source or a subject of a bonus and two directed acyclic graphs (DAGs) representing inheritance and propagation of bonuses. Core of bonus system is defined in HeroBonus.h file.
|
||||||
different bonuses for heroes, towns, players and units easier. The
|
|
||||||
system consists of a set of nodes representing objects that can be a
|
|
||||||
source or a subject of a bonus and two directed acyclic graphs (DAGs)
|
|
||||||
representing inheritance and propagation of bonuses. Core of bonus
|
|
||||||
system is defined in HeroBonus.h file.
|
|
||||||
|
|
||||||
Here is a brief sketch of the system (black arrows indicate the
|
Here is a brief sketch of the system (black arrows indicate the direction of inheritance and red arrows the direction of propagation):
|
||||||
direction of inheritance and red arrows the direction of propagation):
|
|
||||||
|
|
||||||
<figure>
|
<figure>
|
||||||
<img src="Bonus_system.png" title="Bonus_system.png" />
|
<img src="Bonus_system.png" title="Bonus_system.png" />
|
||||||
@@ -15,114 +9,76 @@ direction of inheritance and red arrows the direction of propagation):
|
|||||||
|
|
||||||
## Propagation and inheritance
|
## Propagation and inheritance
|
||||||
|
|
||||||
Each bonus originates from some node in the bonus system, and may have
|
Each bonus originates from some node in the bonus system, and may have propagator and limiter objects attached to it. Bonuses are shared around as follows:
|
||||||
propagator and limiter objects attached to it. Bonuses are shared around
|
|
||||||
as follows:
|
|
||||||
|
|
||||||
1. Bonuses with propagator are propagated to "matching" descendants in
|
1. Bonuses with propagator are propagated to "matching" descendants in the red DAG - which descendants match is determined by the propagator. Bonuses without a propagator will not be propagated.
|
||||||
the red DAG - which descendants match is determined by the
|
2. Bonuses without limiters are inherited by all descendants in the black DAG. If limiters are present, they can restrict inheritance to certain nodes.
|
||||||
propagator. Bonuses without a propagator will not be propagated.
|
|
||||||
2. Bonuses without limiters are inherited by all descendants in the
|
|
||||||
black DAG. If limiters are present, they can restrict inheritance to
|
|
||||||
certain nodes.
|
|
||||||
|
|
||||||
Inheritance is the default means of sharing bonuses. A typical example
|
Inheritance is the default means of sharing bonuses. A typical example is an artefact granting a bonus to attack/defense stat, which is inherited by the hero wearing it, and then by creatures in the hero's army.
|
||||||
is an artefact granting a bonus to attack/defense stat, which is
|
A common limiter is by creature - e.g. the hero Eric has a specialty that grants bonuses to attack, defense and speed, but only to griffins.
|
||||||
inherited by the hero wearing it, and then by creatures in the hero's
|
Propagation is used when bonuses need to be shared in a different direction than the black DAG for inheritance. E.g. Magi and Archmagi on the battlefield reduce the cost of spells for the controlling hero.
|
||||||
army.
|
|
||||||
|
|
||||||
A common limiter is by creature - e.g. the hero Eric has a specialty
|
|
||||||
that grants bonuses to attack, defense and speed, but only to griffins.
|
|
||||||
|
|
||||||
Propagation is used when bonuses need to be shared in a different
|
|
||||||
direction than the black DAG for inheritance. E.g. Magi and Archmagi on
|
|
||||||
the battlefield reduce the cost of spells for the controlling hero.
|
|
||||||
|
|
||||||
### Technical Details
|
### Technical Details
|
||||||
|
|
||||||
- Propagation is done by copying bonuses to the target nodes. This
|
- Propagation is done by copying bonuses to the target nodes. This happens when bonuses are added.
|
||||||
happens when bonuses are added.
|
- Inheritance is done on-the-fly when needed, by traversing the black DAG. Results are cached to improve performance.
|
||||||
- Inheritance is done on-the-fly when needed, by traversing the black
|
- Whenever a node changes (e.g. bonus added), a global counter gets increased which is used to check whether cached results are still current.
|
||||||
DAG. Results are cached to improve performance.
|
|
||||||
- Whenever a node changes (e.g. bonus added), a global counter gets
|
|
||||||
increased which is used to check whether cached results are still
|
|
||||||
current.
|
|
||||||
|
|
||||||
## Operations on the graph
|
## Operations on the graph
|
||||||
|
|
||||||
There are two basic types of operations that can be performed on the
|
There are two basic types of operations that can be performed on the graph:
|
||||||
graph:
|
|
||||||
|
|
||||||
### Adding a new node
|
### Adding a new node
|
||||||
|
|
||||||
When node is attached to a new black parent [1], the propagation system
|
When node is attached to a new black parent [1], the propagation system is triggered and works as follows:
|
||||||
is triggered and works as follows:
|
- For the attached node and its all red ancestors
|
||||||
|
- For every bonus
|
||||||
|
- Call propagator giving the new descendant -\> then attach appropriately bonuses to the red descendant of attached node (or the node itself).
|
||||||
|
|
||||||
|
E.g. when a hero equips an artifact, the hero gets attached to the artifact to inherit its bonuses.
|
||||||
For the attached node and its all red ancestors
|
|
||||||
|
|
||||||
|
|
||||||
For every bonus
|
|
||||||
|
|
||||||
|
|
||||||
Call propagator giving the new descendant -\> then attach appropriately
|
|
||||||
bonuses to the red descendant of attached node (or the node itself).
|
|
||||||
|
|
||||||
E.g. when a hero equips an artifact, the hero gets attached to the
|
|
||||||
artifact to inherit its bonuses.
|
|
||||||
|
|
||||||
### Deleting an existing node
|
### Deleting an existing node
|
||||||
|
|
||||||
Analogically to the adding a new node, just remove propagated bonuses
|
Analogically to the adding a new node, just remove propagated bonuses instead of adding them. Then update the hierarchy.
|
||||||
instead of adding them. Then update the hierarchy.
|
|
||||||
|
|
||||||
E.g. when a hero removes an artifact, the hero (which became a child of
|
E.g. when a hero removes an artifact, the hero (which became a child of the artifact when equipping it) is removed from it.
|
||||||
the artifact when equipping it) is removed from it.
|
|
||||||
|
|
||||||
Note that only *propagated* bonuses need to be handled when nodes are
|
Note that only *propagated* bonuses need to be handled when nodes are added or removed. *Inheritance* is done on-the-fly and thus automatic.
|
||||||
added or removed. *Inheritance* is done on-the-fly and thus automatic.
|
|
||||||
|
|
||||||
## Limiters
|
## Limiters
|
||||||
|
|
||||||
If multiple limiters are specified for a bonus, a child inherits the
|
If multiple limiters are specified for a bonus, a child inherits the bonus only if all limiters say that it should.
|
||||||
bonus only if all limiters say that it should.
|
|
||||||
|
|
||||||
So e.g. a list of multiple creature type limiters (with different
|
So e.g. a list of multiple creature type limiters (with different creatures) would ensure that no creature inherits the bonus. In such a case, the solution is to use one bonus per creature.
|
||||||
creatures) would ensure that no creature inherits the bonus. In such a
|
|
||||||
case, the solution is to use one bonus per creature.
|
|
||||||
|
|
||||||
## Propagators
|
## Propagators
|
||||||
|
|
||||||
## Updaters
|
## Updaters
|
||||||
|
|
||||||
Updaters are objects attached to bonuses. They can modify a bonus
|
Updaters are objects attached to bonuses. They can modify a bonus (typically by changing *val*) during inheritance, including bonuses that a node "inherits" from itself, based on properties (typically level) of the node it passes through. Which nodes update a bonus depends on the type of updater. E.g. updaters that perform updates based on hero level will update bonuses as the are inherited by heroes.
|
||||||
(typically by changing *val*) during inheritance, including bonuses that
|
|
||||||
a node "inherits" from itself, based on properties (typically level) of
|
|
||||||
the node it passes through. Which nodes update a bonus depends on the
|
|
||||||
type of updater. E.g. updaters that perform updates based on hero level
|
|
||||||
will update bonuses as the are inherited by heroes.
|
|
||||||
|
|
||||||
The following example shows an artifact providing a bonus based on the
|
The following example shows an artifact providing a bonus based on the level of the hero that wears it:
|
||||||
level of the hero that wears it:
|
|
||||||
|
|
||||||
` "core:greaterGnollsFlail":`
|
```javascript
|
||||||
` {`
|
"core:greaterGnollsFlail":
|
||||||
` "text" : { "description" : "This mighty flail increases the attack of all gnolls under the hero's command by twice the hero's level." },`
|
{
|
||||||
` "bonuses" : [`
|
"text" : { "description" : "This mighty flail increases the attack of all gnolls under the hero's command by twice the hero's level." },
|
||||||
` {`
|
"bonuses" : [
|
||||||
` "limiters" : [`
|
{
|
||||||
` {`
|
"limiters" : [
|
||||||
` "parameters" : [ "gnoll", true ],`
|
{
|
||||||
` "type" : "CREATURE_TYPE_LIMITER"`
|
"parameters" : [ "gnoll", true ],
|
||||||
` }`
|
"type" : "CREATURE_TYPE_LIMITER"
|
||||||
` ],`
|
}
|
||||||
` "subtype" : "primSkill.attack",`
|
],
|
||||||
` "type" : "PRIMARY_SKILL",`
|
"subtype" : "primSkill.attack",
|
||||||
` "val" : 2,`
|
"type" : "PRIMARY_SKILL",
|
||||||
` "updater" : "TIMES_HERO_LEVEL"`
|
"val" : 2,
|
||||||
` }`
|
"updater" : "TIMES_HERO_LEVEL"
|
||||||
` ]`
|
}
|
||||||
` }`
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Calculating the total value of a bonus
|
## Calculating the total value of a bonus
|
||||||
|
|
||||||
@@ -136,5 +92,4 @@ TBD
|
|||||||
|
|
||||||
<references/>
|
<references/>
|
||||||
|
|
||||||
[1] the only possibility -\> adding parent is the same as adding a child
|
[1] the only possibility -\> adding parent is the same as adding a child to it
|
||||||
to it
|
|
74
docs/developers/Building_Android.md
Normal file
74
docs/developers/Building_Android.md
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
The following instructions apply to **v1.2 and later**. For earlier versions the best documentation is https://github.com/vcmi/vcmi-android/blob/master/building.txt (and reading scripts in that repo), however very limited to no support will be provided from our side if you wish to go down that rabbit hole.
|
||||||
|
|
||||||
|
*Note*: building has been tested only on Linux and macOS. It may or may not work on Windows out of the box.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
1. CMake 3.20+: download from your package manager or from https://cmake.org/download/
|
||||||
|
2. JDK 11, not necessarily from Oracle
|
||||||
|
3. Android command line tools or Android Studio for your OS: https://developer.android.com/studio/
|
||||||
|
4. Android NDK version **r25c (25.2.9519653)**, there're multiple ways to obtain it:
|
||||||
|
- - install with Android Studio
|
||||||
|
- - install with `sdkmanager` command line tool
|
||||||
|
- - download from https://developer.android.com/ndk/downloads
|
||||||
|
- - download with Conan, see [#NDK and Conan](#NDK_and_Conan "wikilink")
|
||||||
|
5. (optional) Ninja: download from your package manager or from https://github.com/ninja-build/ninja/releases
|
||||||
|
|
||||||
|
## Obtaining source code
|
||||||
|
|
||||||
|
Clone https://github.com/vcmi/vcmi with submodules. Example for command line:
|
||||||
|
|
||||||
|
`git clone --recurse-submodules https://github.com/vcmi/vcmi.git`
|
||||||
|
|
||||||
|
## Obtaining dependencies
|
||||||
|
|
||||||
|
We use Conan package manager to build/consume dependencies, find detailed usage instructions [here](https://github.com/vcmi/vcmi/tree/develop/docs/conan.md). Note that the link points to the cutting-edge state in `develop` branch, for the latest release check the same document in the [master
|
||||||
|
branch](https://github.com/vcmi/vcmi/tree/master/docs/conan.md).
|
||||||
|
|
||||||
|
On the step where you need to replace **PROFILE**, choose:
|
||||||
|
- `android-32` to build for 32-bit architecture (armeabi-v7a)
|
||||||
|
- `android-64` to build for 64-bit architecture (aarch64-v8a)
|
||||||
|
|
||||||
|
### NDK and Conan
|
||||||
|
|
||||||
|
Conan must be aware of the NDK location when you execute `conan install`. There're multiple ways to achieve that as written in the [Conan docs](https://docs.conan.io/1/integrations/cross_platform/android.html):
|
||||||
|
|
||||||
|
- the easiest is to download NDK from Conan (option 1 in the docs), then all the magic happens automatically. You need to create your own Conan profile that imports our Android profile and adds 2 new lines (you can of course just copy everything from our profile into yours without including) and then pass this new profile to `conan install`:
|
||||||
|
|
||||||
|
`include(/path/to/vcmi/CI/conan/android-64)`
|
||||||
|
`[tool_requires]`
|
||||||
|
`android-ndk/r25c`
|
||||||
|
|
||||||
|
- to use an already installed NDK, you can simply pass it on the command line to `conan install`:
|
||||||
|
|
||||||
|
`conan install -c tools.android:ndk_path=/path/to/ndk ...`
|
||||||
|
|
||||||
|
## Build process
|
||||||
|
|
||||||
|
Building for Android is a 2-step process. First, native C++ code is compiled to a shared library (unlike executable on other platforms), then Java code is compiled to an actual executable which will be loading the native shared library at runtime.
|
||||||
|
|
||||||
|
### C++ code
|
||||||
|
|
||||||
|
This is a traditional CMake project, you can build it from command line or some IDE. You're not required to pass any custom options (except Conan toolchain file), defaults are already good. If you wish to use your own CMake presets, inherit them from our `build-with-conan` preset. Example:
|
||||||
|
|
||||||
|
`cmake -S . -B ../build -G Ninja -D CMAKE_BUILD_TYPE=Debug --toolchain ...`
|
||||||
|
`cmake --build ../build`
|
||||||
|
|
||||||
|
You can also see a more detailed walkthrough on CMake configuration at [How to build VCMI (macOS)#Configuring project for building](How_to_build_VCMI_(macOS)#Configuring_project_for_building "wikilink").
|
||||||
|
|
||||||
|
### Java code
|
||||||
|
|
||||||
|
After the C++ part is built, native shared libraries are copied to the appropriate location of the Java project (they will be packaged in the APK). You can either open the Java project located in `android` directory of the repo in Android studio and work with it as with any Android project or build from command line.
|
||||||
|
|
||||||
|
Example how to build from command line in Bash shell, assumes that current working directory is VCMI repository:
|
||||||
|
|
||||||
|
`# the following environment variables must be set`
|
||||||
|
`export JAVA_HOME=/path/to/jdk11`
|
||||||
|
`export ANDROID_HOME=/path/to/android/sdk`
|
||||||
|
``
|
||||||
|
`cd android`
|
||||||
|
`./gradlew assembleDebug`
|
||||||
|
|
||||||
|
APK will appear in `android/vcmi-app/build/outputs/apk/debug` directory which you can then install to your device with `adb install -r /path/to/apk` (adb command is from Android command line tools).
|
||||||
|
|
||||||
|
If you wish to build and install to your device in single action, use `installDebug` instead of `assembleDebug`.
|
117
docs/developers/Building_Linux.md
Normal file
117
docs/developers/Building_Linux.md
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# Compiling VCMI
|
||||||
|
|
||||||
|
- Current baseline requirement for building is Ubuntu 20.04
|
||||||
|
- Supported C++ compilers for UNIX-like systems are GCC 5.5+ and Clang 13+
|
||||||
|
|
||||||
|
Older distributions and compilers might work, but they aren't tested by [Travis CI](https://travis-ci.org/vcmi/vcmi/)
|
||||||
|
|
||||||
|
# Installing dependencies
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
To compile, the following packages (and their development counterparts) are needed to build:
|
||||||
|
|
||||||
|
- CMake 3.10 or newer
|
||||||
|
- SDL2 with devel packages: mixer, image, ttf
|
||||||
|
- zlib and zlib-devel
|
||||||
|
- Recommended, if you want to build launcher or map editor: Qt 5, widget and network modules
|
||||||
|
- Recommended, FFmpeg libraries, if you want to watch in-game videos: libavformat and libswscale. Their name could be libavformat-devel and libswscale-devel, or ffmpeg-libs-devel or similar names.
|
||||||
|
- Boost C++ libraries v1.48+: program-options, filesystem, system, thread, locale
|
||||||
|
- Optional, if you want to build scripting modules: LuaJIT
|
||||||
|
|
||||||
|
## On Debian-based systems (e.g. Ubuntu)
|
||||||
|
|
||||||
|
For Ubuntu 22.04 (jammy) or newer you need to install this list of packages, including **libtbb2-dev**:
|
||||||
|
|
||||||
|
`sudo apt-get install cmake g++ libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-mixer-dev zlib1g-dev libavformat-dev libswscale-dev libboost-dev libboost-filesystem-dev libboost-system-dev libboost-thread-dev libboost-program-options-dev libboost-locale-dev qtbase5-dev libtbb2-dev libluajit-5.1-dev qttools5-dev`
|
||||||
|
|
||||||
|
For Ubuntu 21.10 (impish) or older and all versions of Debian (9 stretch - 11 bullseye) you need to install this list of packages, including **libtbb-dev**:
|
||||||
|
|
||||||
|
`sudo apt-get install cmake g++ libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-mixer-dev zlib1g-dev libavformat-dev libswscale-dev libboost-dev libboost-filesystem-dev libboost-system-dev libboost-thread-dev libboost-program-options-dev libboost-locale-dev qtbase5-dev libtbb-dev libluajit-5.1-dev qttools5-dev`
|
||||||
|
|
||||||
|
Alternatively if you have VCMI installed from repository or PPA you can use:
|
||||||
|
|
||||||
|
sudo apt-get build-dep vcmi
|
||||||
|
|
||||||
|
## On RPM-based distributions (e.g. Fedora)
|
||||||
|
|
||||||
|
sudo yum install cmake gcc-c++ SDL2-devel SDL2_image-devel SDL2_ttf-devel SDL2_mixer-devel boost boost-devel boost-filesystem boost-system boost-thread boost-program-options boost-locale zlib-devel ffmpeg-devel ffmpeg-libs qt5-qtbase-devel tbb-devel luajit-devel fuzzylite-devel
|
||||||
|
|
||||||
|
## On Arch-based distributions
|
||||||
|
|
||||||
|
On Arch-based distributions, there is a development package available for VCMI on the AUR.
|
||||||
|
|
||||||
|
It can be found at: <https://aur.archlinux.org/packages/vcmi-git/>
|
||||||
|
|
||||||
|
Information about building packages from the Arch User Repository (AUR) can be found at the Arch wiki.
|
||||||
|
|
||||||
|
# Getting the sources
|
||||||
|
|
||||||
|
VCMI is still in development. We recommend the following initial directory structure:
|
||||||
|
|
||||||
|
.
|
||||||
|
├── vcmi -> contains sources and is under git control
|
||||||
|
└── build -> contains build output, makefiles, object files,...
|
||||||
|
|
||||||
|
You can get latest sources with:
|
||||||
|
|
||||||
|
`git clone -b develop --recursive https://github.com/vcmi/vcmi.git`
|
||||||
|
|
||||||
|
# Compilation
|
||||||
|
|
||||||
|
## Configuring Makefiles
|
||||||
|
|
||||||
|
`mkdir build && cd build`
|
||||||
|
`cmake ../vcmi`
|
||||||
|
|
||||||
|
# Additional options that you may want to use:
|
||||||
|
|
||||||
|
## To enable debugging:
|
||||||
|
`cmake ../vcmi -DCMAKE_BUILD_TYPE=Debug`
|
||||||
|
|
||||||
|
**Notice**: The ../vcmi/ is not a typo, it will place makefile scripts into the build dir as the build dir is your working dir when calling CMake.
|
||||||
|
|
||||||
|
## Trigger build
|
||||||
|
|
||||||
|
`cmake --build . -- -j2`
|
||||||
|
(-j2 = compile with 2 threads, you can specify any value)
|
||||||
|
|
||||||
|
That will generate vcmiclient, vcmiserver, vcmilauncher as well as .so libraries in **build/bin/** directory.
|
||||||
|
|
||||||
|
# Package building
|
||||||
|
|
||||||
|
## RPM package
|
||||||
|
|
||||||
|
The first step is to prepare a RPM build environment. On Fedora systems you can follow this guide: <http://fedoraproject.org/wiki/How_to_create_an_RPM_package#SPEC_file_overview>
|
||||||
|
|
||||||
|
1. Download the file rpm/vcmi.spec from any tagged VCMI release for which you wish to build a RPM package via the SVN Browser trac at this URL for example(which is for VCMI 0.9): <http://sourceforge.net/apps/trac/vcmi/browser/tags/0.9/rpm/vcmi.spec>
|
||||||
|
|
||||||
|
2. Copy the file to ~/rpmbuild/SPECS
|
||||||
|
|
||||||
|
3. Follow instructions in the vcmi.spec. You have to export the corresponding SVN tag, compress it to a g-zipped archive and copy it to ~/rpmbuild/SOURCES. Instructions are written as comments and you can copy/paste commands into terminal.
|
||||||
|
|
||||||
|
4. Go to ~/rpmbuild/SPECS and open terminal in this folder and type:
|
||||||
|
`rpmbuild -ba vcmi.spec (this will build rpm and source rpm)`
|
||||||
|
|
||||||
|
5. Generated RPM is in folder ~/rpmbuild/RPMS
|
||||||
|
|
||||||
|
If you want to package the generated RPM above for different processor architectures and operating systems you can use the tool mock. Moreover, it is necessary to install mock-rpmfusion_free due to the packages ffmpeg-devel and ffmpeg-libs which aren't available in the standard RPM repositories(at least for Fedora). Go to ~/rpmbuild/SRPMS in terminal and type:
|
||||||
|
|
||||||
|
`mock -r fedora-17-i386-rpmfusion_free path_to_source_RPM`
|
||||||
|
`mock -r fedora-17-x86_64-rpmfusion_free path_to_source_RPM`
|
||||||
|
|
||||||
|
Available root environments and their names are listed in /etc/mock.
|
||||||
|
|
||||||
|
## Debian/Ubuntu
|
||||||
|
|
||||||
|
1. Install debhelper and devscripts packages
|
||||||
|
|
||||||
|
2. Run dpkg-buildpackage command from vcmi source directory
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt-get install debhelper devscripts
|
||||||
|
cd /path/to/source
|
||||||
|
dpkg-buildpackage
|
||||||
|
```
|
||||||
|
|
||||||
|
To generate packages for different architectures see "-a" flag of dpkg-buildpackage command
|
126
docs/developers/Building_Windows.md
Normal file
126
docs/developers/Building_Windows.md
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
# Preparations
|
||||||
|
Windows builds can be made in more than one way and with more than one tool. This guide focuses on the simplest building process using Microsoft Visual Studio 2022
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
|
||||||
|
- Windows Vista or newer.
|
||||||
|
- [Microsoft Visual Studio](https://visualstudio.microsoft.com/downloads/)
|
||||||
|
- Git or git GUI, for example, SourceTree [download](http://www.sourcetreeapp.com/download)
|
||||||
|
- CMake [download](https://cmake.org/download/). During install after accepting license agreement make sure to check "Add CMake to the system PATH for all users".
|
||||||
|
- To unpack pre-build Vcpkg: [7-zip](http://www.7-zip.org/download.html)
|
||||||
|
- Optionally, to create installer: [NSIS](http://nsis.sourceforge.net/Main_Page)
|
||||||
|
|
||||||
|
## Choose an installation directory
|
||||||
|
|
||||||
|
Create a directory for VCMI development, eg. `C:\VCMI` We will call this directory `%VCMI_DIR%`
|
||||||
|
|
||||||
|
Warning! Replace `%VCMI_DIR%` with path you've chosen for VCMI installation in the following commands.
|
||||||
|
|
||||||
|
It is recommended to avoid non-ascii characters in the path to your working folders. The folder should not be write-protected by system.
|
||||||
|
Good locations:
|
||||||
|
- `C:\VCMI`
|
||||||
|
Bad locations:
|
||||||
|
- `C:\Users\Michał\VCMI (non-ascii character)`
|
||||||
|
- `C:\Program Files (x86)\VCMI (write protection)`
|
||||||
|
|
||||||
|
# Install VCMI dependencies
|
||||||
|
|
||||||
|
You have two options: to use pre-built libraries or build your own. We strongly recommend start with using pre-built ones.
|
||||||
|
|
||||||
|
## Option A. Use pre-built Vcpkg
|
||||||
|
|
||||||
|
### Download and unpack archive
|
||||||
|
|
||||||
|
Vcpkg Archives are available at our GitHub: https://github.com/vcmi/vcmi-deps-windows/releases
|
||||||
|
|
||||||
|
- Download latest version available.
|
||||||
|
EG: v1.6 assets - [vcpkg-export-x64-windows-v143.7z](https://github.com/vcmi/vcmi-deps-windows/releases/download/v1.6/vcpkg-export-x64-windows-v143.7z)
|
||||||
|
- Extract archive by right clicking on it and choosing "7-zip -> Extract Here".
|
||||||
|
|
||||||
|
### Move dependencies to target directory
|
||||||
|
Once extracted, a `vcpkg` directory will appear with `installed` and `scripts` subfolders inside.
|
||||||
|
Move extracted `vcpkg` directory into your `%VCMI_DIR%`
|
||||||
|
|
||||||
|
## Option B. Build Vcpkg on your own
|
||||||
|
|
||||||
|
Please be aware that if you're running 32-bit Windows version, then this is impossible due to <https://github.com/microsoft/vcpkg/issues/26036>
|
||||||
|
Be aware that building Vcpkg might take a lot of time depend on your CPU model and 10-20GB of disk space.
|
||||||
|
|
||||||
|
### Create initial directory
|
||||||
|
|
||||||
|
### Clone vcpkg
|
||||||
|
|
||||||
|
1. open SourceTree
|
||||||
|
2. File -\> Clone
|
||||||
|
3. select **<https://github.com/microsoft/vcpkg/>** as source
|
||||||
|
4. select **%VCMI_DIR%/vcpkg** as destination
|
||||||
|
5. click **Clone**
|
||||||
|
|
||||||
|
From command line use:
|
||||||
|
|
||||||
|
git clone https://github.com/microsoft/vcpkg.git %VCMI_DIR%/vcpkg
|
||||||
|
|
||||||
|
### Build vcpkg and dependencies
|
||||||
|
|
||||||
|
- Run `%VCMI_DIR%/vcpkg/bootstrap-vcpkg.bat`
|
||||||
|
- For 32-bit build run: `%VCMI_DIR%/vcpkg/vcpkg.exe install tbb:x64-windows fuzzylite:x64-windows sdl2:x64-windows sdl2-image:x64-windows sdl2-ttf:x64-windows sdl2-mixer[mpg123]:x64-windows boost:x64-windows qt5-base:x64-windows ffmpeg:x64-windows luajit:x64-windows`
|
||||||
|
- For 64-bit build run: `%VCMI_DIR%/vcpkg/vcpkg.exe install install tbb:x86-windows fuzzylite:x86-windows sdl2:x86-windows sdl2-image:x86-windows sdl2-ttf:x86-windows sdl2-mixer[mpg123]:x86-windows boost:x86-windows qt5-base:x86-windows ffmpeg:x86-windows luajit:x86-windows`
|
||||||
|
|
||||||
|
For the list of the packages used you can also consult [vcmi-deps-windows readme](https://github.com/vcmi/vcmi-deps-windows) in case this article gets outdated a bit.
|
||||||
|
|
||||||
|
# Build VCMI
|
||||||
|
|
||||||
|
#### From GIT GUI
|
||||||
|
- Open SourceTree
|
||||||
|
- File -> Clone
|
||||||
|
- select `https://github.com/vcmi/vcmi/` as source
|
||||||
|
- select `%VCMI_DIR%/source` as destination
|
||||||
|
- expand Advanced Options and change Checkout Branch to `develop`
|
||||||
|
- tick `Recursive submodules`
|
||||||
|
- click Clone
|
||||||
|
|
||||||
|
#### From command line
|
||||||
|
- `git clone --recursive https://github.com/vcmi/vcmi.git %VCMI_DIR%/source`
|
||||||
|
|
||||||
|
## Generate solution for VCMI
|
||||||
|
- Create `%VCMI_DIR%/build` folder
|
||||||
|
- Open a command line prompt at `%VCMI_DIR%/build`
|
||||||
|
- Execute `cd %VCMI_DIR%/build`
|
||||||
|
- Create solution (Visual Studio 2022 64-bit) `cmake %VCMI_DIR%/source -DCMAKE_TOOLCHAIN_FILE=%VCMI_DIR%/vcpkg/scripts/buildsystems/vcpkg.cmake -G "Visual Studio 17 2022" -A x64`
|
||||||
|
|
||||||
|
## Compile VCMI with Visual Studio
|
||||||
|
- Open `%VCMI_DIR%/build/VCMI.sln` in Visual Studio
|
||||||
|
- Select `Release` build type in combobox
|
||||||
|
- Right click on `BUILD_ALL` project. This `BUILD_ALL` project should be in `CMakePredefinedTargets` tree in Solution Explorer.
|
||||||
|
- VCMI will be built in `%VCMI_DIR%/build/bin` folder!
|
||||||
|
|
||||||
|
# Create VCMI installer (This step is not required for just building & development)
|
||||||
|
|
||||||
|
Make sure NSIS is installed to default directory or have registry entry so CMake can find it.
|
||||||
|
After you build VCMI execute following commands from `%VCMI_DIR%/build`.
|
||||||
|
|
||||||
|
- for release build: `cpack`
|
||||||
|
- for debug build: `cpack -C Debug`
|
||||||
|
|
||||||
|
# Troubleshooting and workarounds
|
||||||
|
|
||||||
|
Vcpkg might be very unstable due to limited popularity and fact of using bleeding edge packages (such as most recent Boost). Using latest version of dependencies could also expose both problems in VCMI code or library interface changes that developers not checked yet. So if you're built Vcpkg yourself and can't get it working please try to use binary package.
|
||||||
|
|
||||||
|
Pre-built version we provide is always manually tested with all supported versions of MSVC for both Release and Debug builds and all known quirks are listed below.
|
||||||
|
|
||||||
|
#$# Build is successful but can not start new game
|
||||||
|
Make sure you have:
|
||||||
|
* Installed Heroes III from disk or using GOG installer
|
||||||
|
* Copied `Data`, `Maps` and `Mp3` folders from Heroes III to: `%USERPROFILE%\Documents\My Games\vcmi\`
|
||||||
|
|
||||||
|
### VCMI won't run since some library is missing
|
||||||
|
|
||||||
|
**If you open solution using vcmi.sln** Try to build INSTALL target and see if its output works as expected. Copy missing libraries or even all libraries from there to your build directory. Or run cpack and use produced installer and see if you can get libs from there. cpack -V will give more info. If cpack complains that it can not find dumpbin try Visual Studio Command Prompt (special version of cmd provided with Visual Studio with additional PATH) or modify PATH to have this tool available. Another alternative if you use prebuilt vcpkg package is to download latest msvc build, install it and copy missing/all libraries from there.
|
||||||
|
|
||||||
|
### Debug build is very slow
|
||||||
|
|
||||||
|
Debug builds with MSVC are generally extremely slow since it's not just VCMI binaries are built as debug, but every single dependency too and this usually means no optimizations at all. Debug information that available for release builds is often sufficient so just avoid full debug builds unless absolutely necessary. Instead use RelWithDebInfo configuration. Also Debug configuration might have some compilation issues because it is not checked via CI for now.
|
||||||
|
|
||||||
|
### I got crash within library XYZ.dll
|
||||||
|
|
||||||
|
VCPKG generated projects quite often have both debug and regular libs available to linker so it can select wrong lib. For stable RelWithDebInfo build you may try to remove debug folder from VCPKG/installed/x64-windows. Same is done on CI. Also it reduces package size at least twice.
|
68
docs/developers/Building_iOS.md
Normal file
68
docs/developers/Building_iOS.md
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
## Requirements
|
||||||
|
|
||||||
|
1. **macOS**
|
||||||
|
2. Xcode: <https://developer.apple.com/xcode/>
|
||||||
|
3. CMake 3.21+: `brew install --cask cmake` or get from <https://cmake.org/download/>
|
||||||
|
|
||||||
|
## Obtaining source code
|
||||||
|
|
||||||
|
Clone <https://github.com/vcmi/vcmi> with submodules. Example for command line:
|
||||||
|
|
||||||
|
`git clone --recurse-submodules https://github.com/vcmi/vcmi.git`
|
||||||
|
|
||||||
|
## Obtaining dependencies
|
||||||
|
|
||||||
|
There're 2 ways to get prebuilt dependencies:
|
||||||
|
|
||||||
|
- [Conan package manager](https://github.com/vcmi/vcmi/tree/develop/docs/conan.md) - recommended. Note that the link points to the cutting-edge state in `develop` branch, for the latest release check the same document in the [master branch (https://github.com/vcmi/vcmi/tree/master/docs/conan.md).
|
||||||
|
- [legacy manually built libraries](https://github.com/vcmi/vcmi-ios-deps) - can be used if you have Xcode 11/12 or to build for simulator / armv7 device
|
||||||
|
|
||||||
|
## Configuring project
|
||||||
|
|
||||||
|
Only Xcode generator (`-G Xcode`) is supported!
|
||||||
|
|
||||||
|
As a minimum, you must pass the following variables to CMake:
|
||||||
|
|
||||||
|
- `BUNDLE_IDENTIFIER_PREFIX`: unique bundle identifier prefix, something like `com.MY-NAME`
|
||||||
|
- (if using legacy dependencies) `CMAKE_PREFIX_PATH`: path to the downloaded dependencies, e.g. `~/Downloads/vcmi-ios-depends/build/iphoneos`
|
||||||
|
|
||||||
|
There're a few [CMake presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html): for device (Conan and legacy dependencies) and for simulator, named `ios-device-conan`, `ios-device` and `ios-simulator` respectively. You can also create your local "user preset" to avoid typing variables each time, see example [here](https://gist.github.com/kambala-decapitator/59438030c34b53aed7d3895aaa48b718).
|
||||||
|
|
||||||
|
Open terminal and `cd` to the directory with source code. Configuration example for device with Conan:
|
||||||
|
|
||||||
|
`cmake --preset ios-device-conan \`
|
||||||
|
` -D BUNDLE_IDENTIFIER_PREFIX=com.MY-NAME`
|
||||||
|
|
||||||
|
By default build directory containing Xcode project will appear at `../build-ios-device-conan`, but you can change it with `-B` option.
|
||||||
|
|
||||||
|
### Building for device
|
||||||
|
|
||||||
|
To be able to build for iOS device, you must also specify codesigning settings. If you don't know your development team ID, open the generated Xcode project, open project settings (click **VCMI** with blue icon on the very top in the left panel with files), select **vcmiclient** target, open **Signing & Capabilities** tab and select yout team. Now you can copy the value from **Build Settings** tab - `DEVELOPMENT_TEAM` variable (paste it in the Filter field on the right) - click the greenish value - Other... - copy. Now you can pass it in `CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM` variable when configuring the project to avoid selecting the team manually every time CMake re-generates the project.
|
||||||
|
|
||||||
|
Advanced users who know exact private key and provisioning profile to sign with, can use `CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY` and `CMAKE_XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER` variables instead. In this case you must also pass `-D CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE=Manual`.
|
||||||
|
|
||||||
|
## Building project
|
||||||
|
|
||||||
|
### From Xcode IDE
|
||||||
|
|
||||||
|
Open `VCMI.xcodeproj` from the build directory, select `vcmiclient` scheme (the only one with nice icon) with your destination device/simulator and hit Run (Cmd+R).
|
||||||
|
|
||||||
|
You must also install game files, see [Installation on iOS](Installation_on_iOS "wikilink"). But this is not necessary if you are going to run on simulator, as it is able to use game data from your Mac located at `~/Library/Application Support/vcmi`.
|
||||||
|
|
||||||
|
### From command line
|
||||||
|
|
||||||
|
`cmake --build `<path to build directory>` --target vcmiclient -- -quiet`
|
||||||
|
|
||||||
|
You can pass additional xcodebuild options after the `--`. Here `-quiet` is passed to reduce amount of output.
|
||||||
|
|
||||||
|
Alternatively, you can invoke `xcodebuild` directly.
|
||||||
|
|
||||||
|
There's also `ios-release-conan` configure and build preset that is used to create release build on CI.
|
||||||
|
|
||||||
|
## Creating ipa file for distribution
|
||||||
|
|
||||||
|
Invoke `cpack` after building:
|
||||||
|
|
||||||
|
`cpack -C Release`
|
||||||
|
|
||||||
|
This will generate file with extension **ipa** if you use CMake 3.25+and **zip** otherwise (simply change extension to ipa).
|
121
docs/developers/Building_macOS.md
Normal file
121
docs/developers/Building_macOS.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# Requirements
|
||||||
|
|
||||||
|
1. C++ toolchain, either of:
|
||||||
|
- Xcode Command Line Tools (aka CLT): `sudo xcode-select --install`
|
||||||
|
- Xcode IDE: <https://developer.apple.com/xcode/>
|
||||||
|
- (not tested) other C++ compilers, e.g. gcc/clang from [Homebrew](https://brew.sh/)
|
||||||
|
2. CMake: `brew install --cask cmake` or get from <https://cmake.org/download/>
|
||||||
|
3. (optional) Ninja: `brew install ninja` or get from <https://github.com/ninja-build/ninja/releases>
|
||||||
|
|
||||||
|
# Obtaining source code
|
||||||
|
|
||||||
|
Clone <https://github.com/vcmi/vcmi> with submodules. Example for command line:
|
||||||
|
|
||||||
|
`git clone --recurse-submodules https://github.com/vcmi/vcmi.git`
|
||||||
|
|
||||||
|
# Obtaining dependencies
|
||||||
|
|
||||||
|
There're 2 ways to get dependencies automatically.
|
||||||
|
|
||||||
|
## Conan package manager
|
||||||
|
|
||||||
|
Please find detailed instructions in [VCMI repository](https://github.com/vcmi/vcmi/tree/develop/docs/conan.md). Note that the link points to the cutting-edge state in `develop` branch, for the latest release check the same document in the [master branch](https://github.com/vcmi/vcmi/tree/master/docs/conan.md).
|
||||||
|
|
||||||
|
On the step where you need to replace **PROFILE**, choose:
|
||||||
|
|
||||||
|
- if you're on an Intel Mac: `macos-intel`
|
||||||
|
- if you're on an Apple Silicon Mac: `macos-arm`
|
||||||
|
|
||||||
|
Note: if you wish to build 1.0 release in non-`Release` configuration, you should define `USE_CONAN_WITH_ALL_CONFIGS=1` environment variable when executing `conan install`.
|
||||||
|
|
||||||
|
## Homebrew
|
||||||
|
|
||||||
|
1. [Install Homebrew](https://brew.sh/)
|
||||||
|
2. Install dependencies:
|
||||||
|
`brew install boost minizip sdl2 sdl2_image sdl2_mixer sdl2_ttf tbb`
|
||||||
|
3. If you want to watch in-game videos, also install FFmpeg:
|
||||||
|
`brew install ffmpeg@4`
|
||||||
|
4. Install Qt dependency in either of the ways (note that you can skip this if you're not going to build Launcher):
|
||||||
|
- `brew install qt@5` for Qt 5 or `brew install qt` for Qt 6
|
||||||
|
- using [Qt Online Installer](https://www.qt.io/download) - choose **Go open source**
|
||||||
|
|
||||||
|
# Preparing build environment
|
||||||
|
|
||||||
|
This applies only to Xcode-based toolchain. If `xcrun -f clang` prints errors, then use either of the following ways:
|
||||||
|
|
||||||
|
- select an Xcode instance from Xcode application - Preferences - Locations - Command Line Tools
|
||||||
|
- use `xcode-select` utility to set Xcode or Xcode Command Line Tools path: for example,
|
||||||
|
`sudo xcode-select -s /Library/Developer/CommandLineTools`
|
||||||
|
- set `DEVELOPER_DIR` environment variable pointing to Xcode or Xcode Command Line Tools path: for example, `export DEVELOPER_DIR=/Applications/Xcode.app`
|
||||||
|
|
||||||
|
# Configuring project for building
|
||||||
|
|
||||||
|
Note that if you wish to use Qt Creator IDE, you should skip this step and configure respective variables inside the IDE.
|
||||||
|
|
||||||
|
1. In Terminal `cd` to the source code directory
|
||||||
|
2. Start assembling CMake invocation: type `cmake -S . -B BUILD_DIR` where *BUILD_DIR* can be any path, **don't press Return**
|
||||||
|
3. Decide which CMake generator you want to use:
|
||||||
|
- Makefiles: no extra option needed or pass `-G 'Unix Makefiles'`
|
||||||
|
- Ninja (if you have installed it): pass `-G Ninja`
|
||||||
|
- Xcode IDE (if you have installed it): pass `-G Xcode`
|
||||||
|
4. If you picked Makefiles or Ninja, pick desired *build type* - either of Debug / RelWithDebInfo / Release / MinSizeRel - and pass it in `CMAKE_BUILD_TYPE` option, for example: `-D CMAKE_BUILD_TYPE=Release`. If you don't pass this option, `RelWithDebInfo` will be used.
|
||||||
|
5. If you don't want to build Launcher, pass `-D ENABLE_LAUNCHER=OFF`
|
||||||
|
6. You can also pass `-Wno-dev` if you're not interested in CMake developer warnings
|
||||||
|
7. Next step depends on the dependency manager you have picked:
|
||||||
|
- Conan: pass `-D CMAKE_TOOLCHAIN_FILE=conan-generated/conan_toolchain.cmake` where **conan-generated** must be replaced with your directory choice
|
||||||
|
- Homebrew: if you installed FFmpeg or Qt 5, you need to pass `-D "CMAKE_PREFIX_PATH="` variable. See below what you can insert after `=` (but **before the closing quote**), multiple values must be separated with `;` (semicolon):
|
||||||
|
- if you installed FFmpeg, insert `$(brew --prefix ffmpeg@4)`
|
||||||
|
- if you installed Qt 5 from Homebrew, insert:`$(brew --prefix qt@5)`
|
||||||
|
- if you installed Qt from Online Installer, insert your path to Qt directory, for example: `/Users/kambala/dev/Qt-libs/5.15.2/Clang64`
|
||||||
|
- example for FFmpeg + Qt 5: `-D "CMAKE_PREFIX_PATH=$(brew --prefix ffmpeg@4);$(brew --prefix qt@5)"`
|
||||||
|
8. now press Return
|
||||||
|
|
||||||
|
# Building project
|
||||||
|
|
||||||
|
You must also install game files to be able to run the built version, see [Installation on macOS](Installation_on_macOS "wikilink").
|
||||||
|
|
||||||
|
## From Xcode IDE
|
||||||
|
|
||||||
|
Open `VCMI.xcodeproj` from the build directory, select `vcmiclient` scheme and hit Run (Cmd+R). To build Launcher, select `vcmilauncher` scheme instead.
|
||||||
|
|
||||||
|
## From command line
|
||||||
|
|
||||||
|
`cmake --build `<path to build directory>
|
||||||
|
|
||||||
|
- If using Makefiles generator, you'd want to utilize all your CPU cores by appending `-- -j$(sysctl -n hw.ncpu)` to the above
|
||||||
|
- If using Xcode generator, you can also choose which configuration to build by appending `--config `<configuration name> to the above, for example: `--config Debug`
|
||||||
|
|
||||||
|
# Packaging project into DMG file
|
||||||
|
|
||||||
|
After building, run `cpack` from the build directory. If using Xcode generator, also pass `-C `<configuration name> with the same configuration that you used to build the project.
|
||||||
|
|
||||||
|
If you use Conan, it's expected that you use **conan-generated** directory at step 4 of [#Conan package manager](#Conan_package_manager "wikilink").
|
||||||
|
|
||||||
|
# Running VCMI
|
||||||
|
|
||||||
|
You can run VCMI from DMG, but it's will also work from your IDE be it Xcode or Qt Creator.
|
||||||
|
|
||||||
|
Alternatively you can run binaries directly from "bin" directory:
|
||||||
|
|
||||||
|
BUILD_DIR/bin/vcmilauncher
|
||||||
|
BUILD_DIR/bin/vcmiclient
|
||||||
|
BUILD_DIR/bin/vcmiserver
|
||||||
|
|
||||||
|
CMake include commands to copy all needed assets from source directory into "bin" on each build. They'll work when you build from Xcode too.
|
||||||
|
|
||||||
|
# Some useful debugging tips
|
||||||
|
|
||||||
|
Anyone who might want to debug builds, but new to macOS could find following commands useful:
|
||||||
|
|
||||||
|
- To attach DMG file from command line use
|
||||||
|
`hdiutil attach vcmi-1.0.dmg`
|
||||||
|
- Detach volume:
|
||||||
|
`hdiutil detach /Volumes/vcmi-1.0`
|
||||||
|
- To view dependency paths
|
||||||
|
`otool -L /Volumes/vcmi-1.0/VCMI.app/Contents/MacOS/vcmiclient`
|
||||||
|
- To display load commands such as LC_RPATH
|
||||||
|
`otool -l /Volumes/vcmi-1.0/VCMI.app/Contents/MacOS/vcmiclient`
|
||||||
|
|
||||||
|
# Troubleshooting
|
||||||
|
|
||||||
|
In case of troubles you can always consult our CI build scripts or contact the dev team via slack
|
@@ -1,5 +1,4 @@
|
|||||||
The code of VCMI is divided into several main parts: client, server, lib
|
The code of VCMI is divided into several main parts: client, server, lib and AIs, each one in a separate binary file.
|
||||||
and AIs, each one in a separate binary file.
|
|
||||||
|
|
||||||
# The big picture
|
# The big picture
|
||||||
|
|
||||||
@@ -8,33 +7,23 @@ and AIs, each one in a separate binary file.
|
|||||||
<figcaption>Architektura.png</figcaption>
|
<figcaption>Architektura.png</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
VCMI contains three core projects: VCMI_lib (dll / so), VCMI_client
|
VCMI contains three core projects: VCMI_lib (dll / so), VCMI_client (executable) and VCMI_server (executable). [Server](Server "wikilink") handles all [game mechanics](game_mechanics "wikilink") and events. [Client](Client "wikilink") presents [game state](game_state "wikilink") and events to player and collects input from him.
|
||||||
(executable) and VCMI_server (executable). [Server](Server "wikilink")
|
|
||||||
handles all [game mechanics](game_mechanics "wikilink") and events.
|
|
||||||
[Client](Client "wikilink") presents [game state](game_state "wikilink")
|
|
||||||
and events to player and collects input from him.
|
|
||||||
|
|
||||||
During the game, we have one (and only one) server and one or more (one
|
During the game, we have one (and only one) server and one or more (one for each player computer) clients.
|
||||||
for each player computer) clients.
|
|
||||||
|
|
||||||
Important: State of the game and its mechanics are synchronized between
|
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.
|
||||||
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
|
## Game state
|
||||||
|
|
||||||
It's basically CGameState class object and everything that's accessible
|
It's basically CGameState class object and everything that's accessible from it: map (with objects), player statuses, game options, etc.
|
||||||
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
|
One of the more important pieces of VCMI is the [bonus system](bonus_system "wikilink"). It's described in a separate article.
|
||||||
system](bonus_system "wikilink"). It's described in a separate article.
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Most of VCMI configuration files uses Json format and located in
|
Most of VCMI configuration files uses Json format and located in "config" directory
|
||||||
"config" directory
|
|
||||||
|
|
||||||
### [Json parser and writer](Json_parser_and_writer "wikilink")
|
### [Json parser and writer](Json_parser_and_writer "wikilink")
|
||||||
|
|
||||||
@@ -43,33 +32,21 @@ Most of VCMI configuration files uses Json format and located in
|
|||||||
## Main purposes of client
|
## Main purposes of client
|
||||||
|
|
||||||
[Client](Client "wikilink") is responsible for:
|
[Client](Client "wikilink") 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
|
||||||
- displaying changes in state of game indicated by server
|
- displaying changes in state of game indicated by server
|
||||||
|
|
||||||
## Rendering of graphics
|
## Rendering of graphics
|
||||||
|
|
||||||
Rendering of graphics relies heavily on SDL. Currently we do not have
|
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)).
|
||||||
any wrapper for SDL internal structures and most of rendering is about
|
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.
|
||||||
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
|
### Video player
|
||||||
|
|
||||||
Located in client/VideoHandler.cpp/.h, have several platform-specific
|
Located in client/VideoHandler.cpp/.h, have several platform-specific versions:
|
||||||
versions:
|
|
||||||
|
|
||||||
- For 32-bit Windows - using original 32-bit libraries (binkw32.dll,
|
- Using ffmpeg libraries.
|
||||||
smackw32.dll)
|
- Empty player
|
||||||
- For \*nix systems - using ffmpeg libraries.
|
|
||||||
- Empty player for 64-bit Windows
|
|
||||||
|
|
||||||
### [Primitive controls](Primitive_controls "wikilink")
|
### [Primitive controls](Primitive_controls "wikilink")
|
||||||
|
|
||||||
@@ -98,56 +75,30 @@ TBD
|
|||||||
|
|
||||||
## Main purposes of lib
|
## Main purposes of lib
|
||||||
|
|
||||||
VCMI_Lib is a library that contains code common to server and client, so
|
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.
|
||||||
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
|
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](https://github.com/vcmi/vcmi/blob/develop/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](#Wrapped_namespace_examples "wikilink").
|
||||||
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](https://github.com/vcmi/vcmi/blob/develop/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](#Wrapped_namespace_examples "wikilink").
|
|
||||||
|
|
||||||
[Lib](Lib "wikilink") contains code responsible for:
|
[Lib](Lib "wikilink") 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
|
- storing information common to server and client like state of the game
|
||||||
game
|
- managing armies, buildings, artifacts, spells, bonuses and other game objects
|
||||||
- managing armies, buildings, artifacts, spells, bonuses and other
|
- 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)
|
||||||
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
|
- networking and serialization
|
||||||
|
|
||||||
### [Serialization](Serialization "wikilink")
|
### [Serialization](Serialization "wikilink")
|
||||||
|
|
||||||
The serialization framework can serialize basic types, several standard
|
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](http://www.boost.org/doc/libs/1_52_0/libs/serialization/doc/index.html).
|
||||||
containers among smart pointers and custom objects. Its design is based
|
In addition to the basic functionality it provides light-weight transfer of CGObjectInstance objects by sending only the index/id.
|
||||||
on the [boost serialization
|
|
||||||
libraries](http://www.boost.org/doc/libs/1_52_0/libs/serialization/doc/index.html).
|
|
||||||
In addition to the basic functionality it provides light-weight transfer
|
|
||||||
of CGObjectInstance objects by sending only the index/id.
|
|
||||||
|
|
||||||
See the [Serialization](Serialization "wikilink") page for all the
|
See the [Serialization](Serialization "wikilink") page for all the details.
|
||||||
details.
|
|
||||||
|
|
||||||
### Wrapped namespace examples
|
### Wrapped namespace examples
|
||||||
|
|
||||||
#### Inside the lib
|
#### Inside the lib
|
||||||
|
|
||||||
Both header and implementation of a new class inside the lib should have
|
Both header and implementation of a new class inside the lib should have the following structure:
|
||||||
the following structure:
|
|
||||||
|
|
||||||
`<includes>`
|
`<includes>`
|
||||||
`VCMI_LIB_NAMESPACE_BEGIN`
|
`VCMI_LIB_NAMESPACE_BEGIN`
|
||||||
@@ -161,8 +112,7 @@ and
|
|||||||
|
|
||||||
#### Headers outside the lib
|
#### Headers outside the lib
|
||||||
|
|
||||||
Forward declarations of the lib in headers of other parts of the project
|
Forward declarations of the lib in headers of other parts of the project need to be wrapped in the macros:
|
||||||
need to be wrapped in the macros:
|
|
||||||
|
|
||||||
`<includes>`
|
`<includes>`
|
||||||
`VCMI_LIB_NAMESPACE_BEGIN`
|
`VCMI_LIB_NAMESPACE_BEGIN`
|
||||||
@@ -176,10 +126,7 @@ Example:
|
|||||||
|
|
||||||
#### New project part
|
#### New project part
|
||||||
|
|
||||||
If you're creating new project part, place `VCMI_LIB_USING_NAMESPACE` in
|
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>
|
||||||
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](Artificial_Intelligence "wikilink") (AI)
|
# [Artificial Intelligence](Artificial_Intelligence "wikilink") (AI)
|
||||||
|
|
||||||
@@ -189,18 +136,13 @@ Stupid AI is recent and used battle AI.
|
|||||||
|
|
||||||
## [Adventure AI](Adventure_AI "wikilink")
|
## [Adventure AI](Adventure_AI "wikilink")
|
||||||
|
|
||||||
VCAI module is currently developed agent-based system driven by goals
|
VCAI module is currently developed agent-based system driven by goals and heroes.
|
||||||
and heroes.
|
|
||||||
|
|
||||||
## [Programming challenge](Programming_challenge "wikilink")
|
## [Programming challenge](Programming_challenge "wikilink")
|
||||||
|
|
||||||
## [Fuzzy logic](Fuzzy_logic "wikilink")
|
## [Fuzzy logic](Fuzzy_logic "wikilink")
|
||||||
|
|
||||||
VCMI includes [FuzzyLite](http://code.google.com/p/fuzzy-lite/) library
|
VCMI includes [FuzzyLite](http://code.google.com/p/fuzzy-lite/) 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.
|
||||||
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](Utilities "wikilink")
|
# [Utilities](Utilities "wikilink")
|
||||||
|
|
||||||
|
@@ -1,31 +1,20 @@
|
|||||||
## C++ Standard
|
## C++ Standard
|
||||||
|
|
||||||
VCMI implementation bases on C++14 standard. Any feature is acceptable
|
VCMI implementation bases on C++17 standard. Any feature is acceptable as long as it's will pass build on our CI, but there is list below on what is already being used.
|
||||||
as long as it's will pass build on our CI, but there is list below on
|
|
||||||
what is already being used.
|
|
||||||
|
|
||||||
Any compiler supporting C++14 should work, but this has not been
|
Any compiler supporting C++17 should work, but this has not been thoroughly tested. You can find information about extensions and compiler support at [1](http://en.cppreference.com/w/cpp/compiler_support).
|
||||||
thoroughly tested. You can find information about extensions and
|
|
||||||
compiler support at
|
|
||||||
[1](http://en.cppreference.com/w/cpp/compiler_support).
|
|
||||||
|
|
||||||
## Style Guidelines
|
## Style Guidelines
|
||||||
|
|
||||||
In order to keep the code consistent, please use the following
|
In order to keep the code consistent, please use the following conventions. From here on 'good' and 'bad' are used to attribute things that would make the coding style match, or not match. It is not a judgment call on your coding abilities, but more of a style and look call. Please try to follow these guidelines to ensure prettiness.
|
||||||
conventions. From here on \`good' and \`bad' are used to attribute
|
|
||||||
things that would make the coding style match, or not match. It is not a
|
|
||||||
judgment call on your coding abilities, but more of a style and look
|
|
||||||
call. Please try to follow these guidelines to ensure prettiness.
|
|
||||||
|
|
||||||
### Indentation
|
### Indentation
|
||||||
|
|
||||||
Use tabs for indentation. If you are modifying someone else's code, try
|
Use tabs for indentation. If you are modifying someone else's code, try to keep the coding style similar.
|
||||||
to keep the coding style similar.
|
|
||||||
|
|
||||||
### Where to put braces
|
### Where to put braces
|
||||||
|
|
||||||
Inside a code block put the opening brace on the next line after the
|
Inside a code block put the opening brace on the next line after the current statement:
|
||||||
current statement:
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -46,8 +35,7 @@ if(a) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Avoid using unnecessary open/close braces, vertical space is usually
|
Avoid using unnecessary open/close braces, vertical space is usually limited:
|
||||||
limited:
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -64,8 +52,7 @@ if(a) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Unless there are either multiple hierarchical conditions being used or
|
Unless there are either multiple hierarchical conditions being used or that the condition cannot fit into a single line.
|
||||||
that the condition cannot fit into a single line.
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -109,8 +96,7 @@ if(a)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If "else" branch has brackets then "if" should also have brackets even
|
If "else" branch has brackets then "if" should also have brackets even if it is one line.
|
||||||
if it is one line.
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -142,8 +128,7 @@ else
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If you intentionally want to avoid usage of "else if" and keep if body
|
If you intentionally want to avoid usage of "else if" and keep if body indent make sure to use braces.
|
||||||
indent make sure to use braces.
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -188,8 +173,7 @@ void Method() {
|
|||||||
|
|
||||||
### Use whitespace for clarity
|
### Use whitespace for clarity
|
||||||
|
|
||||||
Use white space in expressions liberally, except in the presence of
|
Use white space in expressions liberally, except in the presence of parenthesis.
|
||||||
parenthesis.
|
|
||||||
|
|
||||||
**Good:**
|
**Good:**
|
||||||
|
|
||||||
@@ -205,14 +189,11 @@ if(a+5>method(blah('a')+4))
|
|||||||
foo+=24;
|
foo+=24;
|
||||||
```
|
```
|
||||||
|
|
||||||
Between if, for, while,.. and the opening brace there shouldn't be a
|
Between if, for, while,.. and the opening brace there shouldn't be a whitespace. The keywords are highlighted, so they don't need further separation.
|
||||||
whitespace. The keywords are highlighted, so they don't need further
|
|
||||||
separation.
|
|
||||||
|
|
||||||
### Where to put spaces
|
### Where to put spaces
|
||||||
|
|
||||||
Use a space before and after the address or pointer character in a
|
Use a space before and after the address or pointer character in a pointer declaration.
|
||||||
pointer declaration.
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -286,9 +267,7 @@ if((a && b) || (c + 1 == d))
|
|||||||
|
|
||||||
### Where to use parentheses
|
### Where to use parentheses
|
||||||
|
|
||||||
When allocating objects, don't use parentheses for creating stack-based
|
When allocating objects, don't use parentheses for creating stack-based objects by zero param c-tors to avoid c++ most vexing parse and use parentheses for creating heap-based objects.
|
||||||
objects by zero param c-tors to avoid c++ most vexing parse and use
|
|
||||||
parentheses for creating heap-based objects.
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -336,8 +315,7 @@ public:
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
When 'private:', 'public:' and other labels are not on the line after
|
When 'private:', 'public:' and other labels are not on the line after opening brackets there must be a new line before them.
|
||||||
opening brackets there must be a new line before them.
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -391,8 +369,7 @@ public:
|
|||||||
|
|
||||||
### Constructor base class and member initialization
|
### Constructor base class and member initialization
|
||||||
|
|
||||||
Constructor member and base class initialization must be on new line,
|
Constructor member and base class initialization must be on new line, indented with tab with leading colon.
|
||||||
indented with tab with leading colon.
|
|
||||||
|
|
||||||
``` cpp
|
``` cpp
|
||||||
CClass::CClass()
|
CClass::CClass()
|
||||||
@@ -501,8 +478,7 @@ auto lambda = []
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not use inline lambda expressions inside if-else, for and other
|
Do not use inline lambda expressions inside if-else, for and other conditions.
|
||||||
conditions.
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -529,8 +505,7 @@ if([]()
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Do not pass inline lambda expressions as parameter unless it's the last
|
Do not pass inline lambda expressions as parameter unless it's the last parameter.
|
||||||
parameter.
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -562,8 +537,7 @@ obj->someMethod(true, []()
|
|||||||
|
|
||||||
### Serialization
|
### Serialization
|
||||||
|
|
||||||
Serialization of each element must be on it's own line since this make
|
Serialization of each element must be on it's own line since this make debugging easier.
|
||||||
debugging easier.
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -586,8 +560,7 @@ template <typename Handler> void serialize(Handler & h, const int version)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Save backward compatibility code is exception when extra brackets are
|
Save backward compatibility code is exception when extra brackets are always useful.
|
||||||
always useful.
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -627,8 +600,7 @@ template <typename Handler> void serialize(Handler & h, const int version)
|
|||||||
|
|
||||||
### File headers
|
### File headers
|
||||||
|
|
||||||
For any new files, please paste the following info block at the very top
|
For any new files, please paste the following info block at the very top of the source file:
|
||||||
of the source file:
|
|
||||||
|
|
||||||
``` cpp
|
``` cpp
|
||||||
/*
|
/*
|
||||||
@@ -642,8 +614,7 @@ of the source file:
|
|||||||
*/
|
*/
|
||||||
```
|
```
|
||||||
|
|
||||||
The above notice have to be included both in header and source files
|
The above notice have to be included both in header and source files (.h/.cpp).
|
||||||
(.h/.cpp).
|
|
||||||
|
|
||||||
### Code order in files
|
### Code order in files
|
||||||
|
|
||||||
@@ -675,8 +646,7 @@ struct CPackForClient;
|
|||||||
|
|
||||||
### Where and how to comment
|
### Where and how to comment
|
||||||
|
|
||||||
If you comment on the same line with code there must be one single space
|
If you comment on the same line with code there must be one single space between code and slashes.
|
||||||
between code and slashes.
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -704,8 +674,7 @@ else // Do something.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If you add single-line comment on own line slashes must have same indent
|
If you add single-line comment on own line slashes must have same indent as code around:
|
||||||
as code around:
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -731,10 +700,7 @@ if(a)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Avoid comments inside multi-line if-else conditions. If your conditions
|
Avoid comments inside multi-line if-else conditions. If your conditions are too hard to understand without additional comments this usually means that code need refactoring. Example given below is need improvement though. **FIXME**
|
||||||
are too hard to understand without additional comments this usually
|
|
||||||
means that code need refactoring. Example given below is need
|
|
||||||
improvement though. **FIXME**
|
|
||||||
|
|
||||||
Good:
|
Good:
|
||||||
|
|
||||||
@@ -757,13 +723,7 @@ if((a && b || (c + 1 > 15)) //Check if hero still alive
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
You should write a comment before the class definition which describes
|
You should write a comment before the class definition which describes shortly the class. 1-2 sentences are enough. Methods and class data members should be commented if they aren't self-describing only. Getters/Setters, simple methods where the purpose is clear or similar methods shouldn't be commented, because vertical space is usually limited. The style of documentation comments should be the three slashes-style: ///.
|
||||||
shortly the class. 1-2 sentences are enough. Methods and class data
|
|
||||||
members should be commented if they aren't self-describing only.
|
|
||||||
Getters/Setters, simple methods where the purpose is clear or similar
|
|
||||||
methods shouldn't be commented, because vertical space is usually
|
|
||||||
limited. The style of documentation comments should be the three
|
|
||||||
slashes-style: ///.
|
|
||||||
|
|
||||||
``` cpp
|
``` cpp
|
||||||
/// Returns true if a debug/trace log message will be logged, false if not.
|
/// Returns true if a debug/trace log message will be logged, false if not.
|
||||||
@@ -772,12 +732,9 @@ bool isDebugEnabled() const;
|
|||||||
bool isTraceEnabled() const;
|
bool isTraceEnabled() const;
|
||||||
```
|
```
|
||||||
|
|
||||||
The above example doesn't follow a strict scheme on how to comment a
|
The above example doesn't follow a strict scheme on how to comment a method. It describes two methods in one go. Comments should be kept short.
|
||||||
method. It describes two methods in one go. Comments should be kept
|
|
||||||
short.
|
|
||||||
|
|
||||||
If you need a more detailed description for a method you can use such
|
If you need a more detailed description for a method you can use such style:
|
||||||
style:
|
|
||||||
|
|
||||||
``` cpp
|
``` cpp
|
||||||
/// <A short one line description>
|
/// <A short one line description>
|
||||||
@@ -795,80 +752,47 @@ A good essay about writing comments:
|
|||||||
|
|
||||||
### Casing
|
### Casing
|
||||||
|
|
||||||
Local variables and methods start with a lowercase letter and use the
|
Local variables and methods start with a lowercase letter and use the camel casing. Classes/Structs start with an uppercase letter and use the camel casing as well. Macros and constants are written uppercase.
|
||||||
camel casing. Classes/Structs start with an uppercase letter and use the
|
|
||||||
camel casing as well. Macros and constants are written uppercase.
|
|
||||||
|
|
||||||
### Line length
|
### Line length
|
||||||
|
|
||||||
The line length for c++ source code is 120 columns. If your function
|
The line length for c++ source code is 120 columns. If your function declaration arguments go beyond this point, please align your arguments to match the opening brace. For best results use the same number of tabs used on the first line followed by enough spaces to align the arguments.
|
||||||
declaration arguments go beyond this point, please align your arguments
|
|
||||||
to match the opening brace. For best results use the same number of tabs
|
|
||||||
used on the first line followed by enough spaces to align the arguments.
|
|
||||||
|
|
||||||
### Warnings
|
### Warnings
|
||||||
|
|
||||||
Avoid use of #pragma to disable warnings. Compile at warning level 3.
|
Avoid use of #pragma to disable warnings. Compile at warning level 3. Avoid commiting code with new warnings.
|
||||||
Avoid commiting code with new warnings.
|
|
||||||
|
|
||||||
### File/directory naming
|
### File/directory naming
|
||||||
|
|
||||||
Compilation units(.cpp,.h files) start with a uppercase letter and are
|
Compilation units(.cpp,.h files) start with a uppercase letter and are named like the name of a class which resides in that file if possible. Header only files start with a uppercase letter. JSON files start with a lowercase letter and use the camel casing.
|
||||||
named like the name of a class which resides in that file if possible.
|
|
||||||
Header only files start with a uppercase letter. JSON files start with a
|
|
||||||
lowercase letter and use the camel casing.
|
|
||||||
|
|
||||||
Directories start with a lowercase letter and use the camel casing where
|
Directories start with a lowercase letter and use the camel casing where necessary.
|
||||||
necessary.
|
|
||||||
|
|
||||||
### Logging
|
### Logging
|
||||||
|
|
||||||
Outdated. There is separate entry for [Logging
|
Outdated. There is separate entry for [Logging API](Logging_API "wikilink")
|
||||||
API](Logging_API "wikilink")
|
|
||||||
|
|
||||||
If you want to trace the control flow of VCMI, then you should use the
|
If you want to trace the control flow of VCMI, then you should use the macro LOG_TRACE or LOG_TRACE_PARAMS. The first one prints a message when the function is entered or leaved. The name of the function will also be logged. In addition to this the second macro, let's you specify parameters which you want to print. You should print traces with parameters like this:
|
||||||
macro LOG_TRACE or LOG_TRACE_PARAMS. The first one prints a message when
|
|
||||||
the function is entered or leaved. The name of the function will also be
|
|
||||||
logged. In addition to this the second macro, let's you specify
|
|
||||||
parameters which you want to print. You should print traces with
|
|
||||||
parameters like this:
|
|
||||||
|
|
||||||
``` cpp
|
``` cpp
|
||||||
LOG_TRACE_PARAMS(logGlobal, "hero '%s', spellId '%d', pos '%s'.", hero, spellId, pos);
|
LOG_TRACE_PARAMS(logGlobal, "hero '%s', spellId '%d', pos '%s'.", hero, spellId, pos);
|
||||||
```
|
```
|
||||||
|
|
||||||
When using the macro every "simple" parameter should be logged. The
|
When using the macro every "simple" parameter should be logged. The parameter can be a number, a string or a type with a ostream operator\<\<. You should not log contents of a whole text file, a byte array or sth. like this. If there is a simple type with a few members you want to log, you should write an ostream operator\<\<. The produced message can look like this:
|
||||||
parameter can be a number, a string or a type with a ostream
|
|
||||||
operator\<\<. You should not log contents of a whole text file, a byte
|
|
||||||
array or sth. like this. If there is a simple type with a few members
|
|
||||||
you want to log, you should write an ostream operator\<\<. The produced
|
|
||||||
message can look like this:
|
|
||||||
|
|
||||||
`{BattleAction: side '0', stackNumber '1', actionType 'Walk and attack', destinationTile '{BattleHex: x '7', y '1', hex '24'}', additionalInfo '7', selectedStack '-1'}`
|
`{BattleAction: side '0', stackNumber '1', actionType 'Walk and attack', destinationTile '{BattleHex: x '7', y '1', hex '24'}', additionalInfo '7', selectedStack '-1'}`
|
||||||
|
|
||||||
The name of the type should be logged first, e.g. {TYPE_NAME:
|
The name of the type should be logged first, e.g. {TYPE_NAME: members...}. The members of the object will be logged like logging trace parameters. Collection types (vector, list, ...) should be logged this way: \[{BattleHex: ...}, {...}\] There is no format which has to be followed strictly, so if there is a reason to format members/objects in a different way, then this is ok.
|
||||||
members...}. The members of the object will be logged like logging trace
|
|
||||||
parameters. Collection types (vector, list, ...) should be logged this
|
|
||||||
way: \[{BattleHex: ...}, {...}\] There is no format which has to be
|
|
||||||
followed strictly, so if there is a reason to format members/objects in
|
|
||||||
a different way, then this is ok.
|
|
||||||
|
|
||||||
## Best practices
|
## Best practices
|
||||||
|
|
||||||
### Avoid code duplication
|
### Avoid code duplication
|
||||||
|
|
||||||
Avoid code duplication or don't repeat yourself(DRY) is the most
|
Avoid code duplication or don't repeat yourself(DRY) is the most important aspect in programming. Code duplication of any kind can lead to inconsistency and is much harder to maintain. If one part of the system gets changed you have to change the code in several places. This process is error-prone and leads often to problems. Here you can read more about the DRY principle: [<http://en.wikipedia.org/wiki/Don%27t_repeat_yourself>](http://en.wikipedia.org/wiki/Don%27t_repeat_yourself)
|
||||||
important aspect in programming. Code duplication of any kind can lead
|
|
||||||
to inconsistency and is much harder to maintain. If one part of the
|
|
||||||
system gets changed you have to change the code in several places. This
|
|
||||||
process is error-prone and leads often to problems. Here you can read
|
|
||||||
more about the DRY principle:
|
|
||||||
[<http://en.wikipedia.org/wiki/Don%27t_repeat_yourself>](http://en.wikipedia.org/wiki/Don%27t_repeat_yourself)
|
|
||||||
|
|
||||||
### Do not use uncommon abbrevations
|
### Do not use uncommon abbrevations
|
||||||
|
|
||||||
Do not use uncommon abbrevations for class, method, parameter and global
|
Do not use uncommon abbrevations for class, method, parameter and global object names.
|
||||||
object names.
|
|
||||||
|
|
||||||
Bad:
|
Bad:
|
||||||
|
|
||||||
@@ -886,31 +810,21 @@ class CInterfaceObject
|
|||||||
|
|
||||||
### Loop handling
|
### Loop handling
|
||||||
|
|
||||||
Use range-based for loops. It should be used in any case except you
|
Use range-based for loops. It should be used in any case except you absolutely need iterator, then you may use a simple for loop.
|
||||||
absolutely need iterator, then you may use a simple for loop.
|
|
||||||
|
|
||||||
The loop counter should be of type int, unless you are sure you won't
|
The loop counter should be of type int, unless you are sure you won't need negative indices -- then use size_t.
|
||||||
need negative indices -- then use size_t.
|
|
||||||
|
|
||||||
### Include guards
|
### Include guards
|
||||||
|
|
||||||
Use #pragma once instead of the traditional #ifndef/#define/#endif
|
Use #pragma once instead of the traditional #ifndef/#define/#endif include guards.
|
||||||
include guards.
|
|
||||||
|
|
||||||
### Pre compiled header file
|
### Pre compiled header file
|
||||||
|
|
||||||
The header StdInc.h should be included in every compilation unit. It has
|
The header StdInc.h should be included in every compilation unit. It has to be included before any C macro and before any c++ statements. Pre compiled header should not be changed, except any important thing is missing. The StdInc includes most Boost libraries and nearly all standard STL and C libraries, so you don’t have to include them by yourself.
|
||||||
to be included before any C macro and before any c++ statements. Pre
|
|
||||||
compiled header should not be changed, except any important thing is
|
|
||||||
missing. The StdInc includes most Boost libraries and nearly all
|
|
||||||
standard STL and C libraries, so you don’t have to include them by
|
|
||||||
yourself.
|
|
||||||
|
|
||||||
### Enumeration handling
|
### Enumeration handling
|
||||||
|
|
||||||
Do not declare enumerations in global namespace. It is better to use
|
Do not declare enumerations in global namespace. It is better to use strongly typed enum or to wrap them in class or namespace to avoid polluting global namespace:
|
||||||
strongly typed enum or to wrap them in class or namespace to avoid
|
|
||||||
polluting global namespace:
|
|
||||||
|
|
||||||
``` cpp
|
``` cpp
|
||||||
enum class EAlignment
|
enum class EAlignment
|
||||||
@@ -931,8 +845,7 @@ namespace EAlignment
|
|||||||
|
|
||||||
### Avoid senseless comments
|
### Avoid senseless comments
|
||||||
|
|
||||||
If the comment duplicates the name of commented member, it's better if
|
If the comment duplicates the name of commented member, it's better if it wouldn't exist at all. It just increases maintenance cost. Bad:
|
||||||
it wouldn't exist at all. It just increases maintenance cost. Bad:
|
|
||||||
|
|
||||||
``` cpp
|
``` cpp
|
||||||
size_t getHeroesCount(); //gets count of heroes (surprise?)
|
size_t getHeroesCount(); //gets count of heroes (surprise?)
|
||||||
@@ -940,19 +853,11 @@ size_t getHeroesCount(); //gets count of heroes (surprise?)
|
|||||||
|
|
||||||
### Class handling
|
### Class handling
|
||||||
|
|
||||||
There is no definitive rule which has to be followed strictly. You can
|
There is no definitive rule which has to be followed strictly. You can freely decide if you want to pack your own classes, where you are programming on, all in one file or each in one file. It's more important that you feel comfortable with the code, than consistency overall the project. VCMI has several container class files, so if you got one additional class to them than just add it to them instead of adding new files.
|
||||||
freely decide if you want to pack your own classes, where you are
|
|
||||||
programming on, all in one file or each in one file. It's more important
|
|
||||||
that you feel comfortable with the code, than consistency overall the
|
|
||||||
project. VCMI has several container class files, so if you got one
|
|
||||||
additional class to them than just add it to them instead of adding new
|
|
||||||
files.
|
|
||||||
|
|
||||||
### Functions and interfaces
|
### Functions and interfaces
|
||||||
|
|
||||||
Don't return const objects or primitive types from functions -- it's
|
Don't return const objects or primitive types from functions -- it's pointless. Also, don't return pointers to non-const game data objects from callbacks to player interfaces.
|
||||||
pointless. Also, don't return pointers to non-const game data objects
|
|
||||||
from callbacks to player interfaces.
|
|
||||||
|
|
||||||
Bad:
|
Bad:
|
||||||
|
|
||||||
@@ -968,5 +873,4 @@ std::vector<const CGObjectInstance *> guardingCreatures(int3 pos) const;
|
|||||||
|
|
||||||
## Sources
|
## Sources
|
||||||
|
|
||||||
[Mono project coding
|
[Mono project coding guidelines](http://www.mono-project.com/Coding_Guidelines)
|
||||||
guidelines](http://www.mono-project.com/Coding_Guidelines)
|
|
@@ -1,49 +1,24 @@
|
|||||||
# Introduction to Qt Creator
|
# Introduction to Qt Creator
|
||||||
|
|
||||||
Qt Creator is the recommended IDE for VCMI development on Linux
|
Qt Creator is the recommended IDE for VCMI development on Linux distributions, but it may be used on other operating systems as well. It has the following advantages compared to other IDEs:
|
||||||
distributions, but it may be used on other operating systems as well. It
|
|
||||||
has the following advantages compared to other IDEs:
|
|
||||||
|
|
||||||
- Fast parser/indexer, stable.
|
- Fast parser/indexer, stable.
|
||||||
- Almost no manual configuration when used with CMake. Project
|
- Almost no manual configuration when used with CMake. Project configuration is read from CMake text files,
|
||||||
configuration is read from CMake text files,
|
- Easy to setup and use with multiple different compiler toolchains: GCC, Visual Studio, Clang
|
||||||
- Easy to setup and use with multiple different compiler toolchains:
|
|
||||||
GCC, Visual Studio, Clang
|
|
||||||
|
|
||||||
You can install Qt Creator from repository, but better to stick to
|
You can install Qt Creator from repository, but better to stick to latest version from Qt website: https://www.qt.io/download-open-source/
|
||||||
latest version from Qt website:
|
|
||||||
<https://www.qt.io/download-open-source/>
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
To open the project you have to click File -\> Open file or project...
|
To open the project you have to click File -\> Open file or project... -\> Select /path/to/vcmi/src/CMakeLists.txt.
|
||||||
-\> Select /path/to/vcmi/src/CMakeLists.txt.
|
|
||||||
|
|
||||||
For the first time and for every CMake project configuration change you
|
For the first time and for every CMake project configuration change you have to execute CMake. This step can be done when opening the project for the first time or alternatively via the left bar -\> Projects -\> Build Settings -\> Execute CMake. You have to specify CMake arguments and the build dir. CMake arguments can be the following: `-DCMAKE_BUILD_TYPE=Debug`
|
||||||
have to execute CMake. This step can be done when opening the project
|
|
||||||
for the first time or alternatively via the left bar -\> Projects -\>
|
|
||||||
Build Settings -\> Execute CMake. You have to specify CMake arguments
|
|
||||||
and the build dir. CMake arguments can be the following:
|
|
||||||
|
|
||||||
-DCMAKE_BUILD_TYPE=Debug
|
The build dir should be set to something like /trunk/build for the debug build and /trunk/buildrel for the release build. For cleaning the build dir a command like "make clean" may be not enough. Better way is to delete the build dir, re-create it and re-execute CMake. Steps for cleaning can be configured in the Projects tab as well.
|
||||||
|
|
||||||
The build dir should be set to something like /trunk/build for the debug
|
|
||||||
build and /trunk/buildrel for the release build. For cleaning the build
|
|
||||||
dir a command like "make clean" may be not enough. Better way is to
|
|
||||||
delete the build dir, re-create it and re-execute CMake. Steps for
|
|
||||||
cleaning can be configured in the Projects tab as well.
|
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
|
|
||||||
There is a problem with QtCreator when debugging both vcmiclient and
|
There is a problem with QtCreator when debugging both vcmiclient and vcmiserver. If you debug the vcmiclient, start a game, attach the vcmiserver process to the gdb debugger(Debug \> Start Debugging \> Attach to Running External Application...) then breakpoints which are set for vcmiserver will be ignored. This looks like a bug, in any case it's not intuitively. Two workarounds are available luckily:
|
||||||
vcmiserver. If you debug the vcmiclient, start a game, attach the
|
|
||||||
vcmiserver process to the gdb debugger(Debug \> Start Debugging \>
|
|
||||||
Attach to Running External Application...) then breakpoints which are
|
|
||||||
set for vcmiserver will be ignored. This looks like a bug, in any case
|
|
||||||
it's not intuitively. Two workarounds are available luckily:
|
|
||||||
|
|
||||||
1\) Run vcmiclient (no debug mode), then attach server process to the
|
1. Run vcmiclient (no debug mode), then attach server process to the debugger
|
||||||
debugger
|
2. Open two instances of QtCreator and debug vcmiserver and vcmiclient separately(it works!)
|
||||||
|
|
||||||
2\) Open two instances of QtCreator and debug vcmiserver and vcmiclient
|
|
||||||
separately(it works!)
|
|
@@ -1,117 +0,0 @@
|
|||||||
The following instructions apply to **v1.2 and later**. For earlier
|
|
||||||
versions the best documentation is
|
|
||||||
<https://github.com/vcmi/vcmi-android/blob/master/building.txt> (and
|
|
||||||
reading scripts in that repo), however very limited to no support will
|
|
||||||
be provided from our side if you wish to go down that rabbit hole.
|
|
||||||
|
|
||||||
*Note*: building has been tested only on Linux and macOS. It may or may
|
|
||||||
not work on Windows out of the box.
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
1. CMake 3.20+: download from your package manager or from
|
|
||||||
<https://cmake.org/download/>
|
|
||||||
2. JDK 11, not necessarily from Oracle
|
|
||||||
3. Android command line tools or Android Studio for your OS:
|
|
||||||
<https://developer.android.com/studio/>
|
|
||||||
4. Android NDK version **r25c (25.2.9519653)**, there're multiple ways
|
|
||||||
to obtain it:
|
|
||||||
- install with Android Studio
|
|
||||||
- install with `sdkmanager` command line tool
|
|
||||||
- download from <https://developer.android.com/ndk/downloads>
|
|
||||||
- download with Conan, see [#NDK and
|
|
||||||
Conan](#NDK_and_Conan "wikilink")
|
|
||||||
5. (optional) Ninja: download from your package manager or from
|
|
||||||
<https://github.com/ninja-build/ninja/releases>
|
|
||||||
|
|
||||||
## Obtaining source code
|
|
||||||
|
|
||||||
Clone <https://github.com/vcmi/vcmi> with submodules. Example for
|
|
||||||
command line:
|
|
||||||
|
|
||||||
`git clone --recurse-submodules https://github.com/vcmi/vcmi.git`
|
|
||||||
|
|
||||||
## Obtaining dependencies
|
|
||||||
|
|
||||||
We use Conan package manager to build/consume dependencies, find
|
|
||||||
detailed usage instructions
|
|
||||||
[here](https://github.com/vcmi/vcmi/tree/develop/docs/conan.md). Note
|
|
||||||
that the link points to the cutting-edge state in `develop` branch, for
|
|
||||||
the latest release check the same document in the [master
|
|
||||||
branch](https://github.com/vcmi/vcmi/tree/master/docs/conan.md).
|
|
||||||
|
|
||||||
On the step where you need to replace **PROFILE**, choose:
|
|
||||||
|
|
||||||
- `android-32` to build for 32-bit architecture (armeabi-v7a)
|
|
||||||
- `android-64` to build for 64-bit architecture (aarch64-v8a)
|
|
||||||
|
|
||||||
### NDK and Conan
|
|
||||||
|
|
||||||
Conan must be aware of the NDK location when you execute
|
|
||||||
`conan install`. There're multiple ways to achieve that as written in
|
|
||||||
the [Conan
|
|
||||||
docs](https://docs.conan.io/1/integrations/cross_platform/android.html):
|
|
||||||
|
|
||||||
- the easiest is to download NDK from Conan (option 1 in the docs),
|
|
||||||
then all the magic happens automatically. You need to create your
|
|
||||||
own Conan profile that imports our Android profile and adds 2 new
|
|
||||||
lines (you can of course just copy everything from our profile into
|
|
||||||
yours without including) and then pass this new profile to
|
|
||||||
`conan install`:
|
|
||||||
|
|
||||||
`include(/path/to/vcmi/CI/conan/android-64)`
|
|
||||||
`[tool_requires]`
|
|
||||||
`android-ndk/r25c`
|
|
||||||
|
|
||||||
- to use an already installed NDK, you can simply pass it on the
|
|
||||||
command line to `conan install`:
|
|
||||||
|
|
||||||
`conan install -c tools.android:ndk_path=/path/to/ndk ...`
|
|
||||||
|
|
||||||
## Build process
|
|
||||||
|
|
||||||
Building for Android is a 2-step process. First, native C++ code is
|
|
||||||
compiled to a shared library (unlike executable on other platforms),
|
|
||||||
then Java code is compiled to an actual executable which will be loading
|
|
||||||
the native shared library at runtime.
|
|
||||||
|
|
||||||
### C++ code
|
|
||||||
|
|
||||||
This is a traditional CMake project, you can build it from command line
|
|
||||||
or some IDE. You're not required to pass any custom options (except
|
|
||||||
Conan toolchain file), defaults are already good. If you wish to use
|
|
||||||
your own CMake presets, inherit them from our `build-with-conan` preset.
|
|
||||||
Example:
|
|
||||||
|
|
||||||
`cmake -S . -B ../build -G Ninja -D CMAKE_BUILD_TYPE=Debug --toolchain ...`
|
|
||||||
`cmake --build ../build`
|
|
||||||
|
|
||||||
You can also see a more detailed walkthrough on CMake configuration at
|
|
||||||
[How to build VCMI (macOS)#Configuring project for
|
|
||||||
building](How_to_build_VCMI_(macOS)#Configuring_project_for_building "wikilink").
|
|
||||||
|
|
||||||
### Java code
|
|
||||||
|
|
||||||
After the C++ part is built, native shared libraries are copied to the
|
|
||||||
appropriate location of the Java project (they will be packaged in the
|
|
||||||
APK). You can either open the Java project located in `android`
|
|
||||||
directory of the repo in Android studio and work with it as with any
|
|
||||||
Android project or build from command line.
|
|
||||||
|
|
||||||
Example how to build from command line in Bash shell, assumes that
|
|
||||||
current working directory is VCMI repository:
|
|
||||||
|
|
||||||
`# the following environment variables must be set`
|
|
||||||
`export JAVA_HOME=/path/to/jdk11`
|
|
||||||
`export ANDROID_HOME=/path/to/android/sdk`
|
|
||||||
``
|
|
||||||
`cd android`
|
|
||||||
`./gradlew assembleDebug`
|
|
||||||
|
|
||||||
APK will appear in `android/vcmi-app/build/outputs/apk/debug` directory
|
|
||||||
which you can then install to your device with
|
|
||||||
`adb install -r /path/to/apk` (adb command is from Android command line
|
|
||||||
tools).
|
|
||||||
|
|
||||||
If you wish to build and install to your device in single action, use
|
|
||||||
`installDebug` instead of `assembleDebug`.
|
|
@@ -1,217 +0,0 @@
|
|||||||
# Compiling VCMI
|
|
||||||
|
|
||||||
- Current baseline requirement for building is Ubuntu 20.04
|
|
||||||
- Supported C++ compilers for UNIX-like systems are GCC 5.5+ and Clang
|
|
||||||
13+
|
|
||||||
|
|
||||||
Older distributions and compilers might work, but they aren't tested by
|
|
||||||
[Travis CI](https://travis-ci.org/vcmi/vcmi/)
|
|
||||||
|
|
||||||
# Installing dependencies
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
To compile, the following packages (and their development counterparts)
|
|
||||||
are needed to build:
|
|
||||||
|
|
||||||
- CMake 3.10 or newer
|
|
||||||
- SDL2 with devel packages: mixer, image, ttf
|
|
||||||
- zlib and zlib-devel
|
|
||||||
- Recommended, if you want to build launcher or map editor: Qt 5,
|
|
||||||
widget and network modules
|
|
||||||
- Recommended, FFmpeg libraries, if you want to watch in-game videos:
|
|
||||||
libavformat and libswscale. Their name could be libavformat-devel
|
|
||||||
and libswscale-devel, or ffmpeg-libs-devel or similar names.
|
|
||||||
- Boost C++ libraries v1.48+: program-options, filesystem, system,
|
|
||||||
thread, locale
|
|
||||||
- Optional, if you want to build scripting modules: LuaJIT
|
|
||||||
|
|
||||||
## On Debian-based systems (e.g. Ubuntu)
|
|
||||||
|
|
||||||
For Ubuntu 22.04 (jammy) or newer you need to install this list of
|
|
||||||
packages, including **libtbb2-dev**:
|
|
||||||
|
|
||||||
sudo apt-get install cmake g++ libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-mixer-dev zlib1g-dev libavformat-dev libswscale-dev libboost-dev libboost-filesystem-dev libboost-system-dev libboost-thread-dev libboost-program-options-dev libboost-locale-dev qtbase5-dev libtbb2-dev libluajit-5.1-dev qttools5-dev
|
|
||||||
|
|
||||||
For Ubuntu 21.10 (impish) or older and all versions of Debian (9
|
|
||||||
stretch - 11 bullseye) you need to install this list of packages,
|
|
||||||
including **libtbb-dev**:
|
|
||||||
|
|
||||||
sudo apt-get install cmake g++ libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-mixer-dev zlib1g-dev libavformat-dev libswscale-dev libboost-dev libboost-filesystem-dev libboost-system-dev libboost-thread-dev libboost-program-options-dev libboost-locale-dev qtbase5-dev libtbb-dev libluajit-5.1-dev qttools5-dev
|
|
||||||
|
|
||||||
Alternatively if you have VCMI installed from repository or PPA you can
|
|
||||||
use:
|
|
||||||
|
|
||||||
sudo apt-get build-dep vcmi
|
|
||||||
|
|
||||||
## On RPM-based distributions (e.g. Fedora)
|
|
||||||
|
|
||||||
sudo yum install cmake gcc-c++ SDL2-devel SDL2_image-devel SDL2_ttf-devel SDL2_mixer-devel boost boost-devel boost-filesystem boost-system boost-thread boost-program-options boost-locale zlib-devel ffmpeg-devel ffmpeg-libs qt5-qtbase-devel tbb-devel luajit-devel fuzzylite-devel
|
|
||||||
|
|
||||||
## On Arch-based distributions
|
|
||||||
|
|
||||||
On Arch-based distributions, there is a development package available
|
|
||||||
for VCMI on the AUR.
|
|
||||||
|
|
||||||
It can be found at: <https://aur.archlinux.org/packages/vcmi-git/>
|
|
||||||
|
|
||||||
Information about building packages from the Arch User Repository (AUR)
|
|
||||||
can be found at the Arch wiki.
|
|
||||||
|
|
||||||
## Manual Installation
|
|
||||||
|
|
||||||
For older OS versions the latest prerequisite packages may not be
|
|
||||||
readily available via the system installer. Some brief instructions for
|
|
||||||
manual install are given below (tested on Ubuntu 14.04, update version
|
|
||||||
numbers as desired).
|
|
||||||
|
|
||||||
- CMake (see also
|
|
||||||
<https://askubuntu.com/questions/355565/how-do-i-install-the-latest-version-of-cmake-from-the-command-line/865294>)
|
|
||||||
|
|
||||||
<!-- -->
|
|
||||||
|
|
||||||
wget https://cmake.org/files/v3.11/cmake-3.11.0.tar.gz
|
|
||||||
tar xfz cmake-3.11.0.tar.gz
|
|
||||||
cd cmake-3.11.0
|
|
||||||
./bootstrap
|
|
||||||
make -j2
|
|
||||||
sudo checkinstall --pkgname cmake --pkgversion 3.11.0 -y
|
|
||||||
|
|
||||||
Note: Will only be visible in new terminals. Test with cmake --version.
|
|
||||||
|
|
||||||
- Boost (see also <https://ubuntuforums.org/showthread.php?t=1180792>)
|
|
||||||
|
|
||||||
<!-- -->
|
|
||||||
|
|
||||||
wget https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz
|
|
||||||
tar xfz boost_1_66_0.tar.gz
|
|
||||||
cd boost_1_66_0
|
|
||||||
./bootstrap.sh --with-libraries=program-options,filesystem,system,thread,locale
|
|
||||||
./b2
|
|
||||||
sudo ./b2 install
|
|
||||||
|
|
||||||
Note: Boost 1.66.0 produces a bug in asio.hpp when used with old gcc
|
|
||||||
versions (see <https://svn.boost.org/trac10/ticket/13368>).
|
|
||||||
|
|
||||||
- GCC (for Ubuntu - compile from source is lengthy)
|
|
||||||
|
|
||||||
<!-- -->
|
|
||||||
|
|
||||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install gcc-7 g++-7
|
|
||||||
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70 --slave /usr/bin/g++ g++ /usr/bin/g++-7
|
|
||||||
|
|
||||||
Note: Test with gcc --version (and g++ --version).
|
|
||||||
|
|
||||||
- Clang (for Ubuntu 14.04 - for later versions first line is not
|
|
||||||
needed, and 'trusty' should be replaced with version name)
|
|
||||||
|
|
||||||
<!-- -->
|
|
||||||
|
|
||||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
|
|
||||||
sudo add-apt-repository "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-6.0 main"
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install clang-6.0
|
|
||||||
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-6.0 60 --slave /usr/bin/clang++ clang++ /usr/bin/clang++-6.0
|
|
||||||
|
|
||||||
Note: Test with clang --version (and clang++ --version).
|
|
||||||
|
|
||||||
# Getting the sources
|
|
||||||
|
|
||||||
VCMI is still in development. We recommend the following initial
|
|
||||||
directory structure:
|
|
||||||
|
|
||||||
.
|
|
||||||
├── vcmi -> contains sources and is under git control
|
|
||||||
└── build -> contains build output, makefiles, object files,...
|
|
||||||
|
|
||||||
You can get latest sources with:
|
|
||||||
|
|
||||||
git clone -b develop --recursive https://github.com/vcmi/vcmi.git
|
|
||||||
|
|
||||||
# Compilation
|
|
||||||
|
|
||||||
## Configuring Makefiles
|
|
||||||
|
|
||||||
mkdir build && cd build
|
|
||||||
cmake ../vcmi
|
|
||||||
|
|
||||||
# Additional options that you may want to use:
|
|
||||||
## To enable debugging:
|
|
||||||
cmake ../vcmi -DCMAKE_BUILD_TYPE=Debug
|
|
||||||
|
|
||||||
**Notice**: The ../vcmi/ is not a typo, it will place makefile scripts
|
|
||||||
into the build dir as the build dir is your working dir when calling
|
|
||||||
CMake.
|
|
||||||
|
|
||||||
## Trigger build
|
|
||||||
|
|
||||||
cmake --build . -- -j2
|
|
||||||
# -j2 = compile with 2 threads, you can specify any value
|
|
||||||
|
|
||||||
That will generate vcmiclient, vcmiserver, vcmilauncher as well as 4 .so
|
|
||||||
libraries in **build/bin/** directory.
|
|
||||||
|
|
||||||
# Package building
|
|
||||||
|
|
||||||
## RPM package
|
|
||||||
|
|
||||||
The first step is to prepare a RPM build environment. On Fedora systems
|
|
||||||
you can follow this guide:
|
|
||||||
<http://fedoraproject.org/wiki/How_to_create_an_RPM_package#SPEC_file_overview>
|
|
||||||
|
|
||||||
1\. Download the file rpm/vcmi.spec from any tagged VCMI release for
|
|
||||||
which you wish to build a RPM package via the SVN Browser trac at this
|
|
||||||
URL for example(which is for VCMI 0.9):
|
|
||||||
<http://sourceforge.net/apps/trac/vcmi/browser/tags/0.9/rpm/vcmi.spec>
|
|
||||||
|
|
||||||
2\. Copy the file to ~/rpmbuild/SPECS
|
|
||||||
|
|
||||||
3\. Follow instructions in the vcmi.spec. You have to export the
|
|
||||||
corresponding SVN tag, compress it to a g-zipped archive and copy it to
|
|
||||||
~/rpmbuild/SOURCES. Instructions are written as comments and you can
|
|
||||||
copy/paste commands into terminal.
|
|
||||||
|
|
||||||
4\. Go to ~/rpmbuild/SPECS and open terminal in this folder and type:
|
|
||||||
|
|
||||||
rpmbuild -ba vcmi.spec (this will build rpm and source rpm)
|
|
||||||
|
|
||||||
5\. Generated RPM is in folder ~/rpmbuild/RPMS
|
|
||||||
|
|
||||||
If you want to package the generated RPM above for different processor
|
|
||||||
architectures and operating systems you can use the tool mock. Moreover,
|
|
||||||
it is necessary to install mock-rpmfusion_free due to the packages
|
|
||||||
ffmpeg-devel and ffmpeg-libs which aren't available in the standard RPM
|
|
||||||
repositories(at least for Fedora). Go to ~/rpmbuild/SRPMS in terminal
|
|
||||||
and type:
|
|
||||||
|
|
||||||
mock -r fedora-17-i386-rpmfusion_free path_to_source_RPM
|
|
||||||
mock -r fedora-17-x86_64-rpmfusion_free path_to_source_RPM
|
|
||||||
|
|
||||||
Available root environments and their names are listed in /etc/mock.
|
|
||||||
|
|
||||||
## Debian/Ubuntu
|
|
||||||
|
|
||||||
1\. Install debhelper and devscripts packages
|
|
||||||
|
|
||||||
2\. Run dpkg-buildpackage command from vcmi source directory
|
|
||||||
|
|
||||||
sudo apt-get install debhelper devscripts
|
|
||||||
cd /path/to/source
|
|
||||||
dpkg-buildpackage
|
|
||||||
|
|
||||||
To generate packages for different architectures see "-a" flag of
|
|
||||||
dpkg-buildpackage command
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
To compile using Doxygen, the UseDoxygen CMake module must be installed.
|
|
||||||
It can be fetched from: <http://tobias.rautenkranz.ch/cmake/doxygen/>
|
|
||||||
|
|
||||||
Once UseDoxygen is installed, run:
|
|
||||||
|
|
||||||
cmake .
|
|
||||||
make doc
|
|
||||||
|
|
||||||
The built documentation will be available from ./doc
|
|
@@ -1,165 +0,0 @@
|
|||||||
**Warning!** VCMI project only officially support building with CMake:
|
|
||||||
[How to build VCMI
|
|
||||||
(Windows/Vcpkg)](How_to_build_VCMI_(Windows/Vcpkg) "wikilink").
|
|
||||||
|
|
||||||
Guide below and VS solution found in source tree might be broken and not
|
|
||||||
automatically tested. Use at your own risk only if you know what you're
|
|
||||||
doing.
|
|
||||||
|
|
||||||
# Prerequisites
|
|
||||||
|
|
||||||
- Installed Heroes3 (can be bought for $10 at
|
|
||||||
[gog.com](http://www.gog.com/en/gamecard/heroes_of_might_and_magic_3_complete_edition/))
|
|
||||||
- Optionally, you can have also WoG or ERA installed.
|
|
||||||
- IDE:
|
|
||||||
- Microsoft Visual Studio 2015 (Community Edition recommended - it
|
|
||||||
is free for non-commercial use). Earlier version support is
|
|
||||||
deprecated and project may not compile anymore with them.
|
|
||||||
- Git client:
|
|
||||||
- Visual Studio 2015 has built-in Git support. It isn't complete,
|
|
||||||
but having most important Git commands integrated in IDE is very
|
|
||||||
convienent. Additional GitHub extension for Visual Studio
|
|
||||||
[1](https://visualstudio.github.com/) gives few more features
|
|
||||||
that may be useful.
|
|
||||||
- Alternatively, you can use another Git client with better Git
|
|
||||||
support, for example Sourcetree
|
|
||||||
[2](https://www.sourcetreeapp.com/)
|
|
||||||
- Libraries used by VCMI - where to get them will be explained later
|
|
||||||
in this tutorial
|
|
||||||
- Boost
|
|
||||||
- SDL2
|
|
||||||
- SDL2_image
|
|
||||||
- SDL2_mixer
|
|
||||||
- SDL2_TTF
|
|
||||||
- FFmpeg
|
|
||||||
- zlib
|
|
||||||
- QT 5 (only used to compile VCMI launcher, which does not have to
|
|
||||||
be rebuilt to test another VCMI parts)
|
|
||||||
|
|
||||||
# Preparing place
|
|
||||||
|
|
||||||
## Initial directory structure
|
|
||||||
|
|
||||||
Create a directory for VCMI development, eg. C:\VCMI. It will be base
|
|
||||||
directory for VCMI source code.
|
|
||||||
|
|
||||||
It is recommended to avoid non-ascii characters in the path to your VCMI
|
|
||||||
development folder. The folder should not be write-protected by system.
|
|
||||||
Good location:
|
|
||||||
|
|
||||||
- C:\VCMI
|
|
||||||
|
|
||||||
Bad locations:
|
|
||||||
|
|
||||||
- C:\Users\Michał\VCMI (non-ascii character)
|
|
||||||
- C:\Program Files (x86)\VCMI (write protection)
|
|
||||||
|
|
||||||
## Obtaining VCMI sources
|
|
||||||
|
|
||||||
### Using Sourcetree (version 1.9.6.1)
|
|
||||||
|
|
||||||
- Click "Clone / New" button in upper left part of the program
|
|
||||||
- Make sure you are in first tab (Clone Repository). In "Source Path /
|
|
||||||
URL:" type following link: <https://github.com/vcmi/vcmi.git>
|
|
||||||
- Set "Destination Path" field to directory desired for VCMI
|
|
||||||
development and press "Clone" button.
|
|
||||||
|
|
||||||
Now you have the local copy of the repository on the disk. It should
|
|
||||||
appear in the Team Explorer under the "Local Git Repositories" section.
|
|
||||||
Double click it and then select a solution to open.
|
|
||||||
|
|
||||||
# Getting Libraries
|
|
||||||
|
|
||||||
This section will show ways to get up-to-date versions of libraries
|
|
||||||
required to build VCMI. When you have a choice if you want 32 or 64 bit
|
|
||||||
version of library - choosing 32 bit will make things easier as you will
|
|
||||||
not have to do additional configuration in Visual Studio to switch to 64
|
|
||||||
bit etc.
|
|
||||||
|
|
||||||
## Boost
|
|
||||||
|
|
||||||
- Header files with extra things can be obtained from boost website
|
|
||||||
download: [3](http://www.boost.org/users/download/)
|
|
||||||
- To avoid rebuilding boost from sources, you can download prebuilt
|
|
||||||
windows binaries (lib files) from there as well. MSVC 14 binaries
|
|
||||||
are for Visual Studio 2015.
|
|
||||||
|
|
||||||
UPDATE: Somebody reported problem with boost newer than 1.62 when trying
|
|
||||||
to build VCMI. To get all boost 1.62 required files use these links:
|
|
||||||
[4](https://sourceforge.net/projects/boost/files/boost/1.62.0/boost_1_62_0.7z/download)
|
|
||||||
[5](https://sourceforge.net/projects/boost/files/boost-binaries/1.62.0/boost_1_62_0-msvc-14.0-32.exe/download)
|
|
||||||
|
|
||||||
## SDL2 and sublibraries
|
|
||||||
|
|
||||||
- You can get SDL2 from [6](http://libsdl.org/download-2.0.php) -
|
|
||||||
download development libraries to get lib and header files
|
|
||||||
- Similar to SDL2 package you can get SDL2_image from
|
|
||||||
[7](https://www.libsdl.org/projects/SDL_image/), SDL2_mixer from
|
|
||||||
[8](https://www.libsdl.org/projects/SDL_mixer/), SDL2_ttf from
|
|
||||||
[9](https://www.libsdl.org/projects/SDL_ttf/).
|
|
||||||
|
|
||||||
## FFmpeg
|
|
||||||
|
|
||||||
- You can get this library from
|
|
||||||
[10](https://ffmpeg.zeranoe.com/builds/). Both header and lib files
|
|
||||||
are available if you choose "dev" download version.
|
|
||||||
|
|
||||||
## zlib
|
|
||||||
|
|
||||||
- most tricky to get - use NuGet package manager that is part of
|
|
||||||
Visual Studio 2015 to get it. Link in NuGet gallery:
|
|
||||||
[11](https://www.nuget.org/packages/zlib/)
|
|
||||||
|
|
||||||
## QT 5
|
|
||||||
|
|
||||||
- (TO BE ADDED)
|
|
||||||
|
|
||||||
# Compiling VCMI
|
|
||||||
|
|
||||||
To compile VCMI you need to be able to compile some of projects that
|
|
||||||
VCMI solution provides, more information about them is in next part of
|
|
||||||
this tutorial. Default build configuration for VCMI solution is RD, what
|
|
||||||
means "release with debug information".
|
|
||||||
|
|
||||||
You need to resolve header and library directories to point to all
|
|
||||||
required libraries in project settings to properly build VCMI. This is
|
|
||||||
out of scope of this tutorial.
|
|
||||||
|
|
||||||
# VCMI solution details
|
|
||||||
|
|
||||||
VCMI solution consists of few separate projects that get compiled to
|
|
||||||
separate output. Many of them rely on VCMI_lib, so making changes to
|
|
||||||
VCMI_lib requires recompiling another projects. Some of the projects are
|
|
||||||
dead or not updated for very long time, for example Editor or ERM.
|
|
||||||
FuzzyLite and minizip are utility projects and are not meant to be
|
|
||||||
currently changed. Projects in development and their purpose are:
|
|
||||||
|
|
||||||
- BattleAI - as name says this project is for artificial intelligence
|
|
||||||
during battles. Gets compiled to DLL module.
|
|
||||||
- VCAI - adventure map artificial intelligence. Gets compiled to DLL
|
|
||||||
module.
|
|
||||||
- VCMI_client - game client, "game display" and user interface related
|
|
||||||
code is here. One of two main game game executables
|
|
||||||
- VCMI_launcher - game launcher with ability to change some available
|
|
||||||
game options, disable / enable VCMI mods etc.
|
|
||||||
- VCMI_lib - contains shared code for client and server. Large part of
|
|
||||||
game mechanics can be found here. Compilable to DLL module.
|
|
||||||
- VCMI_server - game server. Server starts everytime a scenario is
|
|
||||||
launched, and performs network-based communication with game client.
|
|
||||||
Some parts of game mechanics can be found here. One of two main game
|
|
||||||
executables.
|
|
||||||
|
|
||||||
Projects mentioned above need to be compiled "together" to work because
|
|
||||||
of VCMI_lib dependency - for example compiling VCMI_lib and VCMI_client
|
|
||||||
requires recompiling server, AI projects etc. because their equivalents
|
|
||||||
from other sources such as VCMI windows package will not work with new
|
|
||||||
VCMI_lib and raise "cannot find entry point..." error *(TODO: Maybe this
|
|
||||||
can be worked around using another project code generation settings)*.
|
|
||||||
Working launcher is not needed to run the game though, as mentioned in
|
|
||||||
first part of this tutorial (prerequisites). Additional workaround to
|
|
||||||
skip compiling launcher and have access to launcher settings is to use
|
|
||||||
VCMI windows package as separate vcmi copy - changes made in launcher
|
|
||||||
there affect all vcmi copies.
|
|
||||||
|
|
||||||
**There is also Test project for development purposes that can be used
|
|
||||||
for unit tests and similar things that developers may want to do.**
|
|
@@ -1,72 +0,0 @@
|
|||||||
# Preparations
|
|
||||||
Windows builds can be made in more than one way and with more than one tool. This guide focuses on the simplest building process using Microsoft Visual Studio 2022
|
|
||||||
## Prerequisites
|
|
||||||
Windows Vista or newer.
|
|
||||||
Microsoft Visual Studio 2022 [download](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&channel=Release&version=VS2022&source=VSLandingPage&cid=2030&passive=false)
|
|
||||||
Git or git GUI, for example: SourceTree [download](https://www.sourcetreeapp.com/download), or GitKraken [download](https://www.gitkraken.com/download)
|
|
||||||
CMake [download](https://cmake.org/download/). During install after accepting license agreement make sure to check _"Add CMake to the system PATH for all users"_.
|
|
||||||
[7-zip](https://www.7-zip.org/download.html) For unpacking pre-build Vcpkg
|
|
||||||
|
|
||||||
## Choose an installation directory
|
|
||||||
Create a directory for VCMI development, eg. `C:\VCMI` We will call this directory `%VCMI_DIR%`
|
|
||||||
|
|
||||||
> Warning! Replace `%VCMI_DIR%` with path you've chosen for VCMI installation in the following commands.
|
|
||||||
|
|
||||||
> It is recommended to avoid non-ascii characters in the path to your working folders. The folder should not be write-protected by system.
|
|
||||||
Good locations:
|
|
||||||
`C:\VCMI`
|
|
||||||
Bad locations:
|
|
||||||
`C:\Users\Michał\VCMI (non-ascii character)`
|
|
||||||
`C:\Program Files (x86)\VCMI (write protection)`
|
|
||||||
|
|
||||||
## Install VCMI dependencies
|
|
||||||
We strongly recommend to use pre-built vcpkg.
|
|
||||||
|
|
||||||
### Download and unpack vcpkg archive
|
|
||||||
Vcpkg Archives are available at our GitHub: https://github.com/vcmi/vcmi-deps-windows/releases
|
|
||||||
|
|
||||||
* Download latest version available.
|
|
||||||
EG: v1.6 assets - [vcpkg-export-x64-windows-v143.7z](https://github.com/vcmi/vcmi-deps-windows/releases/download/v1.6/vcpkg-export-x64-windows-v143.7z)
|
|
||||||
* Extract archive by right clicking on it and choosing "7-zip -> Extract Here".
|
|
||||||
|
|
||||||
### Move dependencies to target directory
|
|
||||||
Once extracted, a `vcpkg` directory will appear with `installed` and `scripts` subfolders inside.
|
|
||||||
Move extracted `vcpkg` directory into your `%VCMI_DIR%`
|
|
||||||
|
|
||||||
# Build VCMI
|
|
||||||
## Clone VCMI
|
|
||||||
#### From GIT GUI
|
|
||||||
* Open SourceTree
|
|
||||||
* File -> Clone
|
|
||||||
* select `https://github.com/vcmi/vcmi/` as source
|
|
||||||
* select `%VCMI_DIR%/source` as destination
|
|
||||||
* expand Advanced Options and change Checkout Branch to `develop`
|
|
||||||
* tick `Recursive submodules`
|
|
||||||
* click Clone
|
|
||||||
#### From command line
|
|
||||||
* `git clone --recursive https://github.com/vcmi/vcmi.git %VCMI_DIR%/source`
|
|
||||||
|
|
||||||
## Generate solution for VCMI
|
|
||||||
* Create `%VCMI_DIR%/build` folder
|
|
||||||
* Open a command line prompt at `%VCMI_DIR%/build`
|
|
||||||
* Execute `cd %VCMI_DIR%/build`
|
|
||||||
* Create solution (Visual Studio 2022 64-bit) `cmake %VCMI_DIR%/source -DCMAKE_TOOLCHAIN_FILE=%VCMI_DIR%/vcpkg/scripts/buildsystems/vcpkg.cmake -G "Visual Studio 17 2022" -A x64`
|
|
||||||
|
|
||||||
## Compile VCMI with Visual Studio
|
|
||||||
Open `%VCMI_DIR%/build/VCMI.sln` in Visual Studio
|
|
||||||
Select `Release` build type in combobox
|
|
||||||
Right click on `BUILD_ALL` project. This `BUILD_ALL` project should be in `CMakePredefinedTargets` tree in Solution Explorer.
|
|
||||||
VCMI will be built in `%VCMI_DIR%/build/bin` folder!
|
|
||||||
|
|
||||||
# Notes
|
|
||||||
## Build is successful but can not start new game
|
|
||||||
Make sure you have:
|
|
||||||
* Installed Heroes III from disk or using GOG installer
|
|
||||||
* Copied `Data`, `Maps` and `Mp3` folders from Heroes III to: `%USERPROFILE%\Documents\My Games\vcmi\`
|
|
||||||
|
|
||||||
## Debug build is very slow
|
|
||||||
Debug builds with MSVC are generally extremely slow since it's not just VCMI binaries are built as debug, but every single dependency too and this usually means no optimizations at all. Debug information that available for release builds is often sufficient so just avoid full debug builds unless absolutely necessary. Instead use RelWithDebInfo configuration. Also Debug configuration might have some compilation issues because it is not checked via CI for now.
|
|
||||||
|
|
||||||
## Further notes:
|
|
||||||
For installing / uninstalling mods you need to launch `VCMI_launcher.exe`
|
|
||||||
For Map Editor you need to launch `VCMI_mapeditor.exe`
|
|
@@ -1,258 +0,0 @@
|
|||||||
# Prerequisites
|
|
||||||
|
|
||||||
- Windows Vista or newer.
|
|
||||||
- Microsoft Visual Studio
|
|
||||||
[2017](https://www.visualstudio.com/vs/older-downloads/) or
|
|
||||||
[2019](http://www.visualstudio.com/downloads/download-visual-studio-vs)
|
|
||||||
- CI use VS2019, so you are going to have less problems with it.
|
|
||||||
- Git or git GUI, for example, SourceTree
|
|
||||||
[download](http://www.sourcetreeapp.com/download)
|
|
||||||
- CMake [download](https://cmake.org/download/). During install after
|
|
||||||
accepting license agreement make sure to check "Add CMake to the
|
|
||||||
system PATH for all users".
|
|
||||||
- To unpack pre-build Vcpkg:
|
|
||||||
[7-zip](http://www.7-zip.org/download.html)
|
|
||||||
- To create installer: [NSIS](http://nsis.sourceforge.net/Main_Page)
|
|
||||||
|
|
||||||
# Choose directory
|
|
||||||
|
|
||||||
Create a directory for VCMI development, eg. **C:\VCMI** We will call
|
|
||||||
this directory **%VCMI_DIR%**
|
|
||||||
|
|
||||||
**Warning!** Replace **%VCMI_DIR%** with path you chosen in following
|
|
||||||
commands of this instruction.
|
|
||||||
|
|
||||||
## How to choose good directory
|
|
||||||
|
|
||||||
It is recommended to avoid non-ascii characters in the path to your
|
|
||||||
working folders. The folder should not be write-protected by system.
|
|
||||||
Good location:
|
|
||||||
|
|
||||||
- **C:\VCMI**
|
|
||||||
|
|
||||||
Bad locations:
|
|
||||||
|
|
||||||
- **C:\Users\Michał\VCMI** (non-ascii character)
|
|
||||||
- **C:\Program Files (x86)\VCMI** (write protection)
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
|
|
||||||
You have two options: to use pre-built libraries or build your own. We
|
|
||||||
strongly recommend start with using pre-built ones.
|
|
||||||
|
|
||||||
## Option A. Use pre-built Vcpkg
|
|
||||||
|
|
||||||
So you decide to start using Vcpkg packages pre-built by VCMI team.
|
|
||||||
|
|
||||||
Package guaranteed to work since they tested with every commit by
|
|
||||||
[GitHub Actions](https://github.com/vcmi/vcmi/actions).
|
|
||||||
|
|
||||||
### Download and unpack archive
|
|
||||||
|
|
||||||
Archives are available from GitHub:
|
|
||||||
<https://github.com/vcmi/vcmi-deps-windows/releases>
|
|
||||||
|
|
||||||
Only download latest version available.
|
|
||||||
|
|
||||||
- vcpkg-export-**x86**-windows-v140.7z to build for 32-bit no debug, 3
|
|
||||||
times smaller file size
|
|
||||||
- vcpkg-export-**x64**-windows-v140.7z to build for 64-bit no debug, 3
|
|
||||||
times smaller file size
|
|
||||||
- vcpkg-export-**x86**-windows-v140-debug.7z to build for 32-bit with
|
|
||||||
debug configuration available
|
|
||||||
- vcpkg-export-**x64**-windows-v140-debug.7z to build for 64-bit with
|
|
||||||
debug configuration available
|
|
||||||
|
|
||||||
Extract archive by right clicking on it and choosing "7-zip -\> Extract
|
|
||||||
Here".
|
|
||||||
|
|
||||||
### Move dependencies to target directory
|
|
||||||
|
|
||||||
Once extracted "vcpkg" directory will appear with "installed" and
|
|
||||||
"scripts" inside it.
|
|
||||||
|
|
||||||
Move extracted "vcpkg" directory into your **%VCMI_DIR%**.
|
|
||||||
|
|
||||||
## Option B. Build Vcpkg on your own
|
|
||||||
|
|
||||||
Please be aware that if you're running 32-bit Windows version, then this
|
|
||||||
is impossible due to <https://github.com/microsoft/vcpkg/issues/26036>
|
|
||||||
|
|
||||||
Be aware that building Vcpkg might take a lot of time depend on your CPU
|
|
||||||
model and 10-20GB of disk space.
|
|
||||||
|
|
||||||
### Create initial directory
|
|
||||||
|
|
||||||
### Clone vcpkg
|
|
||||||
|
|
||||||
1. open SourceTree
|
|
||||||
2. File -\> Clone
|
|
||||||
3. select **<https://github.com/microsoft/vcpkg/>** as source
|
|
||||||
4. select **%VCMI_DIR%/vcpkg** as destination
|
|
||||||
5. click **Clone**
|
|
||||||
|
|
||||||
From command line use:
|
|
||||||
|
|
||||||
git clone https://github.com/microsoft/vcpkg.git %VCMI_DIR%/vcpkg
|
|
||||||
|
|
||||||
### Build vcpkg
|
|
||||||
|
|
||||||
- Run
|
|
||||||
|
|
||||||
<!-- -->
|
|
||||||
|
|
||||||
%VCMI_DIR%/vcpkg/bootstrap-vcpkg.bat
|
|
||||||
|
|
||||||
### Build dependencies
|
|
||||||
|
|
||||||
- For 32-bit build run:
|
|
||||||
|
|
||||||
<!-- -->
|
|
||||||
|
|
||||||
%VCMI_DIR%/vcpkg/vcpkg.exe install tbb:x64-windows fuzzylite:x64-windows sdl2:x64-windows sdl2-image:x64-windows sdl2-ttf:x64-windows sdl2-mixer[mpg123]:x64-windows boost:x64-windows qt5-base:x64-windows ffmpeg:x64-windows luajit:x64-windows
|
|
||||||
|
|
||||||
- For 64-bit build run
|
|
||||||
|
|
||||||
<!-- -->
|
|
||||||
|
|
||||||
%VCMI_DIR%/vcpkg/vcpkg.exe install install tbb:x86-windows fuzzylite:x86-windows sdl2:x86-windows sdl2-image:x86-windows sdl2-ttf:x86-windows sdl2-mixer[mpg123]:x86-windows boost:x86-windows qt5-base:x86-windows ffmpeg:x86-windows luajit:x86-windows
|
|
||||||
|
|
||||||
For the list of the packages used you can also consult
|
|
||||||
[vcmi-deps-windows readme](https://github.com/vcmi/vcmi-deps-windows) in
|
|
||||||
case this article gets outdated a bit.
|
|
||||||
|
|
||||||
# Build VCMI
|
|
||||||
|
|
||||||
## Clone VCMI
|
|
||||||
|
|
||||||
1. open SourceTree
|
|
||||||
2. File -\> Clone
|
|
||||||
3. select **<https://github.com/vcmi/vcmi/>** as source
|
|
||||||
4. select **%VCMI_DIR%/source** as destination
|
|
||||||
5. expand Advanced Options and change Checkout Branch to "develop"
|
|
||||||
6. tick Recursive submodules
|
|
||||||
7. click **Clone**
|
|
||||||
|
|
||||||
or From command line use:
|
|
||||||
|
|
||||||
git clone --recursive https://github.com/vcmi/vcmi.git %VCMI_DIR%/source
|
|
||||||
|
|
||||||
## Generate solution for VCMI
|
|
||||||
|
|
||||||
1. create **%VCMI_DIR%/build** folder
|
|
||||||
2. open **%VCMI_DIR%/build** in command line:
|
|
||||||
1. Run Command Prompt or Power Shell.
|
|
||||||
2. Execute: cd %VCMI_DIR%/build
|
|
||||||
3. execute one of following commands to generate project
|
|
||||||
|
|
||||||
**Visual Studio 2017 - 32-bit build**
|
|
||||||
|
|
||||||
cmake %VCMI_DIR%/source -DCMAKE_TOOLCHAIN_FILE=%VCMI_DIR%/vcpkg/scripts/buildsystems/vcpkg.cmake -G "Visual Studio 15 2017"
|
|
||||||
|
|
||||||
**Visual Studio 2017 - 64-bit build**
|
|
||||||
|
|
||||||
cmake %VCMI_DIR%/source -DCMAKE_TOOLCHAIN_FILE=%VCMI_DIR%/vcpkg/scripts/buildsystems/vcpkg.cmake -G "Visual Studio 15 2017 Win64"
|
|
||||||
|
|
||||||
**Visual Studio 2019 - 32-bit build**
|
|
||||||
|
|
||||||
cmake %VCMI_DIR%/source -DCMAKE_TOOLCHAIN_FILE=%VCMI_DIR%/vcpkg/scripts/buildsystems/vcpkg.cmake -G "Visual Studio 16 2019" -A Win32
|
|
||||||
|
|
||||||
**Visual Studio 2019 - 64-bit build**
|
|
||||||
|
|
||||||
cmake %VCMI_DIR%/source -DCMAKE_TOOLCHAIN_FILE=%VCMI_DIR%/vcpkg/scripts/buildsystems/vcpkg.cmake -G "Visual Studio 16 2019" -A x64
|
|
||||||
|
|
||||||
## Compile VCMI with Visual Studio
|
|
||||||
|
|
||||||
1. open **%VCMI_DIR%/build/VCMI.sln** in Visual Studio
|
|
||||||
2. select "Release" build type in combobox
|
|
||||||
3. right click on **BUILD_ALL** project - build project. This BUILD_ALL
|
|
||||||
project should be in "CMakePredefinedTargets" tree in Solution
|
|
||||||
Explorer.
|
|
||||||
4. grab VCMI in **%VCMI_DIR%/build/bin** folder!
|
|
||||||
|
|
||||||
## Compile VCMI from command line
|
|
||||||
|
|
||||||
**For release build**
|
|
||||||
|
|
||||||
cmake --build %VCMI_DIR%/build --config Release
|
|
||||||
|
|
||||||
**For debug build**
|
|
||||||
|
|
||||||
cmake --build %VCMI_DIR%/build --config Debug
|
|
||||||
|
|
||||||
Debug will be used by default even "--config" if not specified.
|
|
||||||
|
|
||||||
# Create VCMI installer (This step is not required for just building & development)
|
|
||||||
|
|
||||||
Make sure NSIS is installed to default directory or have registry entry
|
|
||||||
so CMake can find it.
|
|
||||||
|
|
||||||
After you build VCMI execute following commands from
|
|
||||||
**%VCMI_DIR%/build**.
|
|
||||||
|
|
||||||
### Execute following if you built for Release:
|
|
||||||
|
|
||||||
cpack
|
|
||||||
|
|
||||||
### If you built for Debug:
|
|
||||||
|
|
||||||
cpack -C Debug
|
|
||||||
|
|
||||||
# Troubleshooting and workarounds
|
|
||||||
|
|
||||||
Vcpkg might be very unstable due to limited popularity and fact of using
|
|
||||||
bleeding edge packages (such as most recent Boost). Using latest version
|
|
||||||
of dependencies could also expose both problems in VCMI code or library
|
|
||||||
interface changes that developers not checked yet. So if you're built
|
|
||||||
Vcpkg yourself and can't get it working please try to use binary
|
|
||||||
package.
|
|
||||||
|
|
||||||
Pre-built version we provide is always manually tested with all
|
|
||||||
supported versions of MSVC for both Release and Debug builds and all
|
|
||||||
known quirks are listed below.
|
|
||||||
|
|
||||||
### VCMI won't run since some library is missing
|
|
||||||
|
|
||||||
**If you open solution using vcmi.sln** Try to build INSTALL target and
|
|
||||||
see if its output works as expected. Copy missing libraries or even all
|
|
||||||
libraries from there to your build directory. Or run cpack and use
|
|
||||||
produced installer and see if you can get libs from there. cpack -V will
|
|
||||||
give more info. If cpack complains that it can not find dumpbin try
|
|
||||||
Visual Studio Command Prompt (special version of cmd provided with
|
|
||||||
Visual Studio with additional PATH) or modify PATH to have this tool
|
|
||||||
available. Another alternative if you use prebuilt vcpkg package is to
|
|
||||||
download latest msvc build, install it and copy missing/all libraries
|
|
||||||
from there.
|
|
||||||
|
|
||||||
### Debug build is very slow
|
|
||||||
|
|
||||||
Debug builds with MSVC are generally extremely slow since it's not just
|
|
||||||
VCMI binaries are built as debug, but every single dependency too and
|
|
||||||
this usually means no optimizations at all. Debug information that
|
|
||||||
available for release builds is often sufficient so just avoid full
|
|
||||||
debug builds unless absolutely necessary. Instead use RelWithDebInfo
|
|
||||||
configuration. Also Debug configuration might have some compilation
|
|
||||||
issues because it is not checked via CI for now.
|
|
||||||
|
|
||||||
### I got crash within library XYZ.dll
|
|
||||||
|
|
||||||
VCPKG generated projects quite often have both debug and regular libs
|
|
||||||
available to linker so it can select wrong lib. For stable
|
|
||||||
RelWithDebInfo build you may try to remove debug folder from
|
|
||||||
VCPKG/installed/x64-windows. Same is done on CI. Also it reduces package
|
|
||||||
size at least twice.
|
|
||||||
|
|
||||||
### Some outdated problems
|
|
||||||
|
|
||||||
All problems of such kind should be solved with proper cmake INSTALL
|
|
||||||
code.
|
|
||||||
|
|
||||||
**Build is successful but can not start new game**
|
|
||||||
|
|
||||||
Check that all non-VCMI dlls in AI and Scripting (vcmilua.dll and
|
|
||||||
vcmierm.dll) folders are also copied to the parent folder so that they
|
|
||||||
are available for vcmi_clent.exe. These are tbb.dll fuzzylite.dll
|
|
||||||
lua51.dll. Also there should be as well folder scripts (lua scripts for
|
|
||||||
ERM). If scripting folder is absent please build vcmiLua and vcmiErm
|
|
||||||
projects. There is no direct dependency between them and vcmi_client for
|
|
||||||
now (2021-08-28)
|
|
@@ -1,111 +0,0 @@
|
|||||||
## Requirements
|
|
||||||
|
|
||||||
1. **macOS**
|
|
||||||
2. Xcode: <https://developer.apple.com/xcode/>
|
|
||||||
3. CMake 3.21+: `brew install --cask cmake` or get from
|
|
||||||
<https://cmake.org/download/>
|
|
||||||
|
|
||||||
## Obtaining source code
|
|
||||||
|
|
||||||
Clone <https://github.com/vcmi/vcmi> with submodules. Example for
|
|
||||||
command line:
|
|
||||||
|
|
||||||
`git clone --recurse-submodules https://github.com/vcmi/vcmi.git`
|
|
||||||
|
|
||||||
## Obtaining dependencies
|
|
||||||
|
|
||||||
There're 2 ways to get prebuilt dependencies:
|
|
||||||
|
|
||||||
- [Conan package
|
|
||||||
manager](https://github.com/vcmi/vcmi/tree/develop/docs/conan.md) -
|
|
||||||
recommended. Note that the link points to the cutting-edge state in
|
|
||||||
`develop` branch, for the latest release check the same document in
|
|
||||||
the [master
|
|
||||||
branch](https://github.com/vcmi/vcmi/tree/master/docs/conan.md).
|
|
||||||
- [legacy manually built
|
|
||||||
libraries](https://github.com/vcmi/vcmi-ios-deps) - can be used if
|
|
||||||
you have Xcode 11/12 or to build for simulator / armv7 device
|
|
||||||
|
|
||||||
## Configuring project
|
|
||||||
|
|
||||||
Only Xcode generator (`-G Xcode`) is supported!
|
|
||||||
|
|
||||||
As a minimum, you must pass the following variables to CMake:
|
|
||||||
|
|
||||||
- `BUNDLE_IDENTIFIER_PREFIX`: unique bundle identifier prefix,
|
|
||||||
something like `com.MY-NAME`
|
|
||||||
- (if using legacy dependencies) `CMAKE_PREFIX_PATH`: path to the
|
|
||||||
downloaded dependencies, e.g.
|
|
||||||
`~/Downloads/vcmi-ios-depends/build/iphoneos`
|
|
||||||
|
|
||||||
There're a few [CMake
|
|
||||||
presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html):
|
|
||||||
for device (Conan and legacy dependencies) and for simulator, named
|
|
||||||
`ios-device-conan`, `ios-device` and `ios-simulator` respectively. You
|
|
||||||
can also create your local "user preset" to avoid typing variables each
|
|
||||||
time, see example
|
|
||||||
[here](https://gist.github.com/kambala-decapitator/59438030c34b53aed7d3895aaa48b718).
|
|
||||||
|
|
||||||
Open terminal and `cd` to the directory with source code. Configuration
|
|
||||||
example for device with Conan:
|
|
||||||
|
|
||||||
`cmake --preset ios-device-conan \`
|
|
||||||
` -D BUNDLE_IDENTIFIER_PREFIX=com.MY-NAME`
|
|
||||||
|
|
||||||
By default build directory containing Xcode project will appear at
|
|
||||||
`../build-ios-device-conan`, but you can change it with `-B` option.
|
|
||||||
|
|
||||||
### Building for device
|
|
||||||
|
|
||||||
To be able to build for iOS device, you must also specify codesigning
|
|
||||||
settings. If you don't know your development team ID, open the generated
|
|
||||||
Xcode project, open project settings (click **VCMI** with blue icon on
|
|
||||||
the very top in the left panel with files), select **vcmiclient**
|
|
||||||
target, open **Signing & Capabilities** tab and select yout team. Now
|
|
||||||
you can copy the value from **Build Settings** tab - `DEVELOPMENT_TEAM`
|
|
||||||
variable (paste it in the Filter field on the right) - click the
|
|
||||||
greenish value - Other... - copy. Now you can pass it in
|
|
||||||
`CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM` variable when configuring the
|
|
||||||
project to avoid selecting the team manually every time CMake
|
|
||||||
re-generates the project.
|
|
||||||
|
|
||||||
Advanced users who know exact private key and provisioning profile to
|
|
||||||
sign with, can use `CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY` and
|
|
||||||
`CMAKE_XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER` variables
|
|
||||||
instead. In this case you must also pass
|
|
||||||
|
|
||||||
`-D CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE=Manual`.
|
|
||||||
|
|
||||||
## Building project
|
|
||||||
|
|
||||||
### From Xcode IDE
|
|
||||||
|
|
||||||
Open `VCMI.xcodeproj` from the build directory, select `vcmiclient`
|
|
||||||
scheme (the only one with nice icon) with your destination
|
|
||||||
device/simulator and hit Run (Cmd+R).
|
|
||||||
|
|
||||||
You must also install game files, see [Installation on
|
|
||||||
iOS](Installation_on_iOS "wikilink"). But this is not necessary if you
|
|
||||||
are going to run on simulator, as it is able to use game data from your
|
|
||||||
Mac located at `~/Library/Application Support/vcmi`.
|
|
||||||
|
|
||||||
### From command line
|
|
||||||
|
|
||||||
`cmake --build `<path to build directory>` --target vcmiclient -- -quiet`
|
|
||||||
|
|
||||||
You can pass additional xcodebuild options after the `--`. Here `-quiet`
|
|
||||||
is passed to reduce amount of output.
|
|
||||||
|
|
||||||
Alternatively, you can invoke `xcodebuild` directly.
|
|
||||||
|
|
||||||
There's also `ios-release-conan` configure and build preset that is used
|
|
||||||
to create release build on CI.
|
|
||||||
|
|
||||||
## Creating ipa file for distribution
|
|
||||||
|
|
||||||
Invoke `cpack` after building:
|
|
||||||
|
|
||||||
`cpack -C Release`
|
|
||||||
|
|
||||||
This will generate file with extension **ipa** if you use CMake 3.25+
|
|
||||||
and **zip** otherwise (simply change extension to ipa).
|
|
@@ -1,170 +0,0 @@
|
|||||||
# Requirements
|
|
||||||
|
|
||||||
1. C++ toolchain, either of:
|
|
||||||
- Xcode Command Line Tools (aka CLT):
|
|
||||||
`sudo xcode-select --install`
|
|
||||||
- Xcode IDE: <https://developer.apple.com/xcode/>
|
|
||||||
- (not tested) other C++ compilers, e.g. gcc/clang from
|
|
||||||
[Homebrew](https://brew.sh/)
|
|
||||||
2. CMake: `brew install --cask cmake` or get from
|
|
||||||
<https://cmake.org/download/>
|
|
||||||
3. (optional) Ninja: `brew install ninja` or get from
|
|
||||||
<https://github.com/ninja-build/ninja/releases>
|
|
||||||
|
|
||||||
# Obtaining source code
|
|
||||||
|
|
||||||
Clone <https://github.com/vcmi/vcmi> with submodules. Example for
|
|
||||||
command line:
|
|
||||||
|
|
||||||
`git clone --recurse-submodules https://github.com/vcmi/vcmi.git`
|
|
||||||
|
|
||||||
# Obtaining dependencies
|
|
||||||
|
|
||||||
There're 2 ways to get dependencies automatically.
|
|
||||||
|
|
||||||
## Conan package manager
|
|
||||||
|
|
||||||
Please find detailed instructions in [VCMI
|
|
||||||
repository](https://github.com/vcmi/vcmi/tree/develop/docs/conan.md).
|
|
||||||
Note that the link points to the cutting-edge state in `develop` branch,
|
|
||||||
for the latest release check the same document in the [master
|
|
||||||
branch](https://github.com/vcmi/vcmi/tree/master/docs/conan.md).
|
|
||||||
|
|
||||||
On the step where you need to replace **PROFILE**, choose:
|
|
||||||
|
|
||||||
- if you're on an Intel Mac: `macos-intel`
|
|
||||||
- if you're on an Apple Silicon Mac: `macos-arm`
|
|
||||||
|
|
||||||
Note: if you wish to build 1.0 release in non-`Release` configuration,
|
|
||||||
you should define `USE_CONAN_WITH_ALL_CONFIGS=1` environment variable
|
|
||||||
when executing `conan install`.
|
|
||||||
|
|
||||||
## Homebrew
|
|
||||||
|
|
||||||
1. [Install Homebrew](https://brew.sh/)
|
|
||||||
2. Install dependencies:
|
|
||||||
`brew install boost minizip sdl2 sdl2_image sdl2_mixer sdl2_ttf tbb`
|
|
||||||
3. If you want to watch in-game videos, also install FFmpeg:
|
|
||||||
`brew install ffmpeg@4`
|
|
||||||
4. Install Qt dependency in either of the ways (note that you can skip
|
|
||||||
this if you're not going to build Launcher):
|
|
||||||
- `brew install qt@5` for Qt 5 or `brew install qt` for Qt 6
|
|
||||||
- using [Qt Online Installer](https://www.qt.io/download) - choose
|
|
||||||
**Go open source**
|
|
||||||
|
|
||||||
# Preparing build environment
|
|
||||||
|
|
||||||
This applies only to Xcode-based toolchain. If `xcrun -f clang` prints
|
|
||||||
errors, then use either of the following ways:
|
|
||||||
|
|
||||||
- select an Xcode instance from Xcode application - Preferences -
|
|
||||||
Locations - Command Line Tools
|
|
||||||
- use `xcode-select` utility to set Xcode or Xcode Command Line Tools
|
|
||||||
path: for example,
|
|
||||||
`sudo xcode-select -s /Library/Developer/CommandLineTools`
|
|
||||||
- set `DEVELOPER_DIR` environment variable pointing to Xcode or Xcode
|
|
||||||
Command Line Tools path: for example,
|
|
||||||
`export DEVELOPER_DIR=/Applications/Xcode.app`
|
|
||||||
|
|
||||||
# Configuring project for building
|
|
||||||
|
|
||||||
Note that if you wish to use Qt Creator IDE, you should skip this step
|
|
||||||
and configure respective variables inside the IDE.
|
|
||||||
|
|
||||||
1. In Terminal `cd` to the source code directory
|
|
||||||
2. Start assembling CMake invocation: type `cmake -S . -B BUILD_DIR`
|
|
||||||
where *BUILD_DIR* can be any path, **don't press Return**
|
|
||||||
3. Decide which CMake generator you want to use:
|
|
||||||
- Makefiles: no extra option needed or pass `-G 'Unix Makefiles'`
|
|
||||||
- Ninja (if you have installed it): pass `-G Ninja`
|
|
||||||
- Xcode IDE (if you have installed it): pass `-G Xcode`
|
|
||||||
4. If you picked Makefiles or Ninja, pick desired *build type* - either
|
|
||||||
of Debug / RelWithDebInfo / Release / MinSizeRel - and pass it in
|
|
||||||
`CMAKE_BUILD_TYPE` option, for example:
|
|
||||||
`-D CMAKE_BUILD_TYPE=Release`. If you don't pass this option,
|
|
||||||
`RelWithDebInfo` will be used.
|
|
||||||
5. If you don't want to build Launcher, pass `-D ENABLE_LAUNCHER=OFF`
|
|
||||||
6. You can also pass `-Wno-dev` if you're not interested in CMake
|
|
||||||
developer warnings
|
|
||||||
7. Next step depends on the dependency manager you have picked:
|
|
||||||
- Conan: pass
|
|
||||||
`-D CMAKE_TOOLCHAIN_FILE=conan-generated/conan_toolchain.cmake`
|
|
||||||
where **conan-generated** must be replaced with your directory
|
|
||||||
choice
|
|
||||||
- Homebrew: if you installed FFmpeg or Qt 5, you need to pass
|
|
||||||
`-D "CMAKE_PREFIX_PATH="` variable. See below what you can
|
|
||||||
insert after `=` (but **before the closing quote**), multiple
|
|
||||||
values must be separated with `;` (semicolon):
|
|
||||||
- if you installed FFmpeg, insert `$(brew --prefix ffmpeg@4)`
|
|
||||||
- if you installed Qt 5 from Homebrew, insert:
|
|
||||||
`$(brew --prefix qt@5)`
|
|
||||||
- if you installed Qt from Online Installer, insert your path
|
|
||||||
to Qt directory, for example:
|
|
||||||
`/Users/kambala/dev/Qt-libs/5.15.2/Clang64`
|
|
||||||
- example for FFmpeg + Qt 5:
|
|
||||||
`-D "CMAKE_PREFIX_PATH=$(brew --prefix ffmpeg@4);$(brew --prefix qt@5)"`
|
|
||||||
8. now press Return
|
|
||||||
|
|
||||||
# Building project
|
|
||||||
|
|
||||||
You must also install game files to be able to run the built version,
|
|
||||||
see [Installation on macOS](Installation_on_macOS "wikilink").
|
|
||||||
|
|
||||||
## From Xcode IDE
|
|
||||||
|
|
||||||
Open `VCMI.xcodeproj` from the build directory, select `vcmiclient`
|
|
||||||
scheme and hit Run (Cmd+R). To build Launcher, select `vcmilauncher`
|
|
||||||
scheme instead.
|
|
||||||
|
|
||||||
## From command line
|
|
||||||
|
|
||||||
`cmake --build `<path to build directory>
|
|
||||||
|
|
||||||
- If using Makefiles generator, you'd want to utilize all your CPU
|
|
||||||
cores by appending `-- -j$(sysctl -n hw.ncpu)` to the above
|
|
||||||
- If using Xcode generator, you can also choose which configuration to
|
|
||||||
build by appending `--config `<configuration name> to the above, for
|
|
||||||
example: `--config Debug`
|
|
||||||
|
|
||||||
# Packaging project into DMG file
|
|
||||||
|
|
||||||
After building, run `cpack` from the build directory. If using Xcode
|
|
||||||
generator, also pass `-C `<configuration name> with the same
|
|
||||||
configuration that you used to build the project.
|
|
||||||
|
|
||||||
If you use Conan, it's expected that you use **conan-generated**
|
|
||||||
directory at step 4 of [#Conan package
|
|
||||||
manager](#Conan_package_manager "wikilink").
|
|
||||||
|
|
||||||
# Running VCMI
|
|
||||||
|
|
||||||
You can run VCMI from DMG, but it's will also work from your IDE be it
|
|
||||||
Xcode or Qt Creator.
|
|
||||||
|
|
||||||
Alternatively you can run binaries directly from "bin" directory:
|
|
||||||
|
|
||||||
BUILD_DIR/bin/vcmilauncher
|
|
||||||
BUILD_DIR/bin/vcmiclient
|
|
||||||
BUILD_DIR/bin/vcmiserver
|
|
||||||
|
|
||||||
CMake include commands to copy all needed assets from source directory
|
|
||||||
into "bin" on each build. They'll work when you build from Xcode too.
|
|
||||||
|
|
||||||
# Some useful debugging tips
|
|
||||||
|
|
||||||
Anyone who might want to debug builds, but new to macOS could find
|
|
||||||
following commands useful:
|
|
||||||
|
|
||||||
# To attach DMG file from command line use
|
|
||||||
hdiutil attach vcmi-1.0.dmg
|
|
||||||
# Detach volume:
|
|
||||||
hdiutil detach /Volumes/vcmi-1.0
|
|
||||||
# To view dependency paths
|
|
||||||
otool -L /Volumes/vcmi-1.0/VCMI.app/Contents/MacOS/vcmiclient
|
|
||||||
# To display load commands such as LC_RPATH
|
|
||||||
otool -l /Volumes/vcmi-1.0/VCMI.app/Contents/MacOS/vcmiclient
|
|
||||||
|
|
||||||
# Troubleshooting
|
|
||||||
|
|
||||||
In case of troubles you can always consult our CI build scripts or
|
|
||||||
contact the dev team via slack
|
|
@@ -1,10 +1,8 @@
|
|||||||
# Features
|
# Features
|
||||||
|
|
||||||
- A logger belongs to a "domain", this enables us to change log level
|
- A logger belongs to a "domain", this enables us to change log level settings more selectively
|
||||||
settings more selectively
|
|
||||||
- The log format can be customized
|
- The log format can be customized
|
||||||
- The color of a log entry can be customized based on logger domain
|
- The color of a log entry can be customized based on logger domain and logger level
|
||||||
and logger level
|
|
||||||
- Logger settings can be changed in the settings.json file
|
- Logger settings can be changed in the settings.json file
|
||||||
- No std::endl at the end of a log entry required
|
- No std::endl at the end of a log entry required
|
||||||
- Thread-safe
|
- Thread-safe
|
||||||
@@ -21,15 +19,8 @@ title="Logging_Class_Diagram.jpg" />
|
|||||||
|
|
||||||
Some notes:
|
Some notes:
|
||||||
|
|
||||||
- There are two methods `configure` and `configureDefault` of the
|
- There are two methods `configure` and `configureDefault` of the class `CBasicLogConfigurator` to initialize and setup the logging system. The latter one setups default logging and isn't dependent on VCMI's filesystem, whereas the first one setups logging based on the user's settings which can be configured in the settings.json.
|
||||||
class `CBasicLogConfigurator` to initialize and setup the logging
|
- The methods `isDebugEnabled` and `isTraceEnabled` return true if a log record of level debug respectively trace will be logged. This can be useful if composing the log message is a expensive task and performance is important.
|
||||||
system. The latter one setups default logging and isn't dependent on
|
|
||||||
VCMI's filesystem, whereas the first one setups logging based on the
|
|
||||||
user's settings which can be configured in the settings.json.
|
|
||||||
- The methods `isDebugEnabled` and `isTraceEnabled` return true if a
|
|
||||||
log record of level debug respectively trace will be logged. This
|
|
||||||
can be useful if composing the log message is a expensive task and
|
|
||||||
performance is important.
|
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
@@ -62,37 +53,30 @@ Some notes:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The above code is an example on how to configure logging. It sets the
|
The above code is an example on how to configure logging. It sets the log level to debug globally and the log level of the domain ai to trace. In addition, it tells the console to log debug messages as well with the threshold attribute. Finally, it configures the console so that it logs network trace messages in magenta.
|
||||||
log level to debug globally and the log level of the domain ai to trace.
|
|
||||||
In addition, it tells the console to log debug messages as well with the
|
|
||||||
threshold attribute. Finally, it configures the console so that it logs
|
|
||||||
network trace messages in magenta.
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The following code shows how the logging system can be configured:
|
The following code shows how the logging system can be configured:
|
||||||
|
|
||||||
|
```cpp
|
||||||
console = new CConsoleHandler;
|
console = new CConsoleHandler;
|
||||||
CBasicLogConfigurator logConfig(VCMIDirs::get().localPath() + "/VCMI_Server_log.txt", console);
|
CBasicLogConfigurator logConfig(VCMIDirs::get().localPath() + "/VCMI_Server_log.txt", console);
|
||||||
logConfig.configureDefault(); // Initialize default logging due to that the filesystem and settings are not available
|
logConfig.configureDefault(); // Initialize default logging due to that the filesystem and settings are not available
|
||||||
preinitDLL(console); // Init filesystem
|
preinitDLL(console); // Init filesystem
|
||||||
settings.init(); // Init settings
|
settings.init(); // Init settings
|
||||||
logConfig.configure(); // Now setup "real" logging system, overwrites default settings
|
logConfig.configure(); // Now setup "real" logging system, overwrites default settings
|
||||||
|
```
|
||||||
|
|
||||||
If `configureDefault` or `configure` won't be called, then logs aren't
|
If `configureDefault` or `configure` won't be called, then logs aren't written either to the console or to the file. The default logging setups a system like this:
|
||||||
written either to the console or to the file. The default logging setups
|
|
||||||
a system like this:
|
|
||||||
|
|
||||||
**Console**
|
**Console**
|
||||||
|
|
||||||
Format: %m
|
Format: %m
|
||||||
|
|
||||||
Threshold: info
|
Threshold: info
|
||||||
|
|
||||||
coloredOutputEnabled: true
|
coloredOutputEnabled: true
|
||||||
|
|
||||||
colorMapping: trace -\> gray, debug -\> white, info -\> green, warn -\>
|
colorMapping: trace -\> gray, debug -\> white, info -\> green, warn -\> yellow, error -\> red
|
||||||
yellow, error -\> red
|
|
||||||
|
|
||||||
**File**
|
**File**
|
||||||
|
|
||||||
@@ -104,40 +88,29 @@ global -\> info
|
|||||||
|
|
||||||
## How to get a logger
|
## How to get a logger
|
||||||
|
|
||||||
There exist only one logger object per domain. A logger object cannot be
|
There exist only one logger object per domain. A logger object cannot be copied. You can get access to a logger object by using the globally defined ones like `logGlobal` or `logAi`, etc... or by getting one manually:
|
||||||
copied. You can get access to a logger object by using the globally
|
```cpp
|
||||||
defined ones like `logGlobal` or `logAi`, etc... or by getting one
|
Logger * logger = CLogger::getLogger(CLoggerDomain("rmg"));
|
||||||
manually:
|
```
|
||||||
|
|
||||||
CLogger * logger = CLogger::getLogger(CLoggerDomain("rmg"));
|
|
||||||
|
|
||||||
## Logging
|
## Logging
|
||||||
|
|
||||||
Logging can be done via two ways, stream-like or function-like.
|
Logging can be done via two ways, stream-like or function-like.
|
||||||
|
|
||||||
|
```cpp
|
||||||
logGlobal->warnStream() << "Call to loadBitmap with void fname!";
|
logGlobal->warnStream() << "Call to loadBitmap with void fname!";
|
||||||
logGlobal->warn("Call to loadBitmap with void fname!");
|
logGlobal->warn("Call to loadBitmap with void fname!");
|
||||||
|
```
|
||||||
|
|
||||||
Don't include a '\n' or std::endl at the end of your log message, a new
|
Don't include a '\n' or std::endl at the end of your log message, a new line will be appended automatically.
|
||||||
line will be appended automatically.
|
|
||||||
|
|
||||||
The following list shows several log levels from the highest one to the
|
The following list shows several log levels from the highest one to the lowest one:
|
||||||
lowest one:
|
|
||||||
|
|
||||||
- error -\> for errors, e.g. if resource is not available, if a
|
- error -\> for errors, e.g. if resource is not available, if a initialization fault has occured, if a exception has been thrown (can result in program termination)
|
||||||
initialization fault has occured, if a exception has been thrown
|
- warn -\> for warnings, e.g. if sth. is wrong, but the program can continue execution "normally"
|
||||||
(can result in program termination)
|
- info -\> informational messages, e.g. Filesystem initialized, Map loaded, Server started, etc...
|
||||||
- warn -\> for warnings, e.g. if sth. is wrong, but the program can
|
- debug -\> for debugging, e.g. hero moved to (12,3,0), direction 3', 'following artifacts influence X: .. or pattern detected at pos (10,15,0), p-nr. 30, flip 1, repl. 'D'
|
||||||
continue execution "normally"
|
- trace -\> for logging the control flow, the execution progress or fine-grained events, e.g. hero movement completed, entering CMapEditManager::updateTerrainViews: posx '10', posy '5', width '10', height '10', mapLevel '0',...
|
||||||
- info -\> informational messages, e.g. Filesystem initialized, Map
|
|
||||||
loaded, Server started, etc...
|
|
||||||
- debug -\> for debugging, e.g. hero moved to (12,3,0), direction 3',
|
|
||||||
'following artifacts influence X: .. or pattern detected at pos
|
|
||||||
(10,15,0), p-nr. 30, flip 1, repl. 'D'
|
|
||||||
- trace -\> for logging the control flow, the execution progress or
|
|
||||||
fine-grained events, e.g. hero movement completed, entering
|
|
||||||
CMapEditManager::updateTerrainViews: posx '10', posy '5', width
|
|
||||||
'10', height '10', mapLevel '0',...
|
|
||||||
|
|
||||||
The following colors are available for console output:
|
The following colors are available for console output:
|
||||||
|
|
||||||
@@ -152,12 +125,9 @@ The following colors are available for console output:
|
|||||||
|
|
||||||
## How to trace execution
|
## How to trace execution
|
||||||
|
|
||||||
The program execution can be traced by using the macros TRACE_BEGIN,
|
The program execution can be traced by using the macros TRACE_BEGIN, TRACE_END and their \_PARAMS counterparts. This can be important if you want to analyze the operations/internal workings of the AI or the communication of the client-server. In addition, it can help you to find bugs on a foreign VCMI installation with a custom mod configuration.
|
||||||
TRACE_END and their \_PARAMS counterparts. This can be important if you
|
|
||||||
want to analyze the operations/internal workings of the AI or the
|
|
||||||
communication of the client-server. In addition, it can help you to find
|
|
||||||
bugs on a foreign VCMI installation with a custom mod configuration.
|
|
||||||
|
|
||||||
|
```cpp
|
||||||
int calculateMovementPointsForPath(int3 start, int3 end, CHero * hero) // This is just an example, the function is fictive
|
int calculateMovementPointsForPath(int3 start, int3 end, CHero * hero) // This is just an example, the function is fictive
|
||||||
{
|
{
|
||||||
TRACE_BEGIN_PARAMS(logGlobal, "start '%s', end '%s', hero '%s'", start.toString() % end.toString() % hero.getName()); // toString is fictive as well and returns a string representation of the int3 pos, ....
|
TRACE_BEGIN_PARAMS(logGlobal, "start '%s', end '%s', hero '%s'", start.toString() % end.toString() % hero.getName()); // toString is fictive as well and returns a string representation of the int3 pos, ....
|
||||||
@@ -167,24 +137,20 @@ bugs on a foreign VCMI installation with a custom mod configuration.
|
|||||||
TRACE_END_PARAMS(logGlobal, "movPoints '%i'", movPoints);
|
TRACE_END_PARAMS(logGlobal, "movPoints '%i'", movPoints);
|
||||||
return movPoints;
|
return movPoints;
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# Concepts
|
# Concepts
|
||||||
|
|
||||||
## Domain
|
## Domain
|
||||||
|
|
||||||
A domain is a specific part of the software. In VCMI there exist several
|
A domain is a specific part of the software. In VCMI there exist several domains:
|
||||||
domains:
|
|
||||||
|
|
||||||
- network
|
- network
|
||||||
- ai
|
- ai
|
||||||
- bonus
|
- bonus
|
||||||
- network
|
- network
|
||||||
|
|
||||||
In addition to these domains, there exist always a super domain called
|
In addition to these domains, there exist always a super domain called "global". Sub-domains can be created with "ai.battle" or "ai.adventure" for example. The dot between the "ai" and "battle" is important and notes the parent-child relationship of those two domains. A few examples how the log level will be inherited:
|
||||||
"global". Sub-domains can be created with "ai.battle" or "ai.adventure"
|
|
||||||
for example. The dot between the "ai" and "battle" is important and
|
|
||||||
notes the parent-child relationship of those two domains. A few examples
|
|
||||||
how the log level will be inherited:
|
|
||||||
|
|
||||||
global, level=info
|
global, level=info
|
||||||
network, level=not set, effective level=info
|
network, level=not set, effective level=info
|
||||||
@@ -196,6 +162,4 @@ global, level=debug
|
|||||||
ai, level=not set, effective level=debug
|
ai, level=not set, effective level=debug
|
||||||
ai.battle, level=trace, effective level=trace
|
ai.battle, level=trace, effective level=trace
|
||||||
|
|
||||||
The same technique is applied to the console colors. If you want to have
|
The same technique is applied to the console colors. If you want to have another debug color for the domain ai, you can explicitely set a color for that domain and level.
|
||||||
another debug color for the domain ai, you can explicitely set a color
|
|
||||||
for that domain and level.
|
|
@@ -36,35 +36,30 @@
|
|||||||
|
|
||||||
## API Reference
|
## API Reference
|
||||||
|
|
||||||
TODO **In near future Lua API may change drastically several times.
|
TODO **In near future Lua API may change drastically several times. Information here may be outdated**
|
||||||
Information here may be outdated**
|
|
||||||
|
|
||||||
### Globals
|
### Globals
|
||||||
|
|
||||||
- DATA - persistent table
|
- DATA - persistent table
|
||||||
- DATA.ERM contains ERM state, anything else is free to use.
|
- - DATA.ERM contains ERM state, anything else is free to use.
|
||||||
- GAME - IGameInfoCallback API
|
- GAME - IGameInfoCallback API
|
||||||
- BATTLE - IBattleInfoCallback API
|
- BATTLE - IBattleInfoCallback API
|
||||||
- EVENT_BUS - opaque handle, for use with events API
|
- EVENT_BUS - opaque handle, for use with events API
|
||||||
- SERVICES - root "raw" access to all static game objects
|
- SERVICES - root "raw" access to all static game objects
|
||||||
- SERVICES:artifacts()
|
- - SERVICES:artifacts()
|
||||||
- SERVICES:creatures()
|
- - SERVICES:creatures()
|
||||||
- SERVICES:factions()
|
- - SERVICES:factions()
|
||||||
- SERVICES:heroClasses()
|
- - SERVICES:heroClasses()
|
||||||
- SERVICES:heroTypes()
|
- - SERVICES:heroTypes()
|
||||||
- SERVICES:spells()
|
- - SERVICES:spells()
|
||||||
- SERVICES:skills()
|
- - SERVICES:skills()
|
||||||
- require(URI)
|
- require(URI)
|
||||||
- works similar to usual Lua require
|
- -works similar to usual Lua require
|
||||||
- require("ClassName") - loads additional API and returns it as
|
- -require("ClassName") - loads additional API and returns it as table (for C++ classes)
|
||||||
table (for C++ classes)
|
- -require("core:relative.path.to.module") - loads module from "SCRIPTS/LIB"
|
||||||
- require("core:relative.path.to.module") - loads module from
|
- -TODO require("modName:relative.path.to.module") - loads module from dependent mod
|
||||||
"SCRIPTS/LIB"
|
- -TODO require(":relative.path.to.module") - loads module from same mod
|
||||||
- TODO require("modName:relative.path.to.module") - loads module
|
- logError(text) - backup error log function
|
||||||
from dependent mod
|
|
||||||
- TODO require(":relative.path.to.module") - loads module from
|
|
||||||
same mod
|
|
||||||
- logError(text) - backup error log function
|
|
||||||
|
|
||||||
### Low level events API
|
### Low level events API
|
||||||
|
|
||||||
@@ -86,8 +81,7 @@ sub2 = PlayerGotTurn.subscribeBefore(EVENT_BUS, function(event)
|
|||||||
|
|
||||||
### Lua standard library
|
### Lua standard library
|
||||||
|
|
||||||
VCMI uses LuaJIT, which is Lua 5.1 API, see [upstream
|
VCMI uses LuaJIT, which is Lua 5.1 API, see [upstream documentation](https://www.lua.org/manual/5.1/manual.html)
|
||||||
documentation](https://www.lua.org/manual/5.1/manual.html)
|
|
||||||
|
|
||||||
Following libraries are supported
|
Following libraries are supported
|
||||||
|
|
||||||
@@ -101,8 +95,7 @@ Following libraries are supported
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- no strict limit on function/variable numbers (technical limit 32 bit
|
- no strict limit on function/variable numbers (technical limit 32 bit integer except 0))
|
||||||
integer except 0))
|
|
||||||
- TODO semi compare
|
- TODO semi compare
|
||||||
- DONE macros
|
- DONE macros
|
||||||
|
|
||||||
@@ -158,52 +151,52 @@ Following libraries are supported
|
|||||||
|
|
||||||
### WoG
|
### WoG
|
||||||
|
|
||||||
- TODO !!AR Артефакт (ресурс) в определенной позиции
|
- TODO !!AR Артефакт (ресурс) в определенной позиции
|
||||||
- TODO !!BA Битва
|
- TODO !!BA Битва
|
||||||
- !!BA:A$ return 1 for battle evaluation
|
- !!BA:A$ return 1 for battle evaluation
|
||||||
- TODO !!BF Препятствия на поле боя
|
- TODO !!BF Препятствия на поле боя
|
||||||
- TODO !!BG Действий монстров в бою
|
- TODO !!BG Действий монстров в бою
|
||||||
- TODO !!BH Действия героя в бою
|
- TODO !!BH Действия героя в бою
|
||||||
- TODO !!BM Монстр в битве
|
- TODO !!BM Монстр в битве
|
||||||
- WIP !!BU Универсальные параметры битвы
|
- WIP !!BU Универсальные параметры битвы
|
||||||
- TODO !!CA Замок
|
- TODO !!CA Замок
|
||||||
- TODO !!CD Разрушения замков
|
- TODO !!CD Разрушения замков
|
||||||
- TODO !!CE События в замке
|
- TODO !!CE События в замке
|
||||||
- TODO !!CM Клика мышью
|
- TODO !!CM Клика мышью
|
||||||
- TODO !!DL Нестандартный диалог (только ТЕ или выше)
|
- TODO !!DL Нестандартный диалог (только ТЕ или выше)
|
||||||
- TODO !!CO Командиры
|
- TODO !!CO Командиры
|
||||||
- WIP !!DO Многократный вызов функции
|
- WIP !!DO Многократный вызов функции
|
||||||
- TODO !!EA Бонусы опыта существ
|
- TODO !!EA Бонусы опыта существ
|
||||||
- TODO !!EX Опыт стека
|
- TODO !!EX Опыт стека
|
||||||
- DONE !!FU Однократный вызов функции
|
- DONE !!FU Однократный вызов функции
|
||||||
- TODO !!GE Глобальное событие
|
- TODO !!GE Глобальное событие
|
||||||
- WIP !!HE Герой
|
- WIP !!HE Герой
|
||||||
- TODO !!HL Новый уровень героя
|
- TODO !!HL Новый уровень героя
|
||||||
- TODO !!HO Взаимодействия героев
|
- TODO !!HO Взаимодействия героев
|
||||||
- TODO !!HT Подсказки по правому клику
|
- TODO !!HT Подсказки по правому клику
|
||||||
- WIP !!IF Диалоги и флагов
|
- WIP !!IF Диалоги и флагов
|
||||||
- TODO !!IP Сетевой сервис битвы
|
- TODO !!IP Сетевой сервис битвы
|
||||||
- TODO !!LE Локальное события
|
- TODO !!LE Локальное события
|
||||||
- WIP !!MA Общие параметры монстров
|
- WIP !!MA Общие параметры монстров
|
||||||
- DONE !!MC Макросы
|
- DONE !!MC Макросы
|
||||||
- WIP !!MF Получение физ. урона в бою
|
- WIP !!MF Получение физ. урона в бою
|
||||||
- TODO !!MM Текст в битве
|
- TODO !!MM Текст в битве
|
||||||
- WIP !!MO Монстр в определенной позиции
|
- WIP !!MO Монстр в определенной позиции
|
||||||
- TODO !!MP Контроль MP3
|
- TODO !!MP Контроль MP3
|
||||||
- TODO !!MR Сопротивления магии
|
- TODO !!MR Сопротивления магии
|
||||||
- TODO !!MW Бродячих монстров
|
- TODO !!MW Бродячих монстров
|
||||||
- WIP !!OB Объект в определенной позиции
|
- WIP !!OB Объект в определенной позиции
|
||||||
- TODO !!OW Параметры игрока
|
- TODO !!OW Параметры игрока
|
||||||
- TODO !!PM Пирамиды или новые объекты
|
- TODO !!PM Пирамиды или новые объекты
|
||||||
- TODO !!PO Информация квадрата карты
|
- TODO !!PO Информация квадрата карты
|
||||||
- TODO (???) !!QW Журнала
|
- TODO (???) !!QW Журнала
|
||||||
- TODO !!SN Проигрываемые звуков
|
- TODO !!SN Проигрываемые звуков
|
||||||
- TODO !!SS Настройка заклинаний (только ТЕ или выше)
|
- TODO !!SS Настройка заклинаний (только ТЕ или выше)
|
||||||
- TODO !!TL Контроль времени хода (только ТЕ или выше)
|
- TODO !!TL Контроль времени хода (только ТЕ или выше)
|
||||||
- TODO !!TM Временный таймер
|
- TODO !!TM Временный таймер
|
||||||
- TODO !!TR Квадрата карты (почва, проходимость, т.п.)
|
- TODO !!TR Квадрата карты (почва, проходимость, т.п.)
|
||||||
- TODO !!UN Универсальная команда
|
- TODO !!UN Универсальная команда
|
||||||
- *!#VC Контроль переменных*
|
- *!#VC Контроль переменных*
|
||||||
- WIP !!VR Установка переменных
|
- WIP !!VR Установка переменных
|
||||||
|
|
||||||
## Persistence
|
## Persistence
|
@@ -1,70 +1,39 @@
|
|||||||
# Introduction
|
# Introduction
|
||||||
|
|
||||||
The serializer translates between objects living in our code (like int
|
The 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).
|
||||||
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).
|
|
||||||
|
|
||||||
VCMI uses binary format. The primitive types are simply copied from
|
VCMI uses binary format. The primitive types are simply copied from memory, more complex structures are represented as a sequence of primitives.
|
||||||
memory, more complex structures are represented as a sequence of
|
|
||||||
primitives.
|
|
||||||
|
|
||||||
## Typical tasks
|
## Typical tasks
|
||||||
|
|
||||||
### Bumping a version number
|
### Bumping a version number
|
||||||
|
|
||||||
Different major version of VCMI likely change the format of the save
|
Different 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.
|
||||||
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.
|
|
||||||
|
|
||||||
### Adding a new class
|
### Adding a new class
|
||||||
|
|
||||||
If you want your class to be serializable (eg. being storable in a
|
If 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](#User_types "wikilink")
|
||||||
savegame) you need to define a serialize method template, as described
|
|
||||||
in [#User types](#User_types "wikilink")
|
|
||||||
|
|
||||||
Additionally, if your class is part of one of registered object
|
Additionally, 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 `RegisterTypes.h` file. See [#Polymorphic serialization](#Polymorphic_serialization "wikilink") for more information.
|
||||||
hierarchies (basically: if it derives from CGObjectInstance,
|
|
||||||
IPropagator, ILimiter, CBonusSystemNode, CPack) it needs to be
|
|
||||||
registered. Just add an appropriate entry in the `RegisterTypes.h` file.
|
|
||||||
See [#Polymorphic serialization](#Polymorphic_serialization "wikilink")
|
|
||||||
for more information.
|
|
||||||
|
|
||||||
# How does it work
|
# How does it work
|
||||||
|
|
||||||
## Primitive types
|
## Primitive types
|
||||||
|
|
||||||
They are simply stored in a binary form, as in memory. Compatibility is
|
They are simply stored in a binary form, as in memory. Compatibility is ensued through the following means:
|
||||||
ensued through the following means:
|
|
||||||
|
|
||||||
- VCMI uses internally types that have constant, defined size (like
|
- VCMI uses internally types that have constant, defined size (like int32_t - has 32 bits on all platforms)
|
||||||
si32 - has 32 bits on all platforms)
|
- serializer stores information about its endianess
|
||||||
- serializer stores information about its endianess
|
|
||||||
|
|
||||||
It's not "really" portable, yet it works properly across all platforms
|
It's not "really" portable, yet it works properly across all platforms we currently support.
|
||||||
we currently support.
|
|
||||||
|
|
||||||
## Dependant types
|
## Dependant types
|
||||||
|
|
||||||
### Pointers
|
### Pointers
|
||||||
|
|
||||||
Storing pointers mechanics can be and almost always is customized. See
|
Storing pointers mechanics can be and almost always is customized. See [#Additional features](#Additional_features "wikilink").
|
||||||
[#Additional features](#Additional_features "wikilink").
|
|
||||||
|
|
||||||
In the most basic form storing pointer simply sends the object state and
|
In 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.
|
||||||
loading pointer allocates an object (using "new" operator) and fills its
|
|
||||||
state with the stored data.
|
|
||||||
|
|
||||||
### Arrays
|
### Arrays
|
||||||
|
|
||||||
@@ -89,9 +58,7 @@ Supported STL types include:
|
|||||||
|
|
||||||
### Smart pointers
|
### Smart pointers
|
||||||
|
|
||||||
Smart pointers at the moment are treated as the raw C-style pointers.
|
Smart pointers at the moment are treated as the raw C-style pointers. This is very bad and dangerous for shared_ptr and is expected to be fixed somewhen in the future.
|
||||||
This is very bad and dangerous for shared_ptr and is expected to be
|
|
||||||
fixed somewhen in the future.
|
|
||||||
|
|
||||||
The list of supported data types from standard library:
|
The list of supported data types from standard library:
|
||||||
|
|
||||||
@@ -107,18 +74,13 @@ Additionally, a few types for Boost are supported as well:
|
|||||||
|
|
||||||
## User types
|
## User types
|
||||||
|
|
||||||
To make the user-defined type serializable, it has to provide a template
|
To 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.
|
||||||
method serialize. The first argument (typed as template parameter) is a
|
|
||||||
reference to serializer. The second one is version number.
|
|
||||||
|
|
||||||
Serializer provides an operator& that is internally expanded to \<\<
|
Serializer provides an operator& that is internally expanded to `<<` when serialziing or `>>` when deserializing.
|
||||||
when serialziing or \>\> when deserializing.
|
|
||||||
|
|
||||||
Serializer provides a public bool field `saving`that set to true during
|
Serializer provides a public bool field `saving`that set to true during serialziation and to false for deserialziation.
|
||||||
serialziation and to false for deserialziation.
|
|
||||||
|
|
||||||
Typically, serializing class involves serializing all its members (given
|
Typically, serializing class involves serializing all its members (given that they are serializable). Sample:
|
||||||
that they are serializable). Sample:
|
|
||||||
|
|
||||||
``` cpp
|
``` cpp
|
||||||
/// The rumor struct consists of a rumor name and text.
|
/// The rumor struct consists of a rumor name and text.
|
||||||
@@ -130,20 +92,17 @@ struct DLL_LINKAGE Rumor
|
|||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
void serialize(Handler & h, const int version)
|
void serialize(Handler & h, const int version)
|
||||||
{
|
{
|
||||||
h & name & text;
|
h & name;
|
||||||
|
h & text;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
## Backwards compatibility
|
## Backwards compatibility
|
||||||
|
|
||||||
Serializer, before sending any data, stores its version number. It is
|
Serializer, 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.
|
||||||
passed as the parameter to the serialize method, so conditional code
|
|
||||||
ensuring backwards compatibility can be added.
|
|
||||||
|
|
||||||
Yet, because of numerous changes to our game data structure, providing
|
Yet, because of numerous changes to our game data structure, providing means of backwards compatibility is not feasible. The versioning feature is rarely used.
|
||||||
means of backwards compatibility is not feasible. The versioning feature
|
|
||||||
is rarely used.
|
|
||||||
|
|
||||||
Sample:
|
Sample:
|
||||||
|
|
||||||
@@ -171,51 +130,33 @@ struct DLL_LINKAGE Rumor
|
|||||||
|
|
||||||
### Common information
|
### Common information
|
||||||
|
|
||||||
Serializer classes provide iostream-like interface with operator\<\< for
|
Serializer classes provide iostream-like interface with operator `<<` for serialization and operator `>>` for deserialization. Serializer upon creation will retrieve/store some metadata (version number, endianess), so even if no object is actually serialized, some data will be passed.
|
||||||
serialization and operator\>\> for deserialization. Serializer upon
|
|
||||||
creation will retrieve/store some metadata (version number, endianess),
|
|
||||||
so even if no object is actually serialized, some data will be passed.
|
|
||||||
|
|
||||||
### Serialization to file
|
### Serialization to file
|
||||||
|
|
||||||
CLoadFile/CSaveFile classes allow to read data to file and store data to
|
CLoadFile/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.
|
||||||
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.
|
|
||||||
|
|
||||||
### Networking
|
### Networking
|
||||||
|
|
||||||
CConnection class provides support for sending data structures over
|
CConnection class provides support for sending data structures over TCP/IP protocol. It provides 3 constructors:
|
||||||
TCP/IP protocol. It provides 3 constructors: 1) connect to given
|
1. connect to given hostname at given port (host must be accepting connection)
|
||||||
hostname at given port (host must be accepting connection) 2) accept
|
2. accept connection (takes boost.asio acceptor and io_service)
|
||||||
connection (takes boost.asio acceptor and io_service) 3) adapt
|
3. adapt boost.asio socket with already established connection
|
||||||
boost.asio socket with already established connection
|
|
||||||
|
|
||||||
All three constructors take as the last parameter the name that will be
|
All three constructors take as the last parameter the name that will be used to identify the peer.
|
||||||
used to identify the peer.
|
|
||||||
|
|
||||||
## Additional features
|
## Additional features
|
||||||
|
|
||||||
Here is the list of additional custom features serialzier provides. Most
|
Here is the list of additional custom features serialzier provides. Most of them can be turned on and off.
|
||||||
of them can be turned on and off.
|
|
||||||
|
|
||||||
- [#Polymorphic serialization](#Polymorphic_serialization "wikilink")
|
- [#Polymorphic serialization](#Polymorphic_serialization "wikilink") — no flag to control it, turned on by calls to registerType.
|
||||||
— no flag to control it, turned on by calls to registerType.
|
- [#Vectorized list member serialization](#Vectorized_list_member_serialization "wikilink") — enabled by smartVectorMembersSerialization flag.
|
||||||
- [#Vectorized list member
|
- [#Stack instance serialization](#Stack_instance_serialization "wikilink") — enabled by sendStackInstanceByIds flag.
|
||||||
serialization](#Vectorized_list_member_serialization "wikilink") —
|
- [#Smart pointer serialization](#Smart_pointer_serialization "wikilink") — enabled by smartPointerSerialization flag.
|
||||||
enabled by smartVectorMembersSerialization flag.
|
|
||||||
- [#Stack instance
|
|
||||||
serialization](#Stack_instance_serialization "wikilink") — enabled
|
|
||||||
by sendStackInstanceByIds flag.
|
|
||||||
- [#Smart pointer
|
|
||||||
serialization](#Smart_pointer_serialization "wikilink") — enabled by
|
|
||||||
smartPointerSerialization flag.
|
|
||||||
|
|
||||||
### Polymorphic serialization
|
### Polymorphic serialization
|
||||||
|
|
||||||
Serializer is to recognize the true type of object under the pointer if
|
Serializer is to recognize the true type of object under the pointer if classes of that hierarchy were previously registered.
|
||||||
classes of that hierarchy were previously registered.
|
|
||||||
|
|
||||||
This means that following will work
|
This means that following will work
|
||||||
|
|
||||||
@@ -230,19 +171,13 @@ CLoadFile input("test.dat");
|
|||||||
input >> basePtr; //a new Derived object will be put under the pointer
|
input >> basePtr; //a new Derived object will be put under the pointer
|
||||||
```
|
```
|
||||||
|
|
||||||
Class hierarchies that are now registered to benefit from this feature
|
Class 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.
|
||||||
are mostly adventure map object (CGObjectInstance) and network packs
|
|
||||||
(CPack). See the RegisterTypes.h file for the full list.
|
|
||||||
|
|
||||||
It is crucial that classes are registered in the same order in the both
|
It is crucial that classes are registered in the same order in the both serializers (storing and loading).
|
||||||
serializers (storing and loading).
|
|
||||||
|
|
||||||
### Vectorized list member serialization
|
### Vectorized list member serialization
|
||||||
|
|
||||||
Both client and server store their own copies of game state and VLC
|
Both 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.
|
||||||
(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.
|
|
||||||
|
|
||||||
The vectorised game objects are:
|
The vectorised game objects are:
|
||||||
|
|
||||||
@@ -253,16 +188,11 @@ The vectorised game objects are:
|
|||||||
`CArtifactInstance`
|
`CArtifactInstance`
|
||||||
`CQuest`
|
`CQuest`
|
||||||
|
|
||||||
For this to work, serializer needs an access to gamestate library
|
For this to work, serializer needs an access to gamestate library classes. This is done by calling a method `CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib)`.
|
||||||
classes. This is done by calling a method
|
|
||||||
`CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib)`.
|
|
||||||
|
|
||||||
When the game ends (or gamestate pointer is invaldiated for another
|
When the game ends (or gamestate pointer is invaldiated for another reason) this feature needs to be turned off by toggling its flag.
|
||||||
reason) this feature needs to be turned off by toggling its flag.
|
|
||||||
|
|
||||||
When vectorized member serialization is turned on, serializing pointer
|
When vectorized member serialization is turned on, serializing pointer to such object denotes not sending an object itself but rather its identity. For example:
|
||||||
to such object denotes not sending an object itself but rather its
|
|
||||||
identity. For example:
|
|
||||||
|
|
||||||
``` cpp
|
``` cpp
|
||||||
//Server code
|
//Server code
|
||||||
@@ -297,30 +227,19 @@ This feature makes sense only for server-client network communication.
|
|||||||
|
|
||||||
### Stack instance serialization
|
### Stack instance serialization
|
||||||
|
|
||||||
This feature works very much like the vectorised object serialization.
|
This 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.
|
||||||
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.
|
|
||||||
|
|
||||||
For this to work, obviously, both sides of the connection need to have
|
For this to work, obviously, both sides of the connection need to have exactly the same copies of an armed object and its stacks.
|
||||||
exactly the same copies of an armed object and its stacks.
|
|
||||||
|
|
||||||
This feature depends on vectorised member serialization being turned on.
|
This feature depends on vectorised member serialization being turned on. (Sending owning object by id.)
|
||||||
(Sending owning object by id.)
|
|
||||||
|
|
||||||
### Smart pointer serialization
|
### Smart pointer serialization
|
||||||
|
|
||||||
Note: name is unfortunate, this feature is not about smart pointers
|
Note: 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.
|
||||||
(like shared-ptr and unique_ptr). It is for raw C-style pointers, that
|
|
||||||
happen to point to the same object.
|
|
||||||
|
|
||||||
This feature makes it that multiple pointers pointing to the same object
|
This feature makes it that multiple pointers pointing to the same object are not stored twice.
|
||||||
are not stored twice.
|
|
||||||
|
|
||||||
Each time a pointer is stored, a unique id is given to it. If the same
|
Each 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 — serializer just stores a reference to the id.
|
||||||
pointer is stored a second time, its contents is not serialized —
|
|
||||||
serializer just stores a reference to the id.
|
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
@@ -342,11 +261,6 @@ Foo *loadedA, *loadedB;
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The feature recognizes pointers by addresses. Therefore it allows mixing
|
The 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).
|
||||||
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).
|
|
||||||
|
|
||||||
Pointer cycles are properly handled/
|
Pointer cycles are properly handled. This feature makes sense for savegames and is turned on for them.
|
||||||
|
|
||||||
This feature makes sense for savegames and is turned on for them.
|
|
@@ -1,10 +1,8 @@
|
|||||||
This page hold important information about project infrastructure for
|
< [Documentation](../Readme.md) / Project Infrastructure
|
||||||
current and future contributors. At moment it's all maintained by me
|
|
||||||
(SXX), but following information will be useful if someone going to
|
|
||||||
replace me in future.
|
|
||||||
|
|
||||||
You can also check [detailed information on server
|
This page hold important information about project infrastructure for current and future contributors. At moment it's all maintained by me (SXX), but following information will be useful if someone going to replace me in future.
|
||||||
configuration](Project_servers_configuration "wikilink").
|
|
||||||
|
You can also check [detailed information on server configuration](Project_servers_configuration "wikilink").
|
||||||
|
|
||||||
## Services and accounts
|
## Services and accounts
|
||||||
|
|
||||||
|
@@ -1,3 +1,6 @@
|
|||||||
|
< [Documentation](../Readme.md) / Project Servers Configuration
|
||||||
|
|
||||||
|
|
||||||
This page dedicated to explain specific configurations of our servers for anyone who might need to improve it in future. Check [project infrastructure](project_infrastructure "wikilink") page for services and accounts overview.
|
This page dedicated to explain specific configurations of our servers for anyone who might need to improve it in future. Check [project infrastructure](project_infrastructure "wikilink") page for services and accounts overview.
|
||||||
|
|
||||||
## Droplet configuration
|
## Droplet configuration
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
< [Documentation](../Readme.md) / Release Process
|
||||||
|
|
||||||
## Branches
|
## Branches
|
||||||
Our branching strategy is very similar to GitFlow
|
Our branching strategy is very similar to GitFlow
|
||||||
* `master` branch has release commits. One commit - one release. Each release commit should be tagged with version `maj.min.patch`
|
* `master` branch has release commits. One commit - one release. Each release commit should be tagged with version `maj.min.patch`
|
||||||
@@ -11,7 +13,7 @@ Assuming that all features planned to be released are implemented in `develop` b
|
|||||||
Should be done several weeks before planned release date
|
Should be done several weeks before planned release date
|
||||||
|
|
||||||
- Create [milestone](https://github.com/vcmi/vcmi/milestones) named `Release 1.x`
|
- Create [milestone](https://github.com/vcmi/vcmi/milestones) named `Release 1.x`
|
||||||
- - Specify this milestone for all regression bugs and major bugs related to new functionality
|
- Specify new milestone for all regression bugs and major bugs related to new functionality
|
||||||
- Create `beta` branch from `develop`
|
- Create `beta` branch from `develop`
|
||||||
- Bump vcmi version on `develop` branch
|
- Bump vcmi version on `develop` branch
|
||||||
- Bump version for linux on `develop` branch
|
- Bump version for linux on `develop` branch
|
||||||
@@ -35,7 +37,6 @@ Should be done on release date
|
|||||||
- Check that artifacts for all platforms are available on `master` branch
|
- Check that artifacts for all platforms are available on `master` branch
|
||||||
- Trigger builds for new release on Ubuntu PPA
|
- Trigger builds for new release on Ubuntu PPA
|
||||||
- Attach build artifacts for all platforms to release page
|
- Attach build artifacts for all platforms to release page
|
||||||
- - Android build should be prepared manually from custom branch (master)
|
|
||||||
- Merge prepared pull requests
|
- Merge prepared pull requests
|
||||||
- Publish release page
|
- Publish release page
|
||||||
|
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
< [Documentation](../Readme.md) / Ubuntu PPA
|
||||||
|
|
||||||
## Main links
|
## Main links
|
||||||
- [Team](https://launchpad.net/~vcmi)
|
- [Team](https://launchpad.net/~vcmi)
|
||||||
- [Project](https://launchpad.net/vcmi)
|
- [Project](https://launchpad.net/vcmi)
|
||||||
@@ -10,6 +12,7 @@
|
|||||||
- - [Daily PPA](https://launchpad.net/~vcmi/+archive/ubuntu/vcmi-latest)
|
- - [Daily PPA](https://launchpad.net/~vcmi/+archive/ubuntu/vcmi-latest)
|
||||||
|
|
||||||
## Automatic daily builds process
|
## Automatic daily builds process
|
||||||
|
|
||||||
### Code import
|
### Code import
|
||||||
- Launchpad performs regular (once per few hours) clone of our git repository.
|
- Launchpad performs regular (once per few hours) clone of our git repository.
|
||||||
- This process can be observed on [Sources](https://code.launchpad.net/~vcmi/vcmi/+git/vcmi) page.
|
- This process can be observed on [Sources](https://code.launchpad.net/~vcmi/vcmi/+git/vcmi) page.
|
||||||
|
@@ -278,7 +278,7 @@ Does not grant spells banned in map options.
|
|||||||
|
|
||||||
### GENERATE_RESOURCE
|
### GENERATE_RESOURCE
|
||||||
|
|
||||||
- subtype - [resource](resource "wikilink") type
|
- subtype - resource
|
||||||
- val - daily income
|
- val - daily income
|
||||||
|
|
||||||
### CREATURE_GROWTH
|
### CREATURE_GROWTH
|
||||||
|
@@ -1,8 +1,5 @@
|
|||||||
< [Documentation](../../Readme.md) / [Modding](../Readme.md) / [Map Object Format](../Map_Object_Format.md) / Creature Bank
|
< [Documentation](../../Readme.md) / [Modding](../Readme.md) / [Map Object Format](../Map_Object_Format.md) / Creature Bank
|
||||||
|
|
||||||
This is description of fields for creature banks, part of [Object
|
|
||||||
Format](Object_Format "wikilink")
|
|
||||||
|
|
||||||
``` javascript
|
``` javascript
|
||||||
{
|
{
|
||||||
/// List of levels of this bank. On map loading, one of them will be randomly assigned to bank.
|
/// List of levels of this bank. On map loading, one of them will be randomly assigned to bank.
|
||||||
|
@@ -1,8 +1,5 @@
|
|||||||
< [Documentation](../../Readme.md) / [Modding](../Readme.md) / [Map Object Format](../Map_Object_Format.md) / Dwelling
|
< [Documentation](../../Readme.md) / [Modding](../Readme.md) / [Map Object Format](../Map_Object_Format.md) / Dwelling
|
||||||
|
|
||||||
This is description of fields for creature banks, part of [Object
|
|
||||||
Format](Object_Format "wikilink")
|
|
||||||
|
|
||||||
``` javascript
|
``` javascript
|
||||||
{
|
{
|
||||||
/// List of creatures in this bank. Each list represents one "level" of bank
|
/// List of creatures in this bank. Each list represents one "level" of bank
|
||||||
|
Reference in New Issue
Block a user