1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Imported all data from website wiki

This commit is contained in:
Ivan Savenko 2023-08-13 00:17:38 +03:00
parent 6ac0dabcab
commit 243094b1ea
36 changed files with 5242 additions and 0 deletions

View File

@ -0,0 +1,62 @@
## General
#### What to expect working in VCMI?
Most of original game except multiplayer. Everything else is better to
report on our [bugtracker](http://bugs.vcmi.eu).
#### Can I play VCMI on my Android device?
Read this: <http://forum.vcmi.eu/viewtopic.php?t=614>
#### Do I need to install WoG to play VCMI?
No. VCMI has it's own port of WoG mod available from Launcher. We
recommend to install VCMI over fresh SoD / Complete versions.
#### What does "VCMI" stand for?
VCMI is an acronym of the [Quenya](https://en.wikipedia.org/wiki/Quenya)
phrase "Vinyar Callor Meletya Ingole", meaning "New Heroes of Might and
Magic". ([Source](https://forum.vcmi.eu/t/what-vcmi-stands-for/297/4))
## Game options
#### How can I change screen resolution?
Start any scenario, open System Options dialog and click "High" button.
In case only 800x600 is available, close VCMI, download this
[file](https://www.dropbox.com/sh/fwor43x5xrgzx6q/AABpTFqGK7Q9almbyr3hp9jma/mods/vcmi.zip)
which contains the “bonusIcons” and “extraResolutions” repertories.
Unzip, and place them in XXX (Windows), YYY (Android), ZZZ (Mac) or
~/.local/share/vcmi/Mods (Linux). Then start any scenario, open System
Options dialog and voilà, other resolutions than 800x600 are availables.
Note that you need to restart VCMI for the change to take effect.
#### How to turn off creature queue panel in battles?
Hotkey to switch this panel is "Q"
#### Can I turn off some WoG features that I don't like?
Yes. Take a look on config/defaultMods.json file and edit it to your
liking.
Note to Linux users: this file can be found in vcmi data directory (run
vcmiclient -v to see path). It can be copied into ~/.vcmi/config/ to
avoid editing file usually owned by root.
## Mods
#### Is it possible to add town X to vcmi?
This depends on town authors or anyone else willing to port it to vcmi.
Aim of VCMI is to provide *support* for such features.
#### Where can I find mods for VCMI?
Check
[Modding_guidelines#For_players](Modding_guidelines#For_players "wikilink")
page

79
docs/Main Page.md Normal file
View File

@ -0,0 +1,79 @@
# Welcome to VCMI Project Wiki
[VCMI](VCMI "wikilink") is an open-source project aiming to reimplement
HMM3:WoG and SoD game engines, giving it new and extended possibilities.
## Latest release
As of 28th of April 2023, we released [VCMI
1.2.1](https://github.com/vcmi/vcmi/releases/tag/1.2.1). Now we plan to
have releases 3-4 times per year. Daily builds are still available at
[builds.vcmi.download](https://builds.vcmi.download/branch/develop/) but
they are not guaranteed to be stable. So we encourage everybody to use
them and report found bugs so that we can fix them.
Loading saves made with different version of VCMI is usually **not**
supported, so you may want to finish your ongoing games before
updating.
Please see corresponding "installation on" articles for details for your
platform.
## Documentation and guidelines for users
- [ General information about VCMI Project](VCMI "wikilink")
- [Frequently asked questions](Frequently_asked_questions "wikilink")
- [Engine features](Engine_features "wikilink")
- [Game mechanics](Game_mechanics "wikilink")
- [Bug reporting guidelines](Bug_reporting_guidelines "wikilink")
- [Mod list](Mod_list "wikilink")
- [Cheat codes](Cheat_codes "wikilink")
- [Installation](Installation "wikilink") guides:
- [Windows](Installation_on_Windows "wikilink")
- [macOS](Installation_on_macOS "wikilink")
- [Linux](Installation_on_Linux "wikilink")
- [Android](Installation_on_Android "wikilink")
- [iOS](Installation_on_iOS "wikilink")
## Documentation and guidelines for modders
- [Modding guidelines](Modding_guidelines "wikilink")
- [Mods repository](Mods_repository "wikilink")
- Formats:
- [Mod file Format](Mod_file_Format "wikilink")
- [Town Format](Town_Format "wikilink")
- [Hero Classes Format](Hero_Classes_Format "wikilink")
- [Hero Format](Hero_Format "wikilink")
- [Creature Format](Creature_Format "wikilink")
- [Artifact Format](Artifact_Format "wikilink")
- [Animation Format](Animation_Format "wikilink")
- [Bonus Format](Bonus_Format "wikilink")
- [Object Format](Object_Format "wikilink")
- [Spell Format](Spell_Format "wikilink")
- [Skill Format](Skill_Format "wikilink")
## Documentation and guidelines for developers
- How to build using CMake:
- [Linux](How_to_build_VCMI_(Linux) "wikilink")
- [Linux/MinGW (for
Windows)](How_to_build_VCMI_(Linux/MinGW) "wikilink")
- [macOS](How_to_build_VCMI_(macOS) "wikilink")
- [Windows](How_to_build_VCMI_(Windows/Vcpkg) "wikilink")
- [iOS](How_to_build_VCMI_(iOS) "wikilink")
- [ Android](How_to_build_VCMI_(Android) "wikilink")
- Unsupported build instructions:
- [Windows/MSVS (Visual Studio
2015)](How_to_build_VCMI_(Windows/Visual_Studio_2015) "wikilink")
- [Coding guidelines](Coding_guidelines "wikilink")
- [Code structure](Code_structure "wikilink")
- [Logging API](Logging_API "wikilink")
- Development environment guides:
- [Development with Qt
Creator](Development_with_Qt_Creator "wikilink")
## VCMI Places
- [Website](https://vcmi.eu/)
- [Forum](https://forum.vcmi.eu/)
- [Bugtracker](https://bugs.vcmi.eu/)
- [Slack invite page](https://slack.vcmi.eu/)
- [GitHub repository](https://github.com/vcmi/vcmi)

164
docs/TODO list.md Normal file
View File

@ -0,0 +1,164 @@
The list of all essential, optional and requested features alongside
with the team members interested in them.
# Heroes III
[Missing features at
Trello](https://trello.com/b/68e5rAAl/vcmi-missing-features-only)
### Most important bugfixes
- daily build contains broken vcmi essential package (ticket is for
linux but same problem on Windows also)
<https://bugs.vcmi.eu/view.php?id=2986> - questionable
- desync in multiplayer cross-platform
<https://bugs.vcmi.eu/view.php?id=2583>
### Establish release process
In January 2021 there was a proposition on Slack to make 3 branches:
develop, beta and stable. develop is where people make their changes
when they are ready, people can test it but its not for normal players
beta could be for players who agree to be testers. stable could be for
players who want stable version. Hovewer there were no decision made
### HD mod/quality of life
contact MikeLodz if you have questions about this section
These are necessary, as although they werent present back in 1999, they
are standard today.
- quick transfer of artifacts and armies between heroes, started here
<https://github.com/vcmi/vcmi/pull/636>
- adventure map: movements points preview and cost
- move artifacts between visiting town and garrison heroes
- hero list preview on the "start map" screen.
etc see here for full list of enhancements:
<https://sites.google.com/site/heroes3hd/eng/description/extended-ui>
- some walking creatures need to move faster during battles, as its a
complete waste of time (we need a so called "turbo" mode)
<!-- -->
- this one not sure if its a bug or missing hd mod feature: it should
be possible to preview hero screen when choosing a skill on levelup.
### Hota rebalances?
contact MikeLodz about this section
- what is our stance on Hota rebalances ? we should discuss them at
least and decide which to adopt, and which to ignore \*
### Random map generator
Dydzio said about it on Slack:
`finish `[`https://github.com/dydzio0614/vcmi/tree/rmgtemplates`](https://github.com/dydzio0614/vcmi/tree/rmgtemplates)` (random map generator template pick,`
better selection lists for random map generator template - two versions
(two bitmaps provided) also one more thing - for random map template
pick my vision was to create more generic select list component and make
town portal select component derive from it
### [Adventure AI](Adventure_AI "wikilink")
- More functionality
- Adventure map spells support
- Survival instinct - AI defending towns, escaping etc.
- Handling of all adventure map objects
- Evaluating game objects
- priority for visited objects over others sharing similiar
function
- Support for new objects possible to add via mods - use abstract
interface to determine rewards etc.
- Advanced strategy
- Battle preparation (constructing suitable army & strategy)
- Expert system for Bonuses
([Warmonger](http://forum.vcmi.eu/profile.php?mode=viewprofile&u=130))
### Main menu
- Hall of Fame
# Modding
- Possibility for creatures to cast arbitrary spells, as in H4/H5
### Scripting system
- Language support
- Synchronising scripts in multiplayer
### Mod system
- Adding new content
- Adventure map objects
- Battlefields
[Forum
thread](http://forum.vcmi.eu/viewtopic.php?t=471&postdays=0&postorder=asc&start=0)
### Wog features
- Mithril
- ERM handling (Tow, Tow Dragon)
# New features
- Support for other languages files
([Ivan](http://forum.vcmi.eu/profile.php?mode=viewprofile&u=336))
- Support for multiple map levels
- [New map editor](http://forum.vcmi.eu/viewtopic.php?t=1139)
- Installer
### Online game
- Simultaneous turns
- Spectator mode
- Dedicated server mode
- [Replays](http://forum.vcmi.eu/viewtopic.php?t=264)
### Other platforms
- Linux (<span style="color:green">**Supported**</span>, [forum
thread](http://forum.vcmi.eu/viewtopic.php?t=112))
- Mac OS (<span style="color:green">**Supported**</span>, [forum
thread](http://forum.vcmi.eu/viewtopic.php?t=439))
- Android (<span style="color:green">**Supported**</span>, [forum
thread](http://forum.vcmi.eu/viewtopic.php?t=850))
- iOS (<span style="color:green">**Supported**</span>, [forum
thread](https://forum.vcmi.eu/t/ios-port/820))
- Haiku (<span style="color:yellow">**Status unknown**</span>, [forum
thread](http://forum.vcmi.eu/viewtopic.php?t=310))
- Maemo (<span style="color:yellow">**Status unknown**</span>, [forum
thread](http://forum.vcmi.eu/viewtopic.php?t=328))
- FreeBSD (<span style="color:yellow">**Status unknown**</span>)
# New graphics
### New menus project and graphics
- New stack experience menu ([forum
thread](http://forum.vcmi.eu/viewtopic.php?t=376&start=0))
- New stack artifact dialog
### Improved support for high resolutions
- Auto-adjust resolution
- Moddable menus
### New players
- More player color graphics
- New menus
### 32-bit graphics
### 800 x 480 resolution
Experimental version posted on our forum is available
[here](http://forum.vcmi.eu/viewtopic.php?t=273).

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

View File

@ -0,0 +1,140 @@
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.
Here is a brief sketch of the system (black arrows indicate the
direction of inheritance and red arrows the direction of propagation):
<figure>
<img src="Bonus_system.png" title="Bonus_system.png" />
<figcaption>Bonus_system.png</figcaption>
</figure>
## Propagation and inheritance
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:
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.
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
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.
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
- Propagation is done by copying bonuses to the target nodes. This
happens when bonuses are added.
- Inheritance is done on-the-fly when needed, by traversing the black
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
There are two basic types of operations that can be performed on the
graph:
### Adding a new node
When node is attached to a new black parent [1], the propagation system
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.
### Deleting an existing node
Analogically to the adding a new node, just remove propagated bonuses
instead of adding them. Then update the hierarchy.
E.g. when a hero removes an artifact, the hero (which became a child of
the artifact when equipping it) is removed from it.
Note that only *propagated* bonuses need to be handled when nodes are
added or removed. *Inheritance* is done on-the-fly and thus automatic.
## Limiters
If multiple limiters are specified for a bonus, a child inherits the
bonus only if all limiters say that it should.
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.
## Propagators
## Updaters
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.
The following example shows an artifact providing a bonus based on the
level of the hero that wears it:
` "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" : [`
` {`
` "limiters" : [`
` {`
` "parameters" : [ "gnoll", true ],`
` "type" : "CREATURE_TYPE_LIMITER"`
` }`
` ],`
` "subtype" : "primSkill.attack",`
` "type" : "PRIMARY_SKILL",`
` "val" : 2,`
` "updater" : "TIMES_HERO_LEVEL"`
` }`
` ]`
` }`
## Calculating the total value of a bonus
- [List of bonus value types](List_of_bonus_value_types "wikilink")
## Automatic generation of bonus description
TBD
# Notes
<references/>
[1] the only possibility -\> adding parent is the same as adding a child
to it

View File

@ -0,0 +1,213 @@
The code of VCMI is divided into several main parts: client, server, lib
and AIs, each one in a separate binary file.
# The big picture
<figure>
<img src="Architektura.png" title="Architektura.png" />
<figcaption>Architektura.png</figcaption>
</figure>
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.
During the game, we have one (and only one) server and one or more (one
for each player computer) clients.
Important: State of the game and its mechanics are synchronized between
clients and server. All changes to the game state or mechanics must be
done by server which will send appropriate notices to clients.
## Game state
It's basically CGameState class object and everything that's accessible
from it: map (with objects), player statuses, game options, etc.
## Bonus system
One of the more important pieces of VCMI is the [bonus
system](bonus_system "wikilink"). It's described in a separate article.
## Configuration
Most of VCMI configuration files uses Json format and located in
"config" directory
### [Json parser and writer](Json_parser_and_writer "wikilink")
# Client
## Main purposes of client
[Client](Client "wikilink") is responsible for:
- displaying state of game to human player
- capturing player's actions and sending requests to server
- displaying changes in state of game indicated by server
## Rendering of graphics
Rendering of graphics relies heavily on SDL. Currently we do not have
any wrapper for SDL internal structures and most of rendering is about
blitting surfaces using SDL_BlitSurface. We have a few function that
make rendering easier or make specific parts of rendering (like printing
text). They are places in client/SDL_Extensions and client/SDL_Framerate
(the second one contains code responsible for keeping appropriate
framerate, it should work more smart than just SDL_Delay(miliseconds)).
In rendering, Interface object system is quite helpful. Its base is
CIntObject class that is basically a base class for our library of GUI
components and other objects.
### Video player
Located in client/VideoHandler.cpp/.h, have several platform-specific
versions:
- For 32-bit Windows - using original 32-bit libraries (binkw32.dll,
smackw32.dll)
- For \*nix systems - using ffmpeg libraries.
- Empty player for 64-bit Windows
### [Primitive controls](Primitive_controls "wikilink")
## [Adventure map interface](Adventure_map_interface "wikilink")
TBD
## [Town interface](Town_interface "wikilink")
TBD
## [Battle interface](Battle_interface "wikilink")
# Server
## Main purposes of server
[Server](Server "wikilink") is responsible for:
- maintaining state of the game
- handling requests from all clients participating in game
- informing all clients about changes in state of the game that are
visible to them
# Lib
## Main purposes of lib
VCMI_Lib is a library that contains code common to server and client, so
we avoid it's duplication. Important: the library code is common for
client and server and used by them, but the library instance (in
opposition to the library as file) is not shared by them! Both client
and server create their own "copies" of lib with all its class
instances.
iOS platform pioneered single process build, where server is a static
library and not a dedicated executable. For that to work, the lib had to
be wrapped into special namespace that is defined by client and server
targets on iOS, so that single process is able to contain 2 versions of
the library. To make it more convenient, a few macros were introduced
that can be found in
[Global.h](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:
- handling most of Heroes III files (.lod, .txt setting files)
- storing information common to server and client like state of the
game
- managing armies, buildings, artifacts, spells, bonuses and other
game objects
- handling general game mechanics and related actions (only adventure
map objects; it's an unwanted remnant of past development - all game
mechanics should be handled by the server)
- networking and serialization
### [Serialization](Serialization "wikilink")
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).
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
details.
### Wrapped namespace examples
#### Inside the lib
Both header and implementation of a new class inside the lib should have
the following structure:
`<includes>`
`VCMI_LIB_NAMESPACE_BEGIN`
`<code>`
`VCMI_LIB_NAMESPACE_END`
Example:
[header](https://github.com/vcmi/vcmi/blob/develop/lib/CBuildingHandler.h)
and
[implementation](https://github.com/vcmi/vcmi/blob/develop/lib/CBuildingHandler.cpp)
#### Headers outside the lib
Forward declarations of the lib in headers of other parts of the project
need to be wrapped in the macros:
`<includes>`
`VCMI_LIB_NAMESPACE_BEGIN`
`<lib forward declarations>`
`VCMI_LIB_NAMESPACE_END`
`<other forward declarations>`
`<classes>`
Example:
<https://github.com/vcmi/vcmi/blob/develop/server/CGameHandler.h>
#### New project part
If you're creating new project part, place `VCMI_LIB_USING_NAMESPACE` in
its `StdInc.h` to be able to use lib classes without explicit namespace
in implementation files. Example:
<https://github.com/vcmi/vcmi/blob/develop/launcher/StdInc.h>
# [Artificial Intelligence](Artificial_Intelligence "wikilink") (AI)
## [StupidAI](StupidAI "wikilink")
Stupid AI is recent and used battle AI.
## [Adventure AI](Adventure_AI "wikilink")
VCAI module is currently developed agent-based system driven by goals
and heroes.
## [Programming challenge](Programming_challenge "wikilink")
## [Fuzzy logic](Fuzzy_logic "wikilink")
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.
# [Utilities](Utilities "wikilink")
## [Launcher](Launcher "wikilink")
## [Duels](Duels "wikilink")
[Mod system proposal](Mod_system_proposal "wikilink")
## [ERM parser](ERM_parser "wikilink")

View File

@ -0,0 +1,972 @@
## C++ Standard
VCMI implementation bases on C++14 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.
Any compiler supporting C++14 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).
## Style Guidelines
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.
### Indentation
Use tabs for indentation. If you are modifying someone else's code, try
to keep the coding style similar.
### Where to put braces
Inside a code block put the opening brace on the next line after the
current statement:
Good:
``` cpp
if(a)
{
code();
code();
}
```
Bad:
``` cpp
if(a) {
code();
code();
}
```
Avoid using unnecessary open/close braces, vertical space is usually
limited:
Good:
``` cpp
if(a)
code();
```
Bad:
``` cpp
if(a) {
code();
}
```
Unless there are either multiple hierarchical conditions being used or
that the condition cannot fit into a single line.
Good:
``` cpp
if(a)
{
if(b)
code();
}
```
Bad:
``` cpp
if(a)
if(b)
code();
```
If there are brackets inside the body, outside brackets are required.
Good:
``` cpp
if(a)
{
for(auto elem : list)
{
code();
}
}
```
Bad:
``` cpp
if(a)
for(auto elem : list)
{
code();
}
```
If "else" branch has brackets then "if" should also have brackets even
if it is one line.
Good:
``` cpp
if(a)
{
code();
}
else
{
for(auto elem : list)
{
code();
}
}
```
Bad:
``` cpp
if(a)
code();
else
{
for(auto elem : list)
{
code();
}
}
```
If you intentionally want to avoid usage of "else if" and keep if body
indent make sure to use braces.
Good:
``` cpp
if(a)
{
code();
}
else
{
if(b)
code();
}
```
Bad:
``` cpp
if(a)
code();
else
if(b)
code();
```
When defining a method, use a new line for the brace, like this:
Good:
``` cpp
void method()
{
}
```
Bad:
``` cpp
void Method() {
}
```
### Use whitespace for clarity
Use white space in expressions liberally, except in the presence of
parenthesis.
**Good:**
``` cpp
if(a + 5 > method(blah('a') + 4))
foo += 24;
```
**Bad:**
``` cpp
if(a+5>method(blah('a')+4))
foo+=24;
```
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.
### Where to put spaces
Use a space before and after the address or pointer character in a
pointer declaration.
Good:
``` cpp
CIntObject * images[100];
```
Bad:
``` cpp
CIntObject* images[100]; or
CIntObject *images[100];
```
Do not use spaces before parentheses.
Good:
``` cpp
if(a)
code();
```
Bad:
``` cpp
if (a)
code();
```
Do not use extra spaces around conditions inside parentheses.
Good:
``` cpp
if(a && b)
code();
if(a && (b || c))
code();
```
Bad:
``` cpp
if( a && b )
code();
if(a && ( b || c ))
code();
```
Do not use more than one space between operators.
Good:
``` cpp
if((a && b) || (c + 1 == d))
code();
```
Bad:
``` cpp
if((a && b) || (c + 1 == d))
code();
if((a && b) || (c + 1 == d))
code();
```
### Where to use parentheses
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.
Good:
``` cpp
std::vector<int> v;
CGBoat btn = new CGBoat();
```
Bad:
``` cpp
std::vector<int> v(); // shouldn't compile anyway
CGBoat btn = new CGBoat;
```
Avoid overuse of parentheses:
Good:
``` cpp
if(a && (b + 1))
return c == d;
```
Bad:
``` cpp
if((a && (b + 1)))
return (c == d);
```
### Class declaration
Base class list must be on same line with class name.
``` cpp
class CClass : public CClassBaseOne, public CClassBaseOne
{
int id;
bool parameter;
public:
CClass();
~CClass();
};
```
When 'private:', 'public:' and other labels are not on the line after
opening brackets there must be a new line before them.
Good:
``` cpp
class CClass
{
int id;
public:
CClass();
};
```
Bad:
``` cpp
class CClass
{
int id;
public:
CClass();
};
```
Good:
``` cpp
class CClass
{
protected:
int id;
public:
CClass();
};
```
Bad:
``` cpp
class CClass
{
protected:
int id;
public:
CClass();
};
```
### Constructor base class and member initialization
Constructor member and base class initialization must be on new line,
indented with tab with leading colon.
``` cpp
CClass::CClass()
: CClassBaseOne(true, nullptr), id(0), bool parameters(false)
{
code();
}
```
### Switch statement
Switch statements have the case at the same indentation as the switch.
Good:
``` cpp
switch(alignment)
{
case EAlignment::EVIL:
do_that();
break;
case EAlignment::GOOD:
do_that();
break;
case EAlignment::NEUTRAL:
do_that();
break;
default:
do_that();
break;
}
```
Bad:
``` cpp
switch(alignment)
{
case EAlignment::EVIL:
do_that();
break;
default:
do_that();
break;
}
switch(alignment)
{
case EAlignment::EVIL:
do_that();
break;
default:
do_that();
break;
}
switch(alignment)
{
case EAlignment::EVIL:
{
do_that();
}
break;
default:
{
do_that();
}
break;
}
```
### Lambda expressions
Good:
``` cpp
auto lambda = [this, a, &b](int3 & tile, int index) -> bool
{
do_that();
};
```
Bad:
``` cpp
auto lambda = [this,a,&b](int3 & tile, int index)->bool{do_that();};
```
Empty parameter list is required even if function takes no arguments.
Good:
``` cpp
auto lambda = []()
{
do_that();
};
```
Bad:
``` cpp
auto lambda = []
{
do_that();
};
```
Do not use inline lambda expressions inside if-else, for and other
conditions.
Good:
``` cpp
auto lambda = []()
{
do_that();
};
if(lambda)
{
code();
}
```
Bad:
``` cpp
if([]()
{
do_that();
})
{
code();
}
```
Do not pass inline lambda expressions as parameter unless it's the last
parameter.
Good:
``` cpp
auto lambda = []()
{
do_that();
};
obj->someMethod(lambda, true);
```
Bad:
``` cpp
obj->someMethod([]()
{
do_that();
}, true);
```
Good:
``` cpp
obj->someMethod(true, []()
{
do_that();
});
```
### Serialization
Serialization of each element must be on it's own line since this make
debugging easier.
Good:
``` cpp
template <typename Handler> void serialize(Handler & h, const int version)
{
h & identifier;
h & description;
h & name;
h & dependencies;
}
```
Bad:
``` cpp
template <typename Handler> void serialize(Handler & h, const int version)
{
h & identifier & description & name & dependencies;
}
```
Save backward compatibility code is exception when extra brackets are
always useful.
Good:
``` cpp
template <typename Handler> void serialize(Handler & h, const int version)
{
h & identifier;
h & description;
if(version >= 123)
{
h & totalValue;
}
else if(!h.saving)
{
totalValue = 200;
}
h & name;
h & dependencies;
}
```
Bad:
``` cpp
template <typename Handler> void serialize(Handler & h, const int version)
{
h & identifier;
h & description;
if(version >= 123)
h & totalValue;
else if(!h.saving)
totalValue = 200;
h & name;
h & dependencies;
}
```
### File headers
For any new files, please paste the following info block at the very top
of the source file:
``` cpp
/*
* Name_of_File.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
```
The above notice have to be included both in header and source files
(.h/.cpp).
### Code order in files
For any header or source file code must be in following order:
1. Licensing information
2. pragma once preprocessor directive
3. include directives
4. Forward declarations
5. All other code
``` cpp
/*
* Name_of_File.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "Header.h"
class CGObjectInstance;
struct CPackForClient;
```
### Where and how to comment
If you comment on the same line with code there must be one single space
between code and slashes.
Good:
``` cpp
if(a)
{
code(); //Do something
}
else // Do something.
{
code(); // Do something.
}
```
Bad:
``` cpp
if(a)
{
code();//Do something
}
else // Do something.
{
code(); // TODO:
}
```
If you add single-line comment on own line slashes must have same indent
as code around:
Good:
``` cpp
// Do something
if(a)
{
//Do something
for(auto item : list)
code();
}
```
Bad:
``` cpp
// Do something
if(a)
{
//Do something
for(auto item : list)
code();
}
```
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**
Good:
``` cpp
bool isMyHeroAlive = a && b || (c + 1 > 15);
bool canMyHeroMove = myTurn && hero.movePoints > 0;
if(isMyHeroAlive && canMyHeroMove)
{
code();
}
```
Bad:
``` cpp
if((a && b || (c + 1 > 15)) //Check if hero still alive
&& myTurn && hero.movePoints > 0) //Check if hero can move
{
code();
}
```
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: ///.
``` cpp
/// Returns true if a debug/trace log message will be logged, false if not.
/// Useful if performance is important and concatenating the log message is a expensive task.
bool isDebugEnabled() const;
bool isTraceEnabled() const;
```
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.
If you need a more detailed description for a method you can use such
style:
``` cpp
/// <A short one line description>
///
/// <Longer description>
/// <May span multiple lines or paragraphs as needed>
///
/// @param Description of method's or function's input parameter
/// @param ...
/// @return Description of the return value
```
A good essay about writing comments:
[2](http://ardalis.com/when-to-comment-your-code)
### Casing
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.
### Line length
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.
### Warnings
Avoid use of #pragma to disable warnings. Compile at warning level 3.
Avoid commiting code with new warnings.
### File/directory naming
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.
Directories start with a lowercase letter and use the camel casing where
necessary.
### Logging
Outdated. There is separate entry for [Logging
API](Logging_API "wikilink")
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:
``` cpp
LOG_TRACE_PARAMS(logGlobal, "hero '%s', spellId '%d', pos '%s'.", hero, spellId, pos);
```
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:
`{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:
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
### Avoid code duplication
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)
### Do not use uncommon abbrevations
Do not use uncommon abbrevations for class, method, parameter and global
object names.
Bad:
``` cpp
CArt * getRandomArt(...)
class CIntObject
```
Good:
``` cpp
CArtifact * getRandomArtifact(...)
class CInterfaceObject
```
### Loop handling
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.
The loop counter should be of type int, unless you are sure you won't
need negative indices -- then use size_t.
### Include guards
Use #pragma once instead of the traditional #ifndef/#define/#endif
include guards.
### Pre compiled header file
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.
### Enumeration handling
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:
``` cpp
enum class EAlignment
{
GOOD,
EVIL,
NEUTRAL
};
namespace EAlignment
{
enum EAlignment
{
GOOD, EVIL, NEUTRAL
};
}
```
### Avoid senseless comments
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:
``` cpp
size_t getHeroesCount(); //gets count of heroes (surprise?)
```
### Class handling
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.
### Functions and interfaces
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.
Bad:
``` cpp
const std::vector<CGObjectInstance *> guardingCreatures(int3 pos) const;
```
Good:
``` cpp
std::vector<const CGObjectInstance *> guardingCreatures(int3 pos) const;
```
## Sources
[Mono project coding
guidelines](http://www.mono-project.com/Coding_Guidelines)

View File

@ -0,0 +1,49 @@
# Introduction to Qt Creator
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:
- Fast parser/indexer, stable.
- Almost no manual configuration when used with CMake. Project
configuration is read from CMake text files,
- 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
latest version from Qt website:
<https://www.qt.io/download-open-source/>
## Configuration
To open the project you have to click File -\> Open file or project...
-\> Select /path/to/vcmi/src/CMakeLists.txt.
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
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
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:
1\) Run vcmiclient (no debug mode), then attach server process to the
debugger
2\) Open two instances of QtCreator and debug vcmiserver and vcmiclient
separately(it works!)

View File

@ -0,0 +1,117 @@
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`.

View File

@ -0,0 +1,217 @@
# 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

View File

@ -0,0 +1,165 @@
**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.**

View File

@ -0,0 +1,258 @@
# 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)

View File

@ -0,0 +1,111 @@
## 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).

View File

@ -0,0 +1,170 @@
# 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

View File

@ -0,0 +1,201 @@
# Features
- A logger belongs to a "domain", this enables us to change log level
settings more selectively
- The log format can be customized
- The color of a log entry can be customized based on logger domain
and logger level
- Logger settings can be changed in the settings.json file
- No std::endl at the end of a log entry required
- Thread-safe
- Macros for tracing the application flow
- Provides stream-like and function-like logging
# Class diagram
<figure>
<img src="Logging_Class_Diagram.jpg"
title="Logging_Class_Diagram.jpg" />
<figcaption>Logging_Class_Diagram.jpg</figcaption>
</figure>
Some notes:
- 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.
- 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
## Setup settings.json
``` javascript
{
"logging" : {
"console" : {
"threshold" : "debug",
"colorMapping" : [
{
"domain" : "network",
"level" : "trace",
"color" : "magenta"
}
]
},
"loggers" : [
{
"domain" : "global",
"level" : "debug"
},
{
"domain" : "ai",
"level" : "trace"
}
]
}
}
```
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.
## Configuration
The following code shows how the logging system can be configured:
console = new CConsoleHandler;
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
preinitDLL(console); // Init filesystem
settings.init(); // Init settings
logConfig.configure(); // Now setup "real" logging system, overwrites default settings
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:
**Console**
Format: %m
Threshold: info
coloredOutputEnabled: true
colorMapping: trace -\> gray, debug -\> white, info -\> green, warn -\>
yellow, error -\> red
**File**
Format: %d %l %n \[%t\] - %m
**Loggers**
global -\> info
## How to get a logger
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:
CLogger * logger = CLogger::getLogger(CLoggerDomain("rmg"));
## Logging
Logging can be done via two ways, stream-like or function-like.
logGlobal->warnStream() << "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
line will be appended automatically.
The following list shows several log levels from the highest one to the
lowest one:
- 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)
- warn -\> for warnings, e.g. if sth. is wrong, but the program can
continue execution "normally"
- 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:
- default
- green
- red
- magenta
- yellow
- white
- gray
- teal
## How to trace execution
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.
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, ....
int movPoints;
// Do some stuff
// ...
TRACE_END_PARAMS(logGlobal, "movPoints '%i'", movPoints);
return movPoints;
}
# Concepts
## Domain
A domain is a specific part of the software. In VCMI there exist several
domains:
- network
- ai
- bonus
- network
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, level=info
network, level=not set, effective level=info
global, level=warn
network, level=trace, effective level=trace
global, level=debug
ai, level=not set, effective level=debug
ai.battle, level=trace, effective level=trace
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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -0,0 +1,352 @@
# Introduction
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).
VCMI uses binary format. The primitive types are simply copied from
memory, more complex structures are represented as a sequence of
primitives.
## Typical tasks
### Bumping a version number
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.
### Adding a new class
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")
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.
# How does it work
## Primitive types
They are simply stored in a binary form, as in memory. Compatibility is
ensued through the following means:
- VCMI uses internally types that have constant, defined size (like
si32 - has 32 bits on all platforms)
- serializer stores information about its endianess
It's not "really" portable, yet it works properly across all platforms
we currently support.
## Dependant types
### Pointers
Storing pointers mechanics can be and almost always is customized. See
[#Additional features](#Additional_features "wikilink").
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.
### Arrays
Serializing array is simply serializing all its elements.
## Standard library types
### STL Containers
First the container size is stored, then every single contained element.
Supported STL types include:
`vector`
`array`
`set`
`unordered_set`
`list`
`string`
`pair`
`map`
### Smart 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.
The list of supported data types from standard library:
`shared_ptr (partial!!!)`
`unique_ptr`
### Boost
Additionally, a few types for Boost are supported as well:
`variant`
`optional`
## User types
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.
Serializer provides an operator& that is internally expanded to \<\<
when serialziing or \>\> when deserializing.
Serializer provides a public bool field `saving`that set to true during
serialziation and to false for deserialziation.
Typically, serializing class involves serializing all its members (given
that they are serializable). Sample:
``` cpp
/// The rumor struct consists of a rumor name and text.
struct DLL_LINKAGE Rumor
{
std::string name;
std::string text;
template <typename Handler>
void serialize(Handler & h, const int version)
{
h & name & text;
}
};
```
## Backwards compatibility
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.
Yet, because of numerous changes to our game data structure, providing
means of backwards compatibility is not feasible. The versioning feature
is rarely used.
Sample:
``` cpp
/// The rumor struct consists of a rumor name and text.
struct DLL_LINKAGE Rumor
{
std::string name; //introduced in version 1065
std::string text;
template <typename Handler>
void serialize(Handler & h, const int version)
{
if(version >= 1065)
h & name;
else if(!h.saving) //when loading old savegame
name = "no name"; //set name to some default value [could be done in class constructor as well]
h & text;
}
};
```
## Serializer classes
### Common information
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 to file
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.
### Networking
CConnection class provides support for sending data structures over
TCP/IP protocol. It provides 3 constructors: 1) connect to given
hostname at given port (host must be accepting connection) 2) accept
connection (takes boost.asio acceptor and io_service) 3) adapt
boost.asio socket with already established connection
All three constructors take as the last parameter the name that will be
used to identify the peer.
## Additional features
Here is the list of additional custom features serialzier provides. Most
of them can be turned on and off.
- [#Polymorphic serialization](#Polymorphic_serialization "wikilink")
— no flag to control it, turned on by calls to registerType.
- [#Vectorized list member
serialization](#Vectorized_list_member_serialization "wikilink") —
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
Serializer is to recognize the true type of object under the pointer if
classes of that hierarchy were previously registered.
This means that following will work
``` cpp
Derived *d = new Derived();
Base *basePtr = d;
CSaveFile output("test.dat");
output << b;
//
Base *basePtr = nullptr;
CLoadFile input("test.dat");
input >> basePtr; //a new Derived object will be put under the pointer
```
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.
It is crucial that classes are registered in the same order in the both
serializers (storing and loading).
### Vectorized list member serialization
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.
The vectorised game objects are:
`CGObjectInstance`
`CGHeroInstance`
`CCreature`
`CArtifact`
`CArtifactInstance`
`CQuest`
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)`.
When the game ends (or gamestate pointer is invaldiated for another
reason) this feature needs to be turned off by toggling its flag.
When vectorized member serialization is turned on, serializing pointer
to such object denotes not sending an object itself but rather its
identity. For example:
``` cpp
//Server code
CCreature *someCreature = ...;
connection << someCreature;
```
the last line is equivalent to
``` cpp
connection << someCreature->idNumber;
```
//Client code
``` cpp
CCreature *someCreature = nullptr;
connection >> someCreature;
```
the last line is equivalent to
``` cpp
CreatureID id;
connection >> id;
someCreature = VLC->creh->creatures[id.getNum()];
```
Important: this means that the object state is not serialized.
This feature makes sense only for server-client network communication.
### Stack instance 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.
For this to work, obviously, both sides of the connection need to have
exactly the same copies of an armed object and its stacks.
This feature depends on vectorised member serialization being turned on.
(Sending owning object by id.)
### Smart pointer serialization
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.
This feature makes it that multiple pointers pointing to the same object
are not stored twice.
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.
For example:
``` cpp
Foo * a = new Foo();
Foo * b = b;
{
CSaveFile test("test.txt");
test << a << b;
}
Foo *loadedA, *loadedB;
{
CLoadFile test("test.txt");
test >> loadedA >> loadedB;
//now both pointers point to the same object
assert(loadedA == loadedB);
}
```
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).
Pointer cycles are properly handled/
This feature makes sense for savegames and is turned on for them.

View File

@ -0,0 +1,832 @@
The bonuses were grouped according to their original purpose. The bonus
system allows them to propagate freely betwen the nodes, however they
may not be recognized properly beyond the scope of original use.
# General-purpose bonuses
### NONE
### MORALE, LUCK
- val = value
### MAGIC_SCHOOL_SKILL
eg. for magic plains terrain and for magic school secondary skills
- subtype: school of magic (0 - all, 1 - air, 2 - fire, 4 - water, 8 -
earth)
- val - level
### NO_TYPE
### DARKNESS
- val = radius
# Hero bonuses
### MOVEMENT
Before 1.2: both water / land After 1.2: subtype 0 - sea, subtype 1 -
land
- val = number of movement points (100 points for a tile)
### LAND_MOVEMENT, SEA_MOVEMENT (before 1.2)
- val = number of movement points (100 points for a tile)
### WATER_WALKING
- subtype: 1 - without penalty, 2 - with penalty
### FLYING_MOVEMENT
- subtype: 1 - without penalty, 2 - with penalty
### NO_TERRAIN_PENALTY (since 0.98f)
Hero does not get movement penalty on certain terrain type (Nomads
ability).
- subtype - type of terrain
### PRIMARY_SKILL
- uses subtype to pick skill
- additional info if set: 1 - only melee, 2 - only distance
### SIGHT_RADIOUS (before 1.2)
Additional bonus to range of sight (Used for Scouting secondary skill)
- val = distance in tiles
### SIGHT_RADIUS (after 1.2)
Sight radius of a hero. Used for base radius + Scouting secondary skill
- val = distance in tiles
### MANA_REGENERATION
Before 1.2: points per turn apart from normal (1 + mysticism) After 1.2:
points per turn (used for artifacts, global 1 point/turn regeneration
and mysticism secondary skill)
### FULL_MANA_REGENERATION
all mana points are replenished every day
### NONEVIL_ALIGNMENT_MIX
good and neutral creatures can be mixed without morale penalty
### SECONDARY_SKILL_PREMY (before 1.2)
%
### SURRENDER_DISCOUNT
%
### IMPROVED_NECROMANCY
Before 1.2: allows Necropolis units other than skeletons to be raised by
necromancy After 1.2: determine units which is raised by necromancy
skill.
- subtype: creature raised
- val: Necromancer power
- addInfo: limiter by Necromancer power
- Example (from Necromancy skill):
` "power" : {`
` "type" : "IMPROVED_NECROMANCY",`
` "subtype" : "creature.skeleton",`
` "addInfo" : 0`
` }`
### LEARN_BATTLE_SPELL_CHANCE (since 1.2)
- subtype: 0 - from enemy hero, 1 - from entire battlefield (not
implemented now).
- val: chance to learn spell after battle victory
Note: used for Eagle Eye skill
### LEARN_BATTLE_SPELL_LEVEL_LIMIT (since 1.2)
- subtype: school (-1 for all), others TODO
- val: maximum learning level
Note: used for Eagle Eye skill
### LEARN_MEETING_SPELL_LIMIT (since 1.2)
- subtype: school (-1 for all), others TODO
- val: maximum learning level for learning a spell during hero
exchange
Note: used for Scholar skill
### ROUGH_TERRAIN_DISCOUNT (since 1.2)
- val: Non-road terrain discount in movement points
Note: used for Pathfinding skill
### WANDERING_CREATURES_JOIN_BONUS (since 1.2)
- val: value than used as level of diplomacy inside joining
probability calculating
### BEFORE_BATTLE_REPOSITION (since 1.2)
- val: number of hexes - 1 than should be used as repositionable hexes
before battle (like H3 tactics skill)
### BEFORE_BATTLE_REPOSITION_BLOCK (since 1.2)
- val: value than block opposite tactics, if value of opposite tactics
is less than this value of your hero (for 1.2, double-side tactics
is not working).
### HERO_EXPERIENCE_GAIN_PERCENT (since 1.2)
- val: how many experience hero gains from any source. There is a
global effect which set it by 100 (global value) and it is used as
learning skill
### UNDEAD_RAISE_PERCENTAGE (since 1.2)
- val: Percentage of killed enemy creatures to be raised after battle
as undead.
Note: used for Necromancy secondary skill, Necromancy artifacts and town
buildings.
### MANA_PER_KNOWLEDGE (since 1.2)
- val: Percentage rate of translating 10 hero knowledge to mana, used
for intelligence and global bonus
### HERO_GRANTS_ATTACKS (since 1.2)
- subtype: creature to have additional attacks
- val: Number of attacks
Note: used for Artillery secondary skill
### BONUS_DAMAGE_PERCENTAGE (since 1.2)
- subtype: creature to have additional damage percentage
- val: percentage to be granted
Note: used for Artillery secondary skill
### BONUS_DAMAGE_CHANCE (since 1.2)
- subtype: creature to have additional damage chance (will have
BONUS_DAMAGE_PERCENTAGE applied before attack concluded)
- val: chance in percent
### MAX_LEARNABLE_SPELL_LEVEL (since 1.2)
- val: maximum level of spells than hero can learn from any source.
This bonus have priority above any other LEARN\_\*SPELL_LEVEL
bonuses.
Note: used as global effect and as wisdom secondary skill.
## Hero specialties
### SPECIAL_SPELL_LEV
- subtype = id
- additionalInfo = value per level in percent
### SPELL_DAMAGE
Since 1.2: used for Sorcery secondary skill
- val = value in percent
### SPECIFIC_SPELL_DAMAGE
- subtype = id of spell
- val = value in percent (Luna, Ciele)
### SPECIAL_BLESS_DAMAGE (before 1.2)
- subtype = spell (bless by default)
- val = value per level in percent
### MAXED_SPELL (before 1.2)
Spell always has expert effects but not expert range
- subtype = id
### SPECIAL_PECULIAR_ENCHANT
blesses and curses with id = val dependent on unit's level
- subtype = 0 or 1 for Coronius
### SPECIAL_UPGRADE
- subtype = base creature ID
- addInfo = target creature ID
# Artifact bonuses
### SPELL_DURATION
### AIR_SPELL_DMG_PREMY, EARTH_SPELL_DMG_PREMY, FIRE_SPELL_DMG_PREMY, WATER_SPELL_DMG_PREMY
Effect of original Orb artifacts.
- val - **percent** bonus to air / earth / fire / water spell damage.
### BLOCK_MORALE, BLOCK_LUCK (removed in 1.2)
### SPELL
Hero knows spell, even if this spell is banned in map options or set to
"special".
- subtype - spell id
- val - skill level (0 - 3)
### SPELLS_OF_LEVEL
hero knows all spells of given level
- subtype - level
- val - skill level
Does not grant spells banned in map options.
### FIRE_SPELLS, AIR_SPELLS, WATER_SPELLS, EARTH_SPELLS
All spells of this school are granted to hero, eg. by Tomes of Magic.
Does not grant spells banned in map options.
### GENERATE_RESOURCE
- subtype - [resource](resource "wikilink") type
- val - daily income
### CREATURE_GROWTH
for legion artifacts
- value - weekly growth bonus,
- subtype - monster level if aplicable
### CREATURE_GROWTH_PERCENT
increases growth of all units in all towns,
- val - percentage
### BATTLE_NO_FLEEING
for Shackles of War
### NEGATE_ALL_NATURAL_IMMUNITIES
Orb of Vulnerability
### OPENING_BATTLE_SPELL
casts a spell at expert level at beginning of battle
- subtype - [spell](spell "wikilink") id
- val - spell power
### FREE_SHIP_BOARDING
movement points preserved with ship boarding and landing
### WHIRLPOOL_PROTECTION
hero won't lose army when teleporting through whirlpool
# Creature bonuses
### STACK_HEALTH
### STACKS_SPEED
- additional info - percent of speed bonus applied after direct
bonuses; \>0 - added, \<0 - subtracted to this part
### CREATURE_DAMAGE
- subtype: 0 = both, 1 = min, 2 = max
### SHOTS
### EXP_MULTIPLIER
- val - percent of additional exp gained by stack / commander (base
value 100)
# Creature abilities
## Static abilities and immunities
### NON_LIVING
eg. golems, elementals
### GARGOYLE
Gargoyle is special than NON_LIVING, cannot be rised or healed
### UNDEAD
### SIEGE_WEAPON
War machines have it. They cannot be raised or healed, have no morale
and don't move.
### DRAGON_NATURE
### KING1, KING2, KING3 (before 1.2)
Creatures take more damage from basic, advanced or expert Slayer effect.
### KING (after 1.2)
Creatures take more damage from Slayer effect than have greater or equal
value than KING bonus.
### FEARLESS
### NO_LUCK
eg. when fighting on cursed ground
### NO_MORALE
eg. when fighting on cursed ground
### SELF_MORALE (before 1.2)
eg. minotaur
### SELF_LUCK (before 1.2)
halfling
## Combat abilities
### FLYING
- subtype - 0 - regular, 1 - teleport
### SHOOTER
### CHARGE_IMMUNITY
### ADDITIONAL_ATTACK
### UNLIMITED_RETALIATIONS
### ADDITIONAL_RETALIATION
- value - number of additional retaliations
### JOUSTING
for champions
- val: percentage of charge
### HATE
eg. angels hate devils,
- subtype - ID of hated creature,
- val - damage bonus percent
### SPELL_LIKE_ATTACK
range is taken from spell, but damage from creature; eg. magog, lich
- subtype - spell,
- value - spell level
### THREE_HEADED_ATTACK
eg. cerberus
### ATTACKS_ALL_ADJACENT
eg. hydra
### TWO_HEX_ATTACK_BREATH
eg. dragons
### RETURN_AFTER_STRIKE
### ENEMY_DEFENCE_REDUCTION
in % (value) eg. behemots
### GENERAL_DAMAGE_REDUCTION
- subtype - 0 - shield (melee) , 1 - air shield effect (ranged), -1 -
armorer secondary skill (all, since 1.2)
### PERCENTAGE_DAMAGE_BOOST (since 1.2)
- subtype: -1 - any damage (not used), 0 - melee damage (offence), 1 -
ranged damage (archery)
### GENERAL_ATTACK_REDUCTION
eg. while stoned or blinded - in %
- subtype: -1 - any damage, 0 - melee damage, 1 - ranged damage
### DEFENSIVE_STANCE
WoG ability.
- val - bonus to defense while defending
### NO_DISTANCE_PENALTY
### NO_MELEE_PENALTY
Ranged stack does full damage in melee.
### NO_WALL_PENALTY
### FREE_SHOOTING
stacks can shoot even if otherwise blocked (sharpshooter's bow effect)
### BLOCKS_RETALIATION
eg. naga
### SOUL_STEAL
WoG ability. Gains new creatures for each enemy killed
- val: number of units gained per enemy killed
- subtype: 0 - gained units survive after battle, 1 - they do not
### TRANSMUTATION
WoG ability. % chance to transform attacked unit to other type
- val: chance to trigger in %
- subtype: 0 - resurrection based on HP, 1 - based on unit count
- addInfo: additional info - target creature ID (attacker default)
### SUMMON_GUARDIANS
WoG ability. Summon guardians surrounding desired stack
- val - amount in % of stack count
- subtype = creature ID
### RANGED_RETALIATION
Allows shooters to perform ranged retaliation
- no additional parameters
### BLOCKS_RANGED_RETALIATION
Disallows ranged retaliation for shooter unit, BLOCKS_RETALIATION bonus
is for melee retaliation only
- no additional parameters
### WIDE_BREATH
Dragon breath affecting multiple nearby hexes
- no additional parameters
### FIRST_STRIKE
First counterattack, then attack if possible
- no additional parameters
### SHOOTS_ALL_ADJACENT
H4 Cyclops-like shoot (attacks all hexes neighboring with target)
without spell-like mechanics
- no additional parameters
### DESTRUCTION
Kills extra units after hit
- subtype: 0 - kill percentage of units, 1 - kill amount
- val: chance in percent to trigger
- addInfo: amount/percentage to kill
### LIMITED_SHOOTING_RANGE (since VCMI 1.2)
Limits shooting range and/or changes long range penalty
- val: max shooting range in hexes
- addInfo: optional - sets range for "broken arrow" half damage
mechanic - default is 10
## Special abilities
### CATAPULT
- subtype: (since 1.2) ability to use when catapulting (usually it
contains ballistics parameters, ability for standard catapult and
affected by ballistics is core:spell.catapultShot)
### CATAPULT_EXTRA_SHOTS
- subtype: (since 1.2) ability to be affected. Ability of CATAPULT
bonus should match. Used for ballistics secondary skill with subtype
of core:spell.catapultShot.
- val: (since 1.2) ability level to be used with catapult. Additional
shots configured in ability level, not here.
- val: (before 1.2) number of additional shots, requires CATAPULT
bonus to work
### MANUAL_CONTROL
- manually control warmachine with
- id = subtype
- val = chance
### CHANGES_SPELL_COST_FOR_ALLY
eg. mage
- value - reduction in mana points
### CHANGES_SPELL_COST_FOR_ENEMY
eg. Silver Pegasus
- value - mana points penalty
### SPELL_RESISTANCE_AURA
eg. unicorns
- value - resistance bonus in % for adjacent creatures
### HP_REGENERATION
creature regenerates val HP every new round
- val: amount of HP regeneration per round
### MANA_DRAIN
value - spell points per turn
### MANA_CHANNELING
eg. familiar
- value in %
### LIFE_DRAIN
- val - precentage of life drained
### DOUBLE_DAMAGE_CHANCE
eg. dread knight
- value in %
### FEAR
### HEALER
First aid tent
- subtype: (since 1.2) ability used for healing.
### FIRE_SHIELD
### MAGIC_MIRROR
- value - chance of redirecting in %
### ACID_BREATH
- val - damage per creature after attack,
- additional info - chance in percent
### DEATH_STARE
- subtype: 0 - gorgon, 1 - commander
- val: if subtype is 0, its the (average) percentage of killed
creatures related to size of attacking stack
### SPECIAL_CRYSTAL_GENERATION
Crystal dragon crystal generation
### NO_SPELLCAST_BY_DEFAULT
Spellcast will not be default attack option for this creature
## Creature spellcasting and activated abilities
### SPELLCASTER
Creature gain activated ability to cast a spell. Example: Archangel,
Faerie Dragon
- subtype - spell id
- value - level of school
- additional info - weighted chance
use SPECIFIC_SPELL_POWER, CREATURE_SPELL_POWER or CREATURE_ENCHANT_POWER
for calculating the power (since 1.2 those bonuses can be used for
calculating CATAPULT and HEALER bonuses)
### ENCHANTER
for Enchanter spells
- val - skill level
- subtype - spell id
- additionalInfo - cooldown (number of turns)
### RANDOM_SPELLCASTER
eg. master genie
- val - spell mastery level
### SPELL_AFTER_ATTACK
- subtype - spell id
- value - chance %
- additional info - \[X, Y\]
- X - spell level
- Y = 0 - all attacks, 1 - shot only, 2 - melee only
### SPELL_BEFORE_ATTACK
- subtype - spell id
- value - chance %
- additional info - \[X, Y\]
- X - spell level
- Y = 0 - all attacks, 1 - shot only, 2 - melee only
### CASTS
how many times creature can cast activated spell
### SPECIFIC_SPELL_POWER
- value used for Thunderbolt and Resurrection casted by units, also
for Healing secondary skill (for core:spell.firstAid used by First
Aid tent)
- subtype - spell id
### CREATURE_SPELL_POWER
- value per unit, divided by 100 (so faerie Dragons have 500)
### CREATURE_ENCHANT_POWER
total duration of spells casted by creature
### REBIRTH
- val - percent of total stack HP restored
- subtype = 0 - regular, 1 - at least one unit (sacred Phoenix)
### ENCHANTED
Stack is permanently enchanted with spell subID of skill level = val, if
val \> 3 then spell is mass and has level of val-3. Enchantment is
refreshed every turn.
## Spell immunities
### LEVEL_SPELL_IMMUNITY
creature is immune to all spell with level below or equal to value of
this bonus
### MAGIC_RESISTANCE
- value - percent
### SPELL_DAMAGE_REDUCTION
eg. golems
- value - reduction in %
- subtype - spell school; -1 - all, 0 - air, 1 - fire, 2 - water, 3 -
earth
### MORE_DAMAGE_FROM_SPELL
- value - damage increase in %
- subtype - spell id
### FIRE_IMMUNITY,WATER_IMMUNITY, EARTH_IMMUNITY, AIR_IMMUNITY
- subtype 0 - all, 1 - all except positive, 2 - only damage spells
### MIND_IMMUNITY
Creature is immune to all mind spells.
### SPELL_IMMUNITY
- subtype - spell id
- ainfo - 0 - normal, 1 - absolute
### DIRECT_DAMAGE_IMMUNITY
WoG ability. Creature is completely immune to damage spells.
### RECEPTIVE
WoG ability. Creature accepts all friendly spells even though it would
be normally immune to it.
## Deprecated creature abilities
### DAEMON_SUMMONING
pit lord - removed in VCMI 1.2 as part of major battles refactoring
- subtype - type of creatures
- val - hp per unit
# Spell effects
### POISON
- val - max health penalty from poison possible
### SLAYER
- value - spell level
### BIND_EFFECT
doesn't do anything particular, works as a marker
### FORGETFULL
forgetfulness spell effect
- value - level
### NOT_ACTIVE
### ALWAYS_MINIMUM_DAMAGE
unit does its minimum damage from range
- subtype: -1 - any attack, 0 - melee, 1 - ranged
- value: additional damage penalty (it'll subtracted from dmg)
- additional info - multiplicative anti-bonus for dmg in % \[eg 20
means that creature will inflict 80% of normal minimal dmg\]
### ALWAYS_MAXIMUM_DAMAGE
eg. bless effect
- subtype: -1 - any attack, 0 - melee, 1 - ranged
- value: additional damage
- additional info - multiplicative bonus for dmg in %
### ATTACKS_NEAREST_CREATURE
while in berserk
### IN_FRENZY
- value - level
### HYPNOTIZED
### NO_RETALIATION
Eg. when blinded or paralyzed.

View File

@ -0,0 +1,16 @@
Bonus may have any of these durations. They acts in disjunction.
## List of all bonus duration types
- PERMANENT
- ONE_BATTLE //at the end of battle
- ONE_DAY //at the end of day
- ONE_WEEK //at the end of week (bonus lasts till the end of week,
thats NOT 7 days
- N_TURNS //used during battles, after battle bonus is always removed
- N_DAYS
- UNTIL_BEING_ATTACKED //removed after any damage-inflicting attack
- UNTIL_ATTACK //removed after attack and counterattacks are performed
- STACK_GETS_TURN //removed when stack gets its turn - used for
defensive stance
- COMMANDER_KILLED

View File

@ -0,0 +1,105 @@
## Predefined Limiters
The limiters take no parameters:
- SHOOTER_ONLY
- DRAGON_NATURE
- IS_UNDEAD
- CREATURE_NATIVE_TERRAIN
- OPPOSITE_SIDE
Example:
``` javascript
"limiters" : [ "SHOOTER_ONLY" ]
```
## Customizable Limiters
### HAS_ANOTHER_BONUS_LIMITER
Parameters:
- Bonus type
- (optional) bonus subtype
- (optional) bonus sourceType and sourceId in struct
- example: (from Adele's bless):
``` javascript
"limiters" : [
{
"type" : "HAS_ANOTHER_BONUS_LIMITER",
"parameters" : [
"GENERAL_DAMAGE_PREMY",
1,
{
"type" : "SPELL_EFFECT",
"id" : "spell.bless"
}
]
}
],
```
### CREATURE_TYPE_LIMITER
Parameters:
- Creature id (string)
- (optional) include upgrades - default is false
### CREATURE_ALIGNMENT_LIMITER
Parameters:
- Alignment identifier
### CREATURE_FACTION_LIMITER
Parameters:
- Faction identifier
### CREATURE_TERRAIN_LIMITER
Parameters:
- Terrain identifier
Example:
``` javascript
"limiters": [ {
"type":"CREATURE_TYPE_LIMITER",
"parameters": [ "angel", true ]
} ],
```
``` javascript
"limiters" : [ {
"type" : "CREATURE_TERRAIN_LIMITER",
"parameters" : ["sand"]
} ]
```
## Aggregate Limiters
The following limiters must be specified as the first element of a list,
and operate on the remaining limiters in that list:
- allOf (default when no aggregate limiter is specified)
- anyOf
- noneOf
Example:
``` javascript
"limiters" : [
"noneOf",
"IS_UNDEAD",
{
"type" : "HAS_ANOTHER_BONUS_LIMITER",
"parameters" : [ "SIEGE_WEAPON" ]
}
]
```

View File

@ -0,0 +1,25 @@
## Available propagators
- BATTLE_WIDE
Affects both sides during battle
- VISITED_TOWN_AND_VISITOR
Used with Legion artifacts (town visited by hero)
- PLAYER_PROPAGATOR
Bonus will affect all objects owned by player. Used by Statue of Legion.
- TEAM_PROPAGATOR
Bonus will affect all objects owned by player and his allies.
- HERO
Bonus will be transferred to hero (for example from stacks in his army).
- GLOBAL_EFFECT
This effect will influence all creatures, heroes and towns on the map.

View File

@ -0,0 +1,20 @@
# List of all Bonus range types
- NO_LIMIT
- ONLY_DISTANCE_FIGHT
- ONLY_MELEE_FIGHT
- ONLY_ENEMY_ARMY (before 1.2)
TODO: in 0.91 ONLY_MELEE_FIGHT / ONLY_DISTANCE_FIGHT range types work
ONLY with creature attack, should be extended to all battle abilities.
(1.2+) For replacing ONLY_ENEMY_ARMY alias, you should use the following
parameters of bonus:
"propagator": "BATTLE_WIDE",
"propagationUpdater" : "BONUS_OWNER_UPDATER",
"limiters" : [ "OPPOSITE_SIDE" ]
If some propagators was set before, it was actually ignored and should
be replaced to code above. And OPPOSITE_SIDE limiter should be first, if
any other limiters exists.

View File

@ -0,0 +1,21 @@
# List of all possible bonus sources
- ARTIFACT
- ARTIFACT_INSTANCE
- OBJECT
- CREATURE_ABILITY
- TERRAIN_NATIVE
- TERRAIN_OVERLAY
- SPELL_EFFECT
- TOWN_STRUCTURE
- HERO_BASE_SKILL
- SECONDARY_SKILL
- HERO_SPECIAL
- ARMY
- CAMPAIGN_BONUS
- SPECIAL_WEEK
- STACK_EXPERIENCE
- COMMANDER
- GLOBAL_EFFECT (before 1.2)
- GLOBAL (after 1.2)
- OTHER

View File

@ -0,0 +1,89 @@
# List of Bonus Updaters
Updaters come in two forms: simple and complex. Simple updaters take no
parameters and are specified as strings. Complex updaters do take
parameters (sometimes optional), and are specified as structs.
Check the files in *config/heroes/* for additional usage examples.
## GROWS_WITH_LEVEL
- Type: Complex
- Parameters: valPer20, stepSize=1
- Effect: Updates val to
` ceil(valPer20 * floor(heroLevel / stepSize) / 20)`
Example: The following updater will cause a bonus to grow by 6 for every
40 levels. At first level, rounding will cause the bonus to be 0.
` "updater" : {`
` "parameters" : [ 6, 2 ],`
` "type" : "GROWS_WITH_LEVEL"`
` }`
Example: The following updater will cause a bonus to grow by 3 for every
20 levels. At first level, rounding will cause the bonus to be 1.
` "updater" : {`
` "parameters" : [ 3 ],`
` "type" : "GROWS_WITH_LEVEL"`
` }`
Remarks:
- The rounding rules are designed to match the attack/defense bonus
progression for heroes with creature specialties in HMM3.
- There is no point in specifying val for a bonus with a
GROWS_WITH_LEVEL updater.
## TIMES_HERO_LEVEL
- Type: Simple
- Effect: Updates val to
` val * heroLevel`
Usage:
` "updater" : "TIMES_HERO_LEVEL"`
Remark: This updater is redundant, in the sense that GROWS_WITH_LEVEL
can also express the desired scaling by setting valPer20 to 20\*val. It
has been added for convenience.
## TIMES_STACK_LEVEL
- Type: Simple
- Effect: Updates val to
` val * stackLevel`
Usage:
` "updater" : "TIMES_STACK_LEVEL"`
Remark: The stack level for war machines is 0.
## ARMY_MOVEMENT
- Type: Complex
- Parameters: basePerSpeed, dividePerSpeed, additionalMultiplier,
maxValue
- Effect: Updates val to val+= max((floor(basePerSpeed /
dividePerSpeed)\* additionalMultiplier), maxValue)
- Remark: this updater is designed for MOVEMENT bonus to match H3 army
movement rules (in the example - actual movement updater, which
produces values same as in default movement.txt).
- Example:
` "updater" : {`
` "parameters" : [ 20, 3, 10, 700 ],`
` "type" : "ARMY_MOVEMENT"`
` }`
# Additional links
- [Bonus system](Bonus_system "wikilink")
- [Bonus Format](Bonus_Format "wikilink")
- [Hero Format](Hero_Format "wikilink")

View File

@ -0,0 +1,31 @@
Total value of Bonus is calculated using the following:
- For each bonus source type we calculate new source value (for all
bonus value types except PERCENT_TO_SOURCE and
PERCENT_TO_TARGET_TYPE) using the following:
` newVal = (val * (100 + PERCENT_TO_SOURCE) / 100))`
PERCENT_TO_TARGET_TYPE applies as PERCENT_TO_SOURCE to targetSourceType
of bonus.
- All bonus value types summarized and then used as subject of the
following formula:
` clamp(((BASE_NUMBER * (100 + PERCENT_TO_BASE) / 100) + ADDITIVE_VALUE) * (100 + PERCENT_TO_ALL) / 100), INDEPENDENT_MAX, INDEPENDENT_MIN)`
As for 1.2, semantics of INDEPENDENT_MAX and INDEPENDENT_MIN are
wrapped, and first means than bonus total value will be at least
INDEPENDENT_MAX, and second means than bonus value will be at most
INDEPENDENT_MIN.
# List of all bonus value types
- ADDITIVE_VALUE
- BASE_NUMBER
- PERCENT_TO_ALL
- PERCENT_TO_BASE
- INDEPENDENT_MAX
- INDEPENDENT_MIN
- PERCENT_TO_SOURCE (since 1.2)
- PERCENT_TO_TARGET_TYPE (since 1.2)

View File

@ -0,0 +1,169 @@
Work-in-progress page do describe all bonuses provided by town buildings
for future configuration.
## unique buildings
Hardcoded functionalities, selectable but not configurable. In future
should be moved to scripting.
Includes:
- mystic pond
- treasury
- god of fire
- castle gates
- cover of darkness
- portal of summoning
- escape tunnel
Function of all of these objects can be enabled by this:
``` javascript
"function" : "castleGates"
```
## trade-related
Hardcoded functionality for now due to complexity of these objects.
Temporary can be handles as unique buildings. Includes:
- resource - resource
- resource - player
- artifact - resource
- resource - artifact
- creature - resource
- resource - skills
- creature - skeleton
## hero visitables
Buildings that give one or another bonus to visiting hero. All should be
handled via configurable objects system.
Includes:
- gives mana points
- gives movement points
- give bonus to visitor
- permanent bonus to hero
## generic functions
Generic town-specific functions that can be implemented as part of
CBuilding class.
### unlock guild level
``` javascript
"guildLevels" : 1
```
### unlock hero recruitment
``` javascript
"allowsHeroPurchase" : true
```
### unlock ship purchase
``` javascript
"allowsShipPurchase" : true
```
### unlock building purchase
``` javascript
"allowsBuildingPurchase" : true
```
### unlocks creatures
``` javascript
"dwelling" : { "level" : 1, "creature" : "archer" }
```
### creature growth bonus
Turn into town bonus? What about creature-specific bonuses from hordes?
### gives resources
``` javascript
"provides" : { "gold" : 500 }
```
### gives guild spells
``` javascript
"guildSpells" : [5, 0, 0, 0, 0]
```
### gives thieves guild
``` javascript
"thievesGuildLevels" : 1
```
### gives fortifications
``` javascript
"fortificationLevels" : 1
```
### gives war machine
``` javascript
"warMachine" : "ballista"
```
## simple bonuses
Bonuses that can be made part of CBuilding. Note that due to how bonus
system works this bonuses won't be stackable.
TODO: how to handle stackable bonuses like Necromancy Amplifier?
Includes:
- bonus to defender
- bonus to alliance
- bonus to scouting range
- bonus to player
``` javascript
"bonuses" :
{
"moraleToDefenders" :
{
"type": "MORALE",
"val" : 1,
"propagator" : ["VISITED_TOWN_AND_VISITOR"]
},
"luckToTeam" :
{
"type" : "LUCK",
"val" : 2,
"propagator" : [ "TEAM_PROPAGATOR" ]
}
```
## misc
Some other properties of town building that does not fall under "bonus"
category.
### unique building
Possible issue - with removing of fixed ID's buildings in different town
may no longer share same ID. However Capitol must be unique across all
town. Should be fixed somehow.
``` javascript
"onePerPlayer" : true
```
### chance to be built on start
``` javascript
"prebuiltChance" : 75
```

View File

@ -0,0 +1,66 @@
This is description of fields for creature banks, part of [Object
Format](Object_Format "wikilink")
``` javascript
{
/// List of levels of this bank. On map loading, one of them will be randomly assigned to bank.
"levels": [
{
/// Chance for this level to be active
"chance": 30,
/// Description of guards, stacks will be ordered
/// on battlefield according to this scheme:
/// 4 7 1
///
/// 6 5
///
/// 3 2
/// Possible fields:
/// amount - size of stack
/// type - string ID of creature for this stack
/// upgradeChance - chance (in percent) for this stack to be upgraded
"guards": [
{ "amount": 4, "type": "cyclop" },
{ "amount": 4, "type": "cyclop" },
{ "amount": 4, "type": "cyclop", "upgradeChance": 50 },
{ "amount": 4, "type": "cyclop" },
{ "amount": 4, "type": "cyclop" }
],
// How hard are guards of this level. Unused?
"combat_value": 506,
/// Description of rewards granted for clearing bank
"reward" : {
/// Approximate value of reward, known to AI. Unused?
"value": 10000,
/// Granted resources
"resources": {
"wood" : 4,
"mercury" : 4,
"ore" : 4,
"sulfur" : 4,
"crystal" : 4,
"gems" : 4,
"gold" : 0
},
/// Granted creatures, same format as guards
"creatures" : [
{ "amount": 4, "type": "wyvern" }
],
/// List of random artifacts
"artifacts": [ { "class" : "TREASURE" } ]
/// List of spells
"spells" : [ { "level" : 5 } ]
}
}
}
]
}
```

View File

@ -0,0 +1,22 @@
This is description of fields for creature banks, part of [Object
Format](Object_Format "wikilink")
``` javascript
{
/// List of creatures in this bank. Each list represents one "level" of bank
/// Creatures on the same level will have shared growth and available number (similar to towns)
/// Note that due to GUI limitation it is not recommended to have more than 4 creatures at once
"creatures" : [
[ "airElemental", "stormElemental" ],
[ "waterElemental" ]
],
/// List of guards for this dwelling. Can have two possible values:
/// Boolean true/false - If set to "true", guards will be generated using H3 formula:
/// 3 week growth of first available creatures
/// List of objects - custom guards, each entry represent one stack in defender army
"guards" : [
{ "amount" : 12, "type" : "earthElemental" }
]
}
```

View File

@ -0,0 +1,101 @@
Ideally, template format should be 100% compatible with OH3 format and
bring additional improvements.
## List of currently available templates
- Analogy
- Upgrade
- Golden Ring
- Unfair Game
- Jebus Cross
## Template format
``` javascript
/// Unique template name
"Triangle" :
{
//optional name - useful to have several template variations with same name (since 0.99)
"name" : "Custom template name",
"description" : "Brief description of template, recommended setting or rules".
/// Minimal and maximal size of the map. Possible formats:
/// Size code: s, m, l or xl for size with optional suffix "+u" for underground
/// Numeric size, e.g. 120x120x1 (width x height x depth). Note that right now depth can only be 0 or 1
"minSize" : "m",
"maxSize" : "xl+u",
/// Number of players that will be present on map (human or AI)
"players" : "2-4",
/// Number of AI-only players
"cpu" : "2",
///Optional parameter allowing to prohibit some water modes. All modes are allowed if parameter is not specified
"allowedWaterContent" : ["none", "normal", "islands"]
/// List of named zones, see below for format description
"zones" :
{
"zoneA" : { ... },
"zoneB" : { ... },
"zoneC" : { ... }
},
"connections" :
[
{ "a" : "zoneA", "b" : "zoneB", "guard" : 5000, "road" : "false" },
{ "a" : "zoneA", "b" : "zoneC", "guard" : 5000, "road" : "random" },
{ "a" : "zoneB", "b" : "zoneC", "type" : "wide" }
//"type" can be "guarded" (default), "wide", "fictive" or "repulsive"
//"wide" connections have no border, or guard. "fictive" and "repulsive" connections are virtual -
//they do not create actual path, but only attract or repulse zones, respectively
]
}
```
## Zone format
``` javascript
{
"type" : "playerStart", //"cpuStart" "treasure" "junction"
"size" : 2, //relative size of zone
"owner" : 1, //player owned this zone
"playerTowns" : {
"castles" : 1
//"towns" : 1
},
"neutralTowns" : {
//"castles" : 1
"towns" : 1
},
"townsAreSameType" : true,
"monsters" : "normal", //"weak" "strong", "none" - All treasures will be unguarded
"terrainTypes" : [ "sand" ], //possible terrain types. All terrains will be available if not specified
"bannedTerrains" : ["lava", "asphalt"] //optional
"matchTerrainToTown" : false, //if true, terrain for this zone will match native terrain of player faction
"minesLikeZone" : 1,
"treasureLikeZone" : 1
"terrainTypeLikeZone" : 3
"allowedMonsters" : ["inferno", "necropolis"] //factions of monsters allowed on this zone
"bannedMonsters" : ["fortress", "stronghold", "conflux"] //These monsers will never appear in the zone
"allowedTowns" : ["castle", "tower", "rampart"] //towns allowed on this terrain
"bannedTowns" : ["necropolis"] //towns will never spawn on this terrain
"mines" : {
"wood" : 1,
"ore" : 1,
},
"treasure" : [
{
"min" : 2100,
"max": 3000,
"density" : 5
}
...
]
}
```

View File

@ -0,0 +1,55 @@
# List of bugs fixed in VCMI
These bugs were present in original Shadow of Death game, however the
team decided to fix them to bring back desired behaviour.
# List of game mechanics changes
Some of H3 mechanics can't be straight considered as bug, but default
VCMI behaviour is different:
- Dwellings. Remain creatures are accumulated instead of reset each
week. Can be disabled using DWELLINGS_ACCUMULATE_CREATURES.
- Pathfinding. Hero can't grab artifact while flying when all tiles
around it are guarded without triggering attack from guard. Original
behavior can be re-enabled using "originalMovementRules" pathfinder
option.
- Battles. Hero that won battle, but only have temporary summoned
creatures alive going to appear in tavern like if he retreated. Can
be disabled using WINNING_HERO_WITH_NO_TROOPS_RETREATS.
- Battles. Spells from artifacts like AOTD are autocasted on beginning
of the battle, not beginning of turn. Task on mantis:
[1](https://bugs.vcmi.eu/view.php?id=1347)
- Objects. Black market changes artifacts every month like town
artifact merchants do. Can be disabled using
BLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE.
- Spells. Dimension Door spell doesn't allow to teleport to unexplored
tiles. Task on mantis to track this:
[2](https://bugs.vcmi.eu/view.php?id=2751).
# List of extended game functionality
- Quick army management in the garrison screen:
` [LShift] + LClick – splits a half units from the selected stack into`
` an empty slot.`
` [LCtrl] + LClick – splits a single unit from the selected stack into`
` an empty slot.`
` [LCtrl] + [LShift] + LClick – split single units from the selected`
` stack into all empty hero/garrison slots`
` [Alt] + LClick – merge all splitted single units into one stack`
` [Alt] + [LCtrl] + LClick - move all units of selected stack to the city's garrison or to the met hero`
` [Alt] + [LShift] + LClick - dismiss selected stack`
- Mouse click on castle icon in the town screen open quick recruitment
window, where we can purhase in fast way units.
# Manuals and guides
- \[<http://www.4shared.com/document/qLi-INYQ/Heroes_of_Might_and_Magic_III_.html>?
Official Heroes of Might & Magic III user manual\]
- \[<http://www.4shared.com/document/HbWI7YlH/Strategija.html>?
Strategija\] covers detailed machanics not mentioned in official
documents.
- \[<http://www.4shared.com/document/F_3NbdTI/New_WoG_Features.html>?
New WoG features\]

View File

@ -0,0 +1,63 @@
# Download and install VCMI
**This app requires original heroes 3 sod / complete files to operate,
they are not supplied with this installer. it is recommended to purchase
version from gog.com. Heroes 3 "hd edition" (steam version) files are
not supported !!!**
Installation is a two step process, at first you need to install game,
then you need to upload Heroes3 original data files into your android
device.
- Latest release on Google Play (recommended):
<https://play.google.com/store/apps/details?id=is.xyz.vcmi>
- Latest release as .apk file:
<https://github.com/vcmi/vcmi/releases/latest>
- Daily builds (unstable):
<https://builds.vcmi.download/branch/develop/Android/>
# Installing Heroes III data files
- Install Heroes III on your PC or extract Heroes III data files from
gog installer
<!-- -->
- Connect your device to PC and enable file transfer.
<!-- -->
- Copy "Data", "Maps" and "Mp3" from Heroes III to any folder on
mobile device, then open VCMI, select Heroes III data import option,
then select the folder where you copied Heroes III data.
# Troubleshooting / well known issues
## The game crashes on start
**Please double check that you copied original SoD/Complete game files
into your Android Device**
## I installed google play version, but have a problem while installing daily builds
**Solution:** Uninstall google play version first, before installing
daily build version.
## I installed play version, but the screen is flashing / blank on its edges
**Solution:** Should be fixed since VCMI 1.3
## The game always starts in 800x600 resolution, cannot effectively change it, also there is a lot of blank space on my widescreen device
**Solution:** Should be fixed since VCMI 1.3 onwards.
If you use version 1.2 or older - please download "VCMI-extras" mod from
VCMI Launcher. Resolution setting 1024x600 is better than original
800x600 for widescreen mobile phones.
## Other problems
- Please report about gameplay problem on forums: [Help &
Bugs](https://forum.vcmi.eu/c/international-board/help-bugs) or
[Discord](https://discord.gg/chBT42V)
Make sure to specify your device and used version of Android.

View File

@ -0,0 +1,158 @@
VCMI requires data from original Heroes 3: Shadow of Death or Complete
editions. Data from native Linux version made by LOKI will not work.
# Binaries installation
## Ubuntu
**Latest stable build from PPA (recommended)**
Up-to-date releases can be found in our PPA here:
<https://launchpad.net/~vcmi/+archive/ubuntu/ppa>
To install VCMI from PPA use:
sudo apt-add-repository ppa:vcmi/ppa
sudo apt update
sudo apt install vcmi
**Unstable testing build from PPA**
We also provide latest, unstable builds mostly suitable for testing
here: <https://launchpad.net/~vcmi/+archive/ubuntu/vcmi-latest>
In order to install from this PPA use:
sudo add-apt-repository ppa:vcmi/vcmi-latest
sudo apt update
sudo apt install vcmi
**From Ubuntu repository**
VCMI stable builds available in "multiverse" repository. Learn how to
enable it in [Ubuntu
wiki](https://help.ubuntu.com/community/Repositories/Ubuntu).
Once enabled, you can install VCMI using Ubuntu Store or in terminal
using following commands:
sudo apt update
sudo apt install vcmi
Note that version available in Ubuntu is outdated. Install via PPA is
preferred.
## Debian
Stable VCMI version is available in "contrib" repository. Learn how to
enable it in [Debian wiki](https://wiki.debian.org/SourcesList).
To install VCMI from repository:
sudo apt-get update
sudo apt-get install vcmi
## Flatpak (distribution-agnostic)
Latest public release build can be installed via Flatpak.
Depending on your distribution, you may need to install flatpak itself.
You can find guide for your distribution here:
<https://www.flatpak.org/setup/>
Once you have flatpak, you can install VCMI package which can be found
here: <https://flathub.org/apps/details/eu.vcmi.VCMI>
## Other distributions
For other distributions, VCMI can be installed from 3rd-party
repositories listed below.
Note that these repositories are not supported by vcmi team and may not
be up to date.
- Archlinux [vcmi](https://aur.archlinux.org/packages/vcmi/)
[vcmi-git](https://aur.archlinux.org/packages/vcmi-git/)
- openSUSE [1 Click
Install](https://software.opensuse.org/download.html?project=games&package=vcmi)
If you are interested in providing builds for other distributions,
please let us know.
## Compiling from source
Please check following developer guide: [How to build VCMI
(Linux)](How_to_build_VCMI_(Linux) "wikilink")
# Installing Heroes III data files
To install VCMI you will need Heroes III: Shadow of Death or Complete
edition.
## Install data using vcmibuilder script (recommended for non-Flatpak installs)
To install Heroes 3 data using automated script you need any of:
- Offline Installer downloaded from gog.com (both .exe and .bin files
are required)
- Directory with preinstalled game
- One or two CD's or CD images
Run the script using options appropriate to your input files:
vcmibuilder --cd1 /path/to/iso/or/cd --cd2 /path/to/second/cd
vcmibuilder --gog /path/to/gog.com/installer.exe
vcmibuilder --data /path/to/h3/data
You should use only one of these commands.
On flatpak install, it's also possible to run the script, but any path
seems to be interpreted from within the Flatpak sandbox:
flatpak run --command=vcmibuilder eu.vcmi.VCMI --data /path/to/h3/data`
## Install data using gog.com offline installer
Download both files for the "offline backup game installers" and extract
them using innoextract tool
innoextract --output-dir=~/Downloads/HoMM3 "setup_heroes_of_might_and_magic_3_complete_4.0_(28740).exe"
(note that installer file name might be different)
Once innoextract completes, start VCMI Launcher and choose to copy
existing files. Select the ~/Downloads/HoMM3 directory. Once copy is
complete, you can delete both offline installer files as well as
~/Downloads/HoMM3.
## Install using existing Heroes III data
Copy "Data", "Maps" and "Mp3" from Heroes III to:
$HOME/.local/share/vcmi/
Or, in case of flatpak install to
$HOME/.var/app/eu.vcmi.VCMI/data/vcmi/
On some distributions $XDG_DATA_HOME could differ so instead you may
need to use:
$XDG_DATA_HOME/vcmi/
# Launching game
To start the game type in console:
vcmilauncher
Or, to start game directly avoiding Launcher:
vcmiclient
VCMI should be also available via desktop environment menu or launcher
(Games/Strategy/VCMI)
# Reporting bugs
Please report any issues with packages according to [Bug reporting
guidelines](http://wiki.vcmi.eu/index.php?title=Bug_reporting_guidelines)

View File

@ -0,0 +1,51 @@
# Step 1: Download and install VCMI
Install one of following into new folder, same as when installing new
game:
- Latest release (recommended):
<https://github.com/vcmi/vcmi/releases/latest>
- Daily builds (unstable):
<https://builds.vcmi.download/branch/develop/Windows/>
- Please report about problems on GitHub: [Bug
Tracker](https://github.com/vcmi/vcmi/issues)
# Step 2: Installing Heroes III data files
**Since VCMI 1.2 you can skip this step, just run VCMI launcher and it
will help you with importing H3 data. For older releases you can follow
this step.**
- Install Heroes III from disk or using GOG installer.
<!-- -->
- Copy "Data", "Maps" and "Mp3" from Heroes III to:
<!-- -->
%USERPROFILE%\Documents\My Games\vcmi\
Create this folder if it doesnt exist yet
# Step 3: (for release 1.0.0 and above) connect to the mod repository
- If that's your first installation, connection to the mod repository
will be configured automatically, you'll see mods available to
install from VCMI launcher
- We recommend you to install VCMI extras to support various
helpful UI tweaks and (before 1.3) support for different screen
resolutions
# Step 3: (for old builds 0.99 and earlier) download and copy and enable Essential Package
- Skip this step if you installed 1.0.0 or latest daily build
- For some technical reasons it wasn't included in game installation
package for legacy versions and needs to be downloaded and activated
seperately
- Download "VCMI essential files mods" from here
<https://wiki.vcmi.eu/Mod_list#Utilities>
- After unpacking, copy folder Mods to your main VCMI directory
- When launching game, please enable "VCMI essential files" as well as
its sub-elements: Andruids Bonus Icons, Bonus Icons, Spell Immunity
bonus icons, Extra resolutions and Default templates.

View File

@ -0,0 +1,98 @@
You can run VCMI on iOS 12.0 and later, all devices are supported. If
you wish to run on iOS 10 or 11, you should build from source, see [How
to build VCMI (iOS)](How_to_build_VCMI_(iOS) "wikilink").
## Download and install VCMI
The latest release (recommended):
<https://github.com/vcmi/vcmi/releases/latest>
Daily builds: <https://builds.vcmi.download/branch/develop/iOS/>
To run on a non-jailbroken device you need to sign the IPA file, you
have the following options:
- *\[Easiest way\]* [AltStore](https://altstore.io/) or
[Sideloadly](https://sideloadly.io/) - can be installed on Windows
or macOS, don't require dealing with signing on your own
- if you're on iOS 14.0-15.4.1, you can try
<https://github.com/opa334/TrollStore>
- Get signer tool
[here](https://dantheman827.github.io/ios-app-signer/) and a guide
[here](https://forum.kodi.tv/showthread.php?tid=245978) (it's for
Kodi, but the logic is the same). Signing with this app can only be
done on macOS.
- [Create signing assets on macOS from
terminal](https://github.com/kambala-decapitator/xcode-auto-signing-assets).
In the command replace `your.bundle.id` with something like
`com.MY-NAME.vcmi`. After that use the above signer tool.
- [Sign from any
OS](https://github.com/indygreg/PyOxidizer/tree/main/tugger-code-signing).
You'd still need to find a way to create signing assets (private key
and provisioning profile) though.
## Installing Heroes III data files
*Note: if you don't need in-game videos, you can omit
downloading/copying file VIDEO.VID from data folder - it will save your
time and space. The same applies to the Mp3 directory.*
### Installing data files with Finder or Windows explorer
To play the game, you need to upload HoMM3 data files - **Data**,
**Maps** and **Mp3** directories - to the device. Use Finder (or iTunes,
if you're on Windows or your macOS is 10.14 or earlier) for that. You
can also add various [mods](https://wiki.vcmi.eu/Mod_list) by uploading
**Mods** directory. Follow [official Apple
guide](https://support.apple.com/en-us/HT210598) and place files into
VCMI app. Unfortunately, Finder doesn't display copy progress, give it
about 10 minutes to finish.
### Installing data files using iOS device only
If you have data somewhere on device or in shared folder or you have
downloaded it, you can copy it directly on your iPhone/iPad using Files
application.
Just move/copy **Data**, **Maps** and **Mp3** folders into vcmi
application - it will be visible in Files along with other applications'
folders.
### Installing data files with Xcode on macOS
You can also upload files with Xcode. You need to prepare "container"
for that.
1. Connect your device to your Mac
2. Start Xcode
3. Open Devices and Simulators window: Cmd+Shift+2 or Menu - Window -
Devices and Simulators
4. Select your device
5. Select VCMI
6. In the bottom find "three dots" or "cogwheel" button (it should be
next to + - buttons) - click it - select Download Container...
7. Place the game directories inside the downloaded container -
AppData - Documents
8. Click the "three dots" / "cogwheel" button in Xcode again - Replace
Container... - select the downloaded container
9. Wait until Xcode finishes copying, progress is visible (although it
might be "indefinite")
## Game controls
- Tap = left click
- Tap and hold (long press) = right click
- before v1.3: Pinch with 2 fingers = spacebar (visit current object)
- Tap in the bottom area (status bar) to activate chat/console in the
game
You can start game directly (avoiding the launcher) by changing setting
in iOS Settings app - VCMI.
## Reporting bugs
- Please report about gameplay problem on forums: [Help &
Bugs](https://forum.vcmi.eu/c/international-board/help-bugs)
- Please report iOS-specific issues in [this forum
thread](https://forum.vcmi.eu/t/ios-port/820) or (better) at
[GitHub](https://github.com/vcmi/vcmi/issues) with **iOS** label

View File

@ -0,0 +1,50 @@
**For iOS installation look here:
<https://wiki.vcmi.eu/Installation_on_iOS>**
# Download and install VCMI
- The latest release (recommended):
<https://github.com/vcmi/vcmi/releases/latest>
- Daily builds (might be unstable)
- Intel (x86_64) builds:
<https://builds.vcmi.download/branch/develop/macOS/intel>
- Apple Silicon (arm64) builds:
<https://builds.vcmi.download/branch/develop/macOS/arm>
If the app doesn't open, right-click the app bundle - select *Open* menu
item - press *Open* button.
Please report about gameplay problem on forums: [Help &
Bugs](https://forum.vcmi.eu/c/international-board/help-bugs)
If your problem is Mac-specific: DMG corrupted or if it doesn't start
please use following topic:
- [VCMI for macOS](https://forum.vcmi.eu/t/macos-builds/550)
Make sure to specify what hardware and macOS version you use.
# Installing Heroes III data files
1. Find a way to unpack Windows Heroes III or GOG installer. For
example, use `vcmibuilder` script inside app bundle or install the
game with [CrossOver](https://www.codeweavers.com/crossover) /
[Wineskin](https://github.com/Gcenx/WineskinServer).
2. Copy (or symlink) **Data**, **Maps** and **Mp3** directories from
Heroes III to:
<!-- -->
~/Library/Application\ Support/vcmi/
# Connect to the mod repository (optional)
- If that's your first installation, connection to the mod repository
will be configured automatically, you'll see mods available to
install from VCMI launcher
- We recommend you to install VCMI extras to support different
screen resolutions and active various helpful UI tools
- If you don't see mods available to install, go to settings tab
of the launcher and make sure that you have correct link in
"repositories" text field:
- <https://raw.githubusercontent.com/vcmi/vcmi-mods-repository/de