mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Imported all data from website wiki
This commit is contained in:
parent
6ac0dabcab
commit
243094b1ea
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
|
Loading…
Reference in New Issue
Block a user