mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
Imported all data from website wiki
This commit is contained in:
62
docs/Frequently asked questions.md
Normal file
62
docs/Frequently asked questions.md
Normal 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
79
docs/Main Page.md
Normal 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
164
docs/TODO list.md
Normal 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).
|
BIN
docs/developers/Architektura.png
Normal file
BIN
docs/developers/Architektura.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
BIN
docs/developers/BattleField.png
Normal file
BIN
docs/developers/BattleField.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 135 KiB |
140
docs/developers/Bonus system.md
Normal file
140
docs/developers/Bonus system.md
Normal 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
|
213
docs/developers/Code_structure.md
Normal file
213
docs/developers/Code_structure.md
Normal 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")
|
972
docs/developers/Coding Guidelines.md
Normal file
972
docs/developers/Coding Guidelines.md
Normal 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)
|
49
docs/developers/Development_with_Qt_Creator.md
Normal file
49
docs/developers/Development_with_Qt_Creator.md
Normal 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!)
|
117
docs/developers/How to build VCMI (Android).md
Normal file
117
docs/developers/How to build VCMI (Android).md
Normal 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`.
|
217
docs/developers/How to build VCMI (Linux).md
Normal file
217
docs/developers/How to build VCMI (Linux).md
Normal 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
|
165
docs/developers/How to build VCMI (Visual Studio 2015).md
Normal file
165
docs/developers/How to build VCMI (Visual Studio 2015).md
Normal 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.**
|
258
docs/developers/How to build VCMI (Windows Vcpkg).md
Normal file
258
docs/developers/How to build VCMI (Windows Vcpkg).md
Normal 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)
|
111
docs/developers/How to build VCMI (iOS).md
Normal file
111
docs/developers/How to build VCMI (iOS).md
Normal 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).
|
170
docs/developers/How to build VCMI (macOS).md
Normal file
170
docs/developers/How to build VCMI (macOS).md
Normal 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
|
201
docs/developers/Logging API.md
Normal file
201
docs/developers/Logging API.md
Normal 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.
|
BIN
docs/developers/Logging_Class_Diagram.png
Normal file
BIN
docs/developers/Logging_Class_Diagram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
352
docs/developers/Serialization.md
Normal file
352
docs/developers/Serialization.md
Normal 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.
|
832
docs/modders/Bonus/List of all bonus types.md
Normal file
832
docs/modders/Bonus/List of all bonus types.md
Normal 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.
|
16
docs/modders/Bonus/List of bonus duration types.md
Normal file
16
docs/modders/Bonus/List of bonus duration types.md
Normal 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
|
105
docs/modders/Bonus/List of bonus limiters.md
Normal file
105
docs/modders/Bonus/List of bonus limiters.md
Normal 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" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
25
docs/modders/Bonus/List of bonus propagators.md
Normal file
25
docs/modders/Bonus/List of bonus propagators.md
Normal 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.
|
20
docs/modders/Bonus/List of bonus range types.md
Normal file
20
docs/modders/Bonus/List of bonus range types.md
Normal 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.
|
21
docs/modders/Bonus/List of bonus sources.md
Normal file
21
docs/modders/Bonus/List of bonus sources.md
Normal 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
|
89
docs/modders/Bonus/List of bonus updaters.md
Normal file
89
docs/modders/Bonus/List of bonus updaters.md
Normal 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")
|
31
docs/modders/Bonus/List of bonus value types.md
Normal file
31
docs/modders/Bonus/List of bonus value types.md
Normal 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)
|
169
docs/modders/Building bonuses.md
Normal file
169
docs/modders/Building bonuses.md
Normal 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
|
||||||
|
```
|
66
docs/modders/Map objects/Creature bank.md
Normal file
66
docs/modders/Map objects/Creature bank.md
Normal 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 } ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
22
docs/modders/Map objects/Dwelling.md
Normal file
22
docs/modders/Map objects/Dwelling.md
Normal 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" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
101
docs/modders/Random map template.md
Normal file
101
docs/modders/Random map template.md
Normal 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
|
||||||
|
}
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
55
docs/players/Game mechanics.md
Normal file
55
docs/players/Game mechanics.md
Normal 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\]
|
63
docs/players/Installation on Android.md
Normal file
63
docs/players/Installation on Android.md
Normal 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.
|
158
docs/players/Installation on Linux.md
Normal file
158
docs/players/Installation on Linux.md
Normal 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)
|
51
docs/players/Installation on Windows.md
Normal file
51
docs/players/Installation on Windows.md
Normal 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.
|
98
docs/players/Installation on iOS.md
Normal file
98
docs/players/Installation on iOS.md
Normal 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
|
50
docs/players/Installation on macOS.md
Normal file
50
docs/players/Installation on macOS.md
Normal 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
|
Reference in New Issue
Block a user