# About dev

### What is your name?

My name is Denis Makhortov. Sometimes I use `jalhund` nickname&#x20;

### Who are you?

Just a man who likes turn-based strategy and started to create his own in his spare time

### Tell more about you

When I was 17-18, I created my first game. It's Civilization Path ( you can find it in Google Play: <https://play.google.com/store/apps/details?id=com.DenisMakhortov.CivilizationPath>)

<figure><img src="/files/RgITIA9lrU7WwIgBzKNL" alt=""><figcaption><p>Civilization Path</p></figcaption></figure>

Yes, it's ugly and not beautiful. But there was many people who liked it. I was a student and decided to create another game, more interesting and customizable

After 1 year I released another game: Cold Path (Google Play link: <https://play.google.com/store/apps/details?id=com.DenisMakhortov.ColdPath>)

<figure><img src="/files/7p16CQRR2EtSrfCyiGNH" alt=""><figcaption><p>Cold Path</p></figcaption></figure>

It's too much better and detailed. Also you can create your own maps, scenarios and servers. Sources of the Map Editor and the Server are opened and available on github.\
You can read more about Cold Path creating here: <https://forum.defold.com/t/cold-path-turn-based-multiplayer-strategy/65722?u=denis_makhortov>

### How many people are developing the game?

I am alone, but I did not do everything alone.

The music was not created by me, its authors are listed in the About menu. Some in-game scenarios were not created by me, but by the players in the scenario editor. Their authors are also written in that menu

Also, a lot of cool ideas were written by the players. It will not be possible to write everyone, but know that I am very grateful to you for your support and help in development.

### What is the engine?

Game engine: Defold

Language: Lua

For things that are not available in the engine, it is possible to write native extensions in C/C++

I really like the engine, ideal for 2D games. At first, everything is difficult and incomprehensible, but over time, you begin to appreciate the speed of development and its other advantages.

### Is the game code open or closed?

The code of the game itself is closed. I do not plan to open it, since a lot of time was spent on development. There are purchases in the game itself, the money from them goes to rent servers, develop the game, etc.

The server code is open. The server is the core of the game with little scripts around. I opened it to give more options for players to change the gameplay. Now that the server code is open, anyone can run their own server and use it however they like.

The map editor code is open. Use it however you want.

**Can I take as a basis the code of the server or the map editor in order to make my own game based on it?**

Yes. I will be glad that there will be one more good game in the world

### Future plans?

Create Cold Path 2, but there is very little free time.


# Cold Path

Detailed information about the game

If you think that something needs to be added here, then feel free to write me by mail or discord


# Changelog

## 20.1

This update is aimed at fixing bugs from the previous version and adding some long-awaited features to the game.

* **Custom map loading fix**\
  In the new version of the game engine, some changes caused the old code to break, which led to incorrect loading of custom maps. The custom map loading system has been completely rewritten and now works properly.
* **Changing country flag**

  You can now change your country’s flag in the country menu.
* **Nuclear defense**

  A new building has been added – "ABM" (Anti-Ballistic Missile). It protects a province from a nuclear strike with a 90% success rate. To construct it, you first need to research the "Nuclear Defense" technology.
* **Science center II**

  A second-level Science Center has been added for faster research.
* **Vassalage without war**

  You can now offer another country to become your vassal without declaring war. The restriction that a country must have no more than 3 provinces has also been removed. This introduces the possibility of ultimatums and makes gameplay more convenient.
* **Improved ally summoning**

  A country can no longer automatically summon its allies into a war. On the next turn after a summon, all allies receive an invitation to join the war, and only if they accept will they participate.
* **Command list added**

  When opening the chat, a new button appears. Clicking it opens a convenient list of all server commands with their descriptions.
* **Main menu changes**

  The background image and some button backgrounds have been updated. A changelog section and links to the game’s Telegram and Discord communities have been added.
* **Number formatting**

  Numbers are no longer rounded as long as they are below 100,000.


# Army

Description of different weapons and tips for use

## Weapons

### Infantry

The infantry deals damage to the enemy and also loses a certain number from their army. Only infantry can conquer an enemy province.

Example with no bonuses:\
You are attacking 1000 enemy province army with 1001 army. You will win, conquer a province and there will be 1 of your army in it.

### Shell

When shelling, you inflict damage on the enemy, while you do not lose your army, but you lose cartridges.

### Tank

Tank deals 5000 damage to the enemy army and reduces the level of the enemy fortress by 2.

### Air attack

Deals certain damage and, with a certain chance, destroy a building in the province (exact values are available in the description of buildings)

### Chemical weapon

Deals 30% damage to the population and army in the enemy province

### Nuclear weapon

Destroys all population, army, buildings and make province Undeveloped Land. Also deals damage to the population and armies of neighboring provinces in the amount of 90%.\
To use a nuclear weapon, you need to unlock the Nuclear Weapon technology and accumulate 3 uranium


# Inflation

Inflation will start when the player accumulates the amount of money equal to income per turn \* 5

Inflation is expressed as a percentage, where the minimum value (0%) is income per turn \* 5, \_\_and the maximum value (95%) is income per turn \* 30.

Inflation reduces the player's income per turn.

### Example:

Luxembourg does not spend money. Data obtained by experimental verification in the game. Population growth was practically stopped (due to population growth by 31 turns, the income from the population should have been 775 instead of 774 without growth. This is insignificant and does not affect the overall picture)

| Turn | Money | Income per turn | Inflation |
| ---- | ----- | --------------- | --------- |
| 1    | 774   | 774             | 0%        |
| 6    | 4501  | 627             | 19%       |
| 15   | 9328  | 469             | 39%       |
| 31   | 15110 | 280             | 64%       |


# Ideology

Analysis of ideologies in game

### Republic

*There are no bonuses.*

You can don't change it if you have not yet decided on the tactics of the game or are afraid that the situation on the map will change greatly (for example, you will need to quickly switch to the ideology of Monarchy in order to be ready for defense)

### Trade Republic

*+100% gold per turn*\
*+200% maintain an army per turn*

It is worth using if you want to develop peacefully. The maintenance of the army is becoming very expensive, so it will be difficult to war. The income bonus is really big and will allow you to get much more money than with any other ideology.

### Democracy

*+100% population increase*\
*+50% science per turn*\
*-25% army attack*

If you need to increase population or increase science, then this ideology will be the most useful. The attack penalty will make the war more difficult. Ideology is best suited for peaceful play.

### Monarchy

*+50% to the defense of the country if there is at least one enemy who has an army larger than yours*\
*-50% science per turn*

Great for defense. But not suitable if you plan to quickly discover technology. The number of science gained per turn will be 2 times less!

### Theocracy

*Recruiting an army is 2 times cheaper (but not maintenance every turn. You cannot recruit an army if money is less than 0)*\
*There can be no revolt in your country*\
*If your capital is conquered, then you will instantly lose*

When playing with this ideology, remember: be careful and defend the capital as soon as you can. Always pay attention to whether there are neighboring sea provinces from which enemy can attack. Ideology is useful in that you will spend a lot less money on recruiting an army. This can be useful to quickly recruit a huge army and defeat the enemy. You can also hire as much as you normally would while saving money.

### Communism

*During an enemy infantry attack on your land province 20% damage is ignored, of the remaining 20% damage to your army is dealt immediately, 80% damage is evenly distributed across all your provinces (including the one that was attacked)*\
*-40% gold per turn from population*

This is perhaps the most difficult ideology to understand.\
About the first bonus: Now, when enemy attacking your province, instead of being inflicted on one province, it will be scattered across all your provinces. Damage is dispersed in direct proportion to your army in each of your provinces. The more army you have in a province, the more damage this province will take. Also other provinces will receive less damage (or not at all)

Example: a player's province takes 10,000 damage, 35% of which is ignored, leaving (1 - 0.35 = 0.65 = 65%) 6,500 damage. Further, 1,300 of them damage the province, the rest of the damage is scattered across all armies of all provinces of the player\
If the enemy attacks one province, then out of 10 000 damage he will inflict only 1300 damage on it. 5200 will be evenly distributed among all armies in all provinces. More armies in different provinces, the better, the attacked province takes less damage.

When to use this ideology? Best when defending a large country. When playing for small countries, the damage will simply have nowhere to scatter. And in the case of playing for a large country and having at least several provinces with an army, you can defend amazingly. If you use it correctly, then it will be impossible for enemy to conquer any province if enemy do not inflict damage comparable to the size of your entire army.

### Fascism

Tank factory produces two tanks for the price of one\
After you declare war on someone, your army gains an attack bonus +80% for 5 turns, after 5 turns your army gets a bonus to attack -25% until you declare war again

This ideology has 2 applications:

1. Produce tanks and sell them, so you can make good money
2. Use the bonus to attack to quickly defeat the enemy.


# Purchase issues solution

If you have any problems with internal purchases

### Game did not sync purchases

1. Close game(you can use Exit button in the game)
2. Turn on internet. Make sure there are no connection problems
3. Open game

Purchases should be made available. I advise you to check availability not in the Premium menu, but directly trying to access the game features (for example, open Scenario Editor)

### Wrong google account

The game checks for purchases from the default Google account. Check that default Google account is the account from which you made purchases. Default Google account is the first account added to the system

### If none of the above helps

If none of the above helped, then try clear game data and open game


# Adding custom translation to game

You can create and upload your translation to game

### Export translation files

First, you need to get the translation files of the game, so that later they can be changed and loaded into the game. Open: Settings - Dev Menu. Press Export translation files. A message will appear on the screen that the files were exported successfully.

![](/files/-MZmkIWUN9ATOdzkdi5c)

### Change translation

Next, you need to find the exported translation files and modify them. Open the file manager and find the files in path:\
`Android/data/com.DenisMakhortov.ColdPath/files/`

There will be several files in JSON format, they store the translation. You need to change their content.

For example, it was:

`"scenario": "Scenario",`

Became:

`"scenario": "my_cool_translation",`

I think enough changes for today. Save changes.

### Using translation in game

After changing the files, open game (or restart if it was not closed). Open the Settings. The Custom language will appear in the list of available languages, select it. If the Custom language does not appear, then check the JSON files in one of the JSON Parser Online, most likely the comma or quotes were removed when changing.

![](/files/-MZmmWBSJ3qMlZTsNbHd)

Custom translation completed successfully.

![](/files/-MZmmoJ69Zt3aCcE3uyS)

### How to add translation to official version of game?

If you have completed the translation and want me to add it to the official version of the game, then write to me by mail or in Discord. Send the translation files and write how I should indicate you in the menu About the game


# How to play LAN game?

### Game creator:

1. Distribute Wi-Fi hotspot
2. Start a single player game
3. Select **Open Server** in the game menu

### Client

1. Connect to Wi-Fi
2. Open **Join** menu
3. Connect to first server (Wi-Fi Local Server)

Try to connect to it, even if it is not updated by clicking the **Refresh** button and even if it says **Unknown server**

If it writes **Connection error**, check if you are connected to Wi-Fi


# Commands

Game commands

### Single

* /export - save current game state to json file (for debug)
* /ach - achievement animation (achievements in the game are not completed, there is only animation)
* /uuid - show uuid and write it to uuid.txt
* /draw\_adjacency - on/off the display of provinces that can be moved from the selected
* /music\_on - turn on music
* /music\_off - turn off music
* /nolags - no delays and freezes in multiplayer, but there must be a stable connection (default mode)
* /nodisconnect - there may be freezes and delays, but you can play with an unstable connection with a high ping (choose if you are often kicked in multiplayer)
* /profile \<seconds> - profile game performance over time and save the report to a file
* /hide \<seconds> - hide user interface

### Multiplayer

**For all servers**

* /help - show list of commands
* /ping - show ping
* /uuid - show uuid and write it to uuid.txt file
* /select - select province (for /setciv command)
* /load - load map and scenario from server to single
* /profile - profile game performance over time and save the report to a file
* /hide \<seconds> - hide user interface

**Commands of standard plugins, if not removed by server owners**

*Players*

* /players - list of players and display who clicked next button and who doesn't
* /m <ник> <сообщение> - personal message

*Premium*

* /rc - change civilization (no more 3 times per game)
* /pass - allow a player to join the official server even if they don't have a license
* /setcolor r g b - set civilization color (RGB 0 - 255). Example: /setcolor 255 0 0 - red
* /rtr - start voting to start a new game

*Admin*

* /kick - kick player
* /mute - mute player
* /unmute - unmute player
* /ban - ban player
* /banip - ban player by ip + standard ban
* /setmap - set next map
* /setscenario - set next scenario
* /nextgame - finish this game and start next
* /scenarios - scenarios list
* /shutdown - shutdown server
* /select - select province
* /setciv - set player on country chosen by command /select


# Scenario Editor

How to open Scenario Editor: Settings - Dev menu - Scenario editor.

1. Set map (map selection)
2. Load scenario (load any scenario from the existing ones. You can select some scenario and already based on it create your)
3. Edit scenario (yes, edit scenario)
4. Save scenario (JSON) (save the scenario in json format. Files of this format can be exported using the Load scenario button in Dev\_menu. This is the data format for loading the scenario in the game client)
5. Save scenario (Lua) (this scenario format is useful for those who want to create a scenario for their server. A file of this format can be dropped into the server scripts folder and played on the Internet using this script)
6. Menu (main menu of the game)

Now let's take a closer look at the Edit scenario menu.

1. Scenario settings (scenario settings. Here you can change the scenario name and start year)
2. List of civilizations (list of countries. Here you can add a new country, change the existing one or delete)
3. Provinces (open the map for editing provinces data)
4. Buildings (buildings editor)
5. Not ready yet.
6. Back

Let's go through these points in more detail:

1. Scenario settings. Scenario id is the name of the scenario. You can change it to any other. Year - start year. Technology level (0-21) - here you can specify the level of technologies open by default in the game
2. List of civilizations. Here is a list of countries. If you select a country from the list, you can change its name, color, or remove the country from the list. There is a Create button at the bottom - it adds a new country. Then you can edit it the way you need
3. Provinces. When you go here, a map opens. There are two buttons at the top. One is blank and the other has a pencil icon. If you click the first, then when you select a province, nothing will happen. And if the second, then when you click on a province, it will belong to the country that is written at the bottom of the screen. By clicking on the Civilization button, you can select a country from the list for editing or create a new one
4. Buildings.

   Change - select building\
   Control buttons:\
   1\) empty - nothing\
   2\) pencil icon - build selected building\
   3\) red cross - remove all buildings\
   4\) red pencil icon - remove selected building

Scenario creation in short:

1. Settings - Dev menu - Scenario editor Select a map and a scenario and edit
2. In the editor menu, do not forget to click the Save scenario (JSON) button to save the scenario data along the path that is at the bottom left. (if it does not save for you, then check the application permission to write files)
3. Go to Settings - Dev menu. Choose Load scenario. The script will automatically load in the same path as it is usually exported. You can delete a scenario using the Remove custom scenario button. The loaded script will appear in the game creation menu. It will be possible to select it in the same way as the ones built into the game (the scenario can still be selected for editing in the scenario editor. But after that you will definitely need to save it, delete the last one and load the file)

![](/files/-MYBFD0_pHp4Xo4W8NYX)


# Map Editor


# Overview

The map editor is a standalone open source application. The map editor, like the game itself, is created in the Defold game engine.

Default working folder:\
Windows: application folder\
Android: "Android/data/com.DenisMakhortov.ColdPathMapEditor/files/"

Sources: <https://github.com/JAlHund/cold-path-map-editor>

If you want to see console messages (for example, crashes and it's not clear why), you can download the Defold game engine, sources and open the map editor project in Defold


# Set image

In order to create a map, I highly recommend finding something to use as a source. (In this case, the map of the British Isles will be used. You can download it here: <https://raw.githubusercontent.com/JAlHund/cold-path-map-editor/main/source.png>)

Image requirements:\
1\) less than 4096x4096\
2\) Borders should be filled with pure black (RGB: 0, 0, 0)\
3\) Land provinces in pure white (RGB: 255, 255, 255)\
4\) Water provinces must be filled with this color (RGB: 180, 210, 236)

After you have found a suitable image, drop it into folder (for more details, see the Overview section) and rename it to source.png. Next, launch the editor and select Map Creator.

If the uploaded image is less than 4096x4096, then it will appear in the lower left corner. There is nothing wrong with that! Restrictions in the game will be set normally. Just the used space is less than the maximum

If you want to edit the map, then click Image Editor. In this menu, you can edit the image, save it (not the map itself, map image, the modified image that you loaded) using the Save button or load it using the Load button

Description of the buttons on the screen:

1. Tool: nothing (view), pencil, line
2. Color: color of land provinces, color of borders, color of water
3. Pencil size

![](/files/-MYBOx-qJn-cRsq9X-ba)


# Setting up provinces

When you think the map is drawn correctly, press back (if you are in the image editing menu). Next, click Autogenerate. The editor will automatically divide the map into provinces. If you want to combine territories into one province (for example, islands), then click the Province Editor, click on the dropper icon at the top, click on the province to which you want to assign something. The color will be captured, then click on the top F (fill) and click on the territory that you want to refer to the province Usually autogeneration does a good job if the map is drawn correctly.

The New province button sets the fill color to the new color of the land province. (In the map editor at this stage, each territory should have its own unique color, since the editor distinguishes provinces by it. If different territories have the same color, the editor will count them as one province. He also divides provinces by color. If a province water, then its blue color in RGB format must be greater than or equal to 225) If autogeneration did not fill the required territory, and you want it to have a land border. Then press this button and fill the desired territory. The New water button sets the fill color to the new color of the water province.

After you have done everything, click the Export map button and wait, all the necessary files will be written to the exported\_map folder

![](/files/-MYBPS2l5XE0oypvM6FM)


# Checking map in editor

To check how the map will look in the game, close the editor, reopen and select the Map editor

You will have a map loaded as it will look in the game. Also in this mode you can change the center of the province (where the icons will be drawn from). To do this, click on the rectangle to the right of the Change offset label. If rectangular green - the mode of changing the center of the province is on, if red - off. You can change the center of a province by clicking on it

Attention! Changes are saved when you click on the mode switch at the top. After you change the center of the provinces, be sure to click on that button


# Loading into game

After you have created a map, you need to move it to special folder to load it. The always up-to-date path is written in the lower left corner in the scenario editor.

At the moment it is:\
Android: Android/data/com.DenisMakhortov.ColdPath/files/\
Windows: D:/ (Attention! On windows, the file should not be named exported\_map, but ColdPathexported\_map. Also with the scneario file. Not game\_data.json, but ColdPathgame\_data.json Not critical yet, but it would be nice to fix and auto-create the Cold Path folder if it is absent)

So, you have created a map, put it in special folder. Next, go to the game. New Game - Map - select Custom Map. You will see map you created. Scenario that is there is automatically generated. There is only one country in it. This scenario is needed only in order to make your own based on it. Therefore, next you need to open Scenario Editor, select a custom map (Custom map), and create your own scenario for this map. Next, you need to export it (Export to JSON), then load it (Load scenario in the Dev menu in the settings). Done! You can play your scenario on your map!

How to play online? Currently unavailable. It will be necessary to write a some check for map for the players who join + test it well. I'll make it later


# Limitations of editor

Limit on the number and size of provinces:\
\<number of provinces> - \<maximum size>\
1024 - 124x124\
256 - 252x252\
64 - 508x508\
16 - 1020x1020\
4 - 2044x2044\
(124x124 instead of 128x128 due to the extrude borders set to 2. This is to prevent incorrect texture mapping. See the Common texture problems section on the engine forum)

Example: you can create a thousand very small provinces (less than 124x124), but you can create only 4 sizes 1500x1500 (for example)

You cannot load a map image larger than 4096x4096. I have set this limitation. This map size should be sufficient. The larger the size of the map image is supported, the more textures need to be prepared for this, therefore the higher the device requirements (Can be changed in the source)

The game cannot handle more than 1024 provinces. This is the limit


# Contributing

The source code is completely open and available at the link: <https://github.com/JAlHund/cold-path-map-editor>\
Everyone can take part. But something tells me that only I will do, so I will write the basic rules for making a contribution:\
1\) Always test changes 2) One Pull Request - one task (to make it easier to check) This is the case if you want to push your changes to my repository. You can clone and do whatever you want.

To work on the editor, you need to download the Defold game engine, download the sources and open the map editor project in the engine.


# Tips for modifying sources

### Adjust provinces smoothing.

The map editor automatically applies the distance field method to improve the quality of the provinces and avoid the staircase effect. If the provincial boundaries are too smooth, then you can change the value in the file libs/drawpixels/src/drawpixels.cpp\
Below is an example of changing the blur strength from 2 to 1. You can adjust this as you need. Search for the blur function (search for "static uint8\_t \* blur") and find below:\
`int box = 2; // set 1 to have a 3x3 box`\
Change the value 2 to 1 (was `int box = 2;`, change to `int box = 1;)`

### Defold lags when working with the map editor.

Solution: open the main/main.script file and change the line `IMAGE_DATA_PATH = ""` with, for example, disk D `IMAGE_DATA_PATH = "D:/"` The main thing is that a folder outside the project is specified. Also delete the image\_data and exported\_map files in your project folder (save if you need them. This is the map image data and the exported map)

After changing IMAGE\_DATA\_PATH, the map data will not be saved to the project folder, but to the specified path. Fewer files in the project folder - fewer files are processed by Defold


# Global servers

What is global server?

#### How to create server?

1. Rent Vps server on Linux. I recommend Debian or Ubuntu, since the examples below will use commands that 100% work on these systems. It is possible to run on others, but you will have to make decisions on your own and deviate from the instructions.
2. Install dependencies and download server from github. This is the initial server setup and should only be done once.
3. Customize server.
4. Start server and play with friends

#### What can be changed on the server side?

1. Adding custom scenarios and maps
2. Creating plugins
3. Rewrite all game logic the way you want by changing lua files (for example, change the behavior of AI, buildings, and almost everything that is possible)

#### How to connect to server?

There is two ways:

1. Type ip:port in Direct connection section
2. Add your server to global servers list

In order for the server to be added to the list of servers, contact the game developer. The game server must also be:

1. Stable. No often bugs, crashes
2. Have rules and moderation. It is forbidden to ban for no reason or write obscene reasons for the ban
3. Do not bypass the in-game purchase system

Any players can connect to these servers immediately after downloading game, and if there is a mess there, they will have a bad impression of the game, which will affect the rating and purchases


# Create server

#### Rent server

First you need to rent a server (well, or use your computer if the provider allows it)

In this topic, I will try to write specific OS, in fact, this is not so important. I will disassemble the launch and configuration of the server on a specific Linux Debian so that there is no confusion. On all other systems, you can do by analogy

First you need to rent a suitable server. A VPS with 512 MB of RAM fits without problems. The game server is well optimized, you can keep one or more game servers, then this should be enough for you.

After you have bought it, you will receive an email with:

1. ip address of the server (which you will use to connect)
2. login and password OS: debian9 (you can use another, but in this topic it will be used)

#### Programs

In order to interact with the server on a PC, you need to download:

1. Putty - SSH client to connect to and manage server
2. Any FTP client (for example, FileZilla, if it is available on a rented server tariff. If FTP connection is not available, then download WinSCP)

You can also manage the server using your phone. For example, on Android, you can use the following programs:

1. Termius for connecting via ssh
2. CX explorer for working with server files via ftp or sftp

#### Initial server setup

So, you should write the this commands only once. This is the initial setting, you write these commands first, then you can forget about it

So, connect to the server via IP, enter the username and password.

Next, write commands (if it requires input and the inscription "Do you want to continue? \[Y / n]" appears, then press y on the keyboard)

Updating data about repositories

```
apt update 
```

Install LuaJIT

```
apt-get install luajit
```

Install LuaSocket:

```
apt-get install lua-socket
```

Install LuaSec

```
apt-get install lua-sec
```

Install Screen

```
apt-get install screen
```

Install the nano editor (to quickly edit the code in the console)

```
apt-get install nano
```

Installing Git to download the latest version of the server for Cold Path

```
apt-get install git
```

#### Server downloading and starting

We have not downloaded the server yet, and it is better to prepare for this. So, type the command

```
screen -S server1
```

(this is necessary so that when you exit the console, the server remains running in the background. It also helps a lot in that it helps to switch between open programs in the console. Read more about Screen utility in Internet)

Next, create a folder in which our server will be

```
mkdir server1
```

See elements in directory

```
ls
```

Okay, the folder has been created. Now let's move into it.

```
cd server1
```

We will drop our server into this folder. Write command to download the latest version of the server:

```
git clone https://github.com/JAlHund/cold-path-server
```

Or just upload the downloaded sources to the server in another way

We have downloaded a copy of game server to the server. Now let's go to game server folder

```
cd cold-path-server
```

See elements in directory

```
ls
```

Give permission to the script to run

```
chmod +x start.sh
```

Start server

```
./start.sh
```

As you can see, server has started, and now you can connect to it in the game

Select Direct Connection from the Join menu and write ip:port (example: 127.0.0.1:5555). Default port is 5555


# Customization

In the last topic, we started the server. Fine! We can now play on the standard version of the server. But I'm sure you now want to customize it for yourself.

Shut down the running server (Double CTRL + C. Make it fast)

Set time for turn

```
nano server_settings.lua
```

It's in seconds and defaults to 180. Let's change it to 210 so it's 3.5 minutes

Use the arrows on your keyboard to navigate to this number and change it (but don't type numbers on the Numpad, type them using the numbers above the letters)

Great, changed. Now you need to save.

Press CTRL+X

Then y

Then enter

So you can edit files on the server. You can edit a lot, a lot. Let's restart our server. Let's go to the main folder of the server. Starting the server

```
./start.sh
```

Now we can look at what is happening in the console. We can also minimize the current screen. Type on the keyboard: CTRL + A CTRL + D

We detached current screen

When connecting to a server after disconnecting, you will be in the same situation. To load the server screen again, type

```
screen -r server1
```

## How to add custom scenario

By default, the server has a map and scenario from the active parkourcat player. This is to make it easier for you to set up your custom maps and scenarios based on an existing example.

So, we want to add scenario to server (if you have just connected to the server, then do not forget to enter the `screen -r server1` command from the previous topic to go to the server screen. If you go and the server is running, then turn it off with the Double CTRL + C command)

First you had to create a scenario in the scenario editor and export it as a .lua file. You need to upload the resulting file to the server in the folder scripts/scenarios/

Next you need to decide:

1. you want this scenario to run when server starts
2. you want this scenario to be one of those scenarios that automatically starts after the end of the game

If first, then you need to edit start.lua file. Open this file with an editor

```
nano start.lua
```

Find line

```
game_data = require "scripts.scenarios.euro.std"
```

Change it to

```
game_data = require "scripts.scenarios.<карта>.<сценарий>"
```

Save it. (CTRL + X, type y, press enter)

If second, then we already need to edit the standard game\_switch plugin (you can also write your own plugins, but this is a separate and complicated topic. In order to write plugins, you need to program. But this opens up very great opportunities)

Go to core/server/plugins

```
cd core/server/plugins
```

Edit game\_switch plugin

```
nano game_switch.lua
```

Add scenario by analogy with the scenarios that have already been defined

CTRL + X. Enter y. Press enter

Go to server folder

```
cd ../../..
```

Start server

```
./start.sh
```

## How to add custom map

1. Create a map in Map Editor.
2. Create `maps` folder.
3. Rename `exported_map` folder to map id and place it in the `maps` folder.
4. Add your scenario made for this custom map to the server

Players do not need to install anything, the map will be loaded automatically when connecting server


# Plugins

The servers have different plugins. Each plugin is an independent entity. The plugin can track various server events, and also somehow respond to them using a list of commands defined by the server.

## How to install plugin

1. First way. Edit `plugins_list` table in plugins\_manager.lua
2. The same as the first one, but you can not specify the `data` field there, but only `order`, and throw the plugin itself with the .lua extension into `plugins` folder
3. The third way is the most convenient. Just drop plugin into `plugins` folder with the .lua extension, and it will automatically pick up. You no longer need to add them manually in a text editor, just move them to a folder. If you need to adjust the order of calling plugins (first one, then the other), then see the second method of application.

All use cases are in the plugin manager

## API

* `call_function` - call some function. This can be either a server-side function or a function of another plugin registered in the shared space.
* `register_function` - register a function, it can then be called using `call_function`. Useful to enable other plugins to get some info. For example, the system plugin defines a kick function with an appropriate message. And this ready-made function can be used by any other plugin
* `register_command` - register a command. For example, we want the player to receive the message abrakadabra when they enter the command /test
* `set_data` - set data (required for interaction between plugins)
* `get_data` - get data (needed for interaction between plugins). For example, you need to find out the player's nickname
* `remove_data` - remove data
* `send_data` - send data. You can send data to the client. True, the client will only respond to the data whose list is defined on its side. For example, you can use this plugin to force the player to update map data
* `set_server_state` - set the state of the server (ready, off, starting)
* `start` - start the server

### What events does the plugin track?

* `init` - server start
* `verify_registration` - player verification (the server checks whether to let the player into the game or not)
* `on_player_registered` - player registration on the server (when a player connects, he is given a country, he is added to the list of players)
* `on_player_joined` - moment when the player loaded the map (for example, sending him a request to display the rules before this moment does not make sense, because the player is in the menu)
* `on_player_disconnected` - player is disconnected
* `on_data` - receive data from client
* `before_next` - event before next turn
* `game_over` - game over
* `attribute_message` - message formatting

## Analyze standard afk plugin

```
-- it is necessary for the module to work
local M = {}

-- add timer module
local timer_module = require "core.timer"

-- variables for working with functions of other plugins or the server: send data, call a function, receive data
local send_data
local call_function
local get_data

-- table with data of the last synchronization with clients, store the timer and the last time
local last_sync = {
    -- client = {
    --     timer_id,
    --     last_time
    -- }
}

-- waiting for 30 seconds, if there is no answer, then kick
local afk_sec = 30

-- check client
local function check_client(client)
    -- if the current time minus the time of the last synchronization is more than 30 seconds, then kick
    if socket.gettime() - last_sync[client].last_time > afk_sec then
        call_function("kick", client, { "", get_data("clients_data")[client].name, "lost connection"})
    end
    -- send a message to the client to which he must respond
    local t = {
        type = "ping",
        data = {}
    }
    send_data(to_json(t), client)
end
-- called once at init. Here we define the functions we need
function M.init(api)
    send_data = api.send_data
    call_function = api.call_function
    get_data = api.get_data
end

-- called when a player registers
function M.on_player_registered(client)
    -- fill in the synchronization data of the new client
    last_sync[client] = {
        -- we create a timer that every 30 seconds checks for a connection
        timer_id = timer_module.every(afk_sec, function()
            check_client(client)
        end),
        last_time = socket.gettime()
    }
end

-- if the client is disconnected, then delete the data
function M.on_player_disconnected(client)
    last_sync[client].timer_id:remove()
    last_sync[client] = nil
end

-- if the player sent a response, then we update the synchronization data
function M.on_data(data, ip, port, client)
    if data.type == "pong" then
        last_sync[client].last_time = socket.gettime()
    end
end

return M
```


# Game Data

`game_data` is a global table with all data about the current game. You can directly work with it to change the behavior of the game on the server.

## How to find out what it contains

You can find out the contents of any table using the built-in function `debug_log(game_data)` it will write the result to the log file in the server root

## Change Tips

Try not to modify this file yourself, but use ready-made modules. For example, if you want two countries to start war with each other, then connect the relations module at the beginning of the plugin (relationships between countries)

```
local relations = require "core.relations"
```

And in the plugin code itself, at the right time, call

```
relations.register_war(land1, land2)
```

## game\_data summary

I won't list all the content here as it is very large. Only the main thing that may come in handy more often than others

| field      | short description |
| ---------- | ----------------- |
| difficulty | difficulty level  |
| queue      | sequence of moves |
| step       | current turn      |
| lands      | countries         |
| provinces  | provinces         |

**Country data**

Country data is stored in `game_data.lands[land_id]`, where land\_id is the country id (not the name, but the id)

The main, incomplete content of this table:

| field    | short description   |
| -------- | ------------------- |
| ideology | ideology            |
| money    | player's money      |
| economy  | income/expense data |
| allies   | allies              |
| enemies  | enemies             |

**Province data**

Province data is stored in `game_data.provinces[province]`, where province is the id of the province.

The contents of this table are:

| field | short description                                                                     |
| ----- | ------------------------------------------------------------------------------------- |
| water | is it water (true/false)                                                              |
| o     | id of the country that owns it                                                        |
| p     | population                                                                            |
| a     | table with data about the army in this province (key - country id, val - army number) |
| l\_a  | currently hired army that will be available next turn                                 |
| r     | table with resources (how to fill it in, you can see in the fill\_resources.lua file) |


# Tips

**Creating plugin**

To implement your plugin, take any existing one as a basis. Check existing features in standard plugins

**Remove license check on connection (make server free to join)**

Open `core/server/plugins/verifier.lua` and change `verification_mode` from `kick` to `ignore`

**How to rename map**

Change `id` field in map\_info.json file and `map` field in scenario.json file and in all other scenario files for this map, if they exist

For a map installed on the server, additionally change the name of the map folder and map reference in the game\_switch plugin and, if specified, in start.lua

**How to run a server on Windows**

Comment out the lines in `plugins_manager.lua` file where custom plugins are automatically loaded from the folder.

It was:

```
if not plugins_data.HOST_IS_PLAYER then
    load_custom_plugins()
end
```

It became:

```
--if not plugins_data.HOST_IS_PLAYER then
    --load_custom_plugins()
--end
```

**How ​​to run a server on Windows without luassl**

This way you will be able to start the server using only lua and luasocket.

Replace lines in files:

*verifier.lua*

```
local verification_mode = "kick"
```

***

```
local verification_mode = "ignore"
```

*server\_settings.lua*

```
verify_uuid = true,
```

***

```
verify_uuid = false,
```

*environment.lua*

```
ssl = require "ssl"
```

***

```
--ssl = require "ssl"
```

## Briefly about what can be changed on the server

On the server, you can change very, very much. You can't add a new resource because it doesn't exist on the client side. But it can be done that nuclear will make the land unsuitable for settlement forever.

You can rebalance the game however you like. You can override the behavior of existing buildings to your heart's content (but the client will see the army in the water provinces with a beacon, even if on the server side it does not give this bonus, because it is written into the code on the client side)

You can add custom scenarios to the server and play them without any problems. Perhaps there will be a lack of translation, but this can also be fixed if you export the translation data, add the translation into the necessary languages ​​and send it to the players so that they put this translation in the settings

## Project structure:

#### Root

.git - git data

assets - here are data about which province to which you can move on different maps

core - game core

defnet - network module

scripts - helpful scripts

.gitignore - what data should not be sent to the versioning system

admins.dat - admin list (uuid)

banned.dat - banned by uuid

banned\_ip.dat - banned by ip

chat.dat - chat history

convert\_to\_global.bat - bat file, which with one click translates the game sources into the server sources (they are slightly different). I need this thing purely for automation

convert\_to\_global.lua - the same as above, only here is the lua code, this thing is called by a bat file

environment - any global functions. Like displaying tables on the screen, functions for encoding data in JSON for sending over the network, and also defining global modules that should be available in all scripts, for example, luasocket

game\_data.json - current server save

log - server log. What plugins were loaded and when, when what actions took place

luaxxhash.lua - an auxiliary module that was needed to check whether the game data was received correctly on the devices (not used yet, but will come in handy if the data sending system is rewritten)

README.md - project description

server\_crash - crash log

server\_settings.lua - server settings (port, name, time to turn, etc.)

start.bat - bat file to start the server. Makes server restarts automatically after a crash

start.lua - lua script to start the server

start.sh - same as start.bat, only for linux

#### Core

ai - bots

server - main server script and plugins

army\_functions.lua - army actions. Hiring, moving, different types of weapons

buildings\_calc\_functions.lua - building actions processing module

calc\_functions - functions that are calculated every turn (how much money is spent on maintaining the army, how much the population will grow)

core.lua - core, all possible actions in the game are defined here. Depending on which game mode (server, client, single player) there is a certain shell above this script. For example, if the game mode is singleplayer and the player has moved an army, then the singleplayer module calls the core module and orders the change to be drawn on the map. If the player is on the server and not the host, then the client module sends a message to the server, and itself calls the core module to change the game data, because action is done

event\_system.lua - event system. Example: when someone declares war on someone, a function registered in this system is called. Now used only for the balance of power.

game\_values.lua - game values. For example, how much does it cost to hire an army, when inflation starts, how many turns can you change ideology

global\_functions.lua - global functions. For example, find the path from one province to another, find out the list of neighbors of the province, get the translation of any country, calculate country points

ideology.lua - a module that describes how ideologies work. For example, what is the bonus to gold depending on the chosen ideology or how the attack should proceed if communism is chosen

offers.lua - message system between countries. For example, someone sent someone a trade or declared war

relations.lua - relations between countries. Start a war, find out who is fighting with whom. Find out if a country is a vassal

timer.lua - timer module. So that every 3 minutes there is next turn or every 30 seconds the server checks the connection


# Common problems

#### Correction of incorrect display of Russian or others characters

<https://serverfault.com/a/894545>

You need to execute for all screens or execute in the root and then recreate the screens

#### Premium features not working for players

Check the verification\_server file in the server root to see if it matches the one on github. Or contact the developer

#### Server does not start

Try to start server using `./clear_start.sh` or `luajit start.lua` and check output


# О разработчике

### Кто такой jalhund?

Просто парень, который любит пошаговые стратегии, и начал пилить свою в свободное от учёбы время

### Расскажи о сбее

Когда мне было 17-18, я создал первую игру. Это Civilization Path ( вы можете найти ее здесь: <https://play.google.com/store/apps/details?id=com.DenisMakhortov.CivilizationPath>)

<figure><img src="/files/lgPmkqNtaDIMkQW9XIWS" alt=""><figcaption><p>Civilization Path</p></figcaption></figure>

Да, она не очень красивая. Но нашлось много людей, которым она понравилась. Я был студентом и решил создать другую игру: более интересную и детализированную

Спустя 1 год я выпустил новую игру: Cold Path (Google Play link: <https://play.google.com/store/apps/details?id=com.DenisMakhortov.ColdPath>)

<figure><img src="/files/OFHY4OOOQjNrFAvEWwDm" alt=""><figcaption><p>Cold Path</p></figcaption></figure>

Она намного лучше и детализированнее. Также вы можете создавать свои карты, сценарии и даже сервера. Исходники редактора карт и сервера доступны на github.\
Вы можете прочитать больше про создание Cold Path здесь: <https://forum.defold.com/t/cold-path-turn-based-multiplayer-strategy/65722?u=denis_makhortov>

### Сколько человек разрабатывает игру?

Я один, но делал в одиночку не абсолютно все.

Музыку создавал не я, ее авторы указаны в меню Об игре. Некоторые внутриигровые сценарии создавал не я, а игроки в редакторе сценариев. Их авторы также написаны в том меню

Также очень много крутых идей писали игроки. Всех расписать не получится, но знайте, что я вам очень благодарен за поддержку и помощь в разработке.

### На чем ты делаешь игру?

Игровой движок: Defold

Язык программирования: Lua

Для вещей, недоступных в движке, есть возможность писать нативные расширения на C/C++

Движок мне очень нравится, идеально подходит для 2D игр. Вначале все сложно и непонятно, но со временем начинаешь ценить скорость разработки и другие его преимущества

### Код игры открыт или закрыт?

Код самой игры закрыт. Открывать не планирую, так как на разработку было потрачено много времени. В самой игре есть покупки, деньги с них идут на аренду серверов, разработку игры и т.д.

Код сервера открыт. Сервер - это ядро игры с небольшими скриптами вокруг. Я открыл его, чтобы дать больше возможностей игрокам для изменения игрового процесса. Теперь, когда код сервера открыт, каждый может запустить свой сервер и использовать его, как душе угодно

Код редактора карт открыт. Используйте его, как хотите.

**Могу взять за основу код сервера или редактора карт, чтобы на его основе сделать свою игру?**

Да. Я буду рад, что в мире станет на одну хорошую игру больше

### Какие планы на будущее?

Запилить Cold Path 2, но времени свободного очень мало.


# Cold Path

Подробная информация по игре

Если вы думаете, что что-то нужно сюда добавить, смело пишите мне на почту или в дискорд


# Список изменений

## 20.1

Это обновление призвано исправить баги прошлой версии и добавить в игру некоторые возможности, которых игроки ждали очень давно.

* **Исправление загрузки кастомных карт**\
  В новой версии игрового движка произошли некоторые изменения, из-за которых старый код сломался и кастомные карты загружались неправильно. Загрузка кастомных карт была полностью переписана и теперь работает исправно.
* **Изменение флага страны**

  Теперь в игре можно изменить флаг вашей страны. Это можно сделать в меню страны.
* **Ядерная оборона**

  Добавлена новая постройка - "ПРО". Она защитит провинцию от ядерного удара с вероятностью 90%. Для её постройки необходимо сначала изучить технологию "Ядерная оборона".
* **Научный центр II**

  Добавлен Научный центр 2-го уровня для более быстрого изучения науки.
* **Вассалитет без войны**

  Теперь можно предложить стране стать вашим вассалом без объявления войны, а так же убрано условие что у страны должно быть не больше 3 провинций. Это добавляет возможность делать ультиматумы и делает игру более удобной.
* **Улучшен призыв союзников**

  Теперь страна не может автоматически призвать своих союзников в войну. На следующем ходу после призыва всем союзникам отправится предложение вступить в войну и только если они согласятся, они присоединятся к войне.
* **Добавлен список команд**

  При открытии чата появляется новая кнопка. При нажатии открывается удобный список всех команд на сервере с их описанием.
* **Изменено главное меню**

  Изменен фоновое изображение, фон некоторых кнопок, добавлен список изменений и ссылки на Telegram и Discord сообщества игры.
* **Формат чисел**

  Теперь числа не округляются пока они меньше 100 000.


# Армия

Описание разного оружия и советы по использованию

## Виды оружия

### Пехота

Пехота наносит урон врагу, а также теряет определенное число от своей армии. Только пехотой можно захватить вражескую провинцию.

Пример с отсутствием бонусов:\
Вы атакуете армией 1001 вражескую провинцию, где 1000 армии врага. Вы победите, захватите провинцию и в ней будет 1 вашей армии.

### Обстрел

Обстреливая, вы наносите урон противнику, при этом не теряете свою армию, но теряете патроны.

### Танк

Танк наносит 5000 урона вражеской армии, а также уменьшает уровень вражеской крепости на 2.

### Самолет

Наносит определенный урон и с определенным шансом сносит постройку в провинции (точные значения доступны в описании построек)

### Химические оружие

Наносит урон в 30% населению и армии во вражеской провинции

### Ядерное оружие

Уничтожает все население, армию, постройки и превращает провинцию в Неосвоенные земли. Также наносит урон населению и армии соседних провинций в размере 90%.\
Чтобы использовать ядерное оружие, вам нужно открыть технологию "Ядерное оружие" и накопить 3 урана


# Инфляция

Инфляция начнется, когда игрок накопит число денег, равное доходу за ход \* 5

Инфляция выражается в процентах, где минимальное значение (0%) - доход за ход \* 5, а максимальное (95%) - доход за ход \* 30.

Инфляция уменьшает доходы игрока за ход.

### Пример:

Игрок за Люксембург не тратит деньги. Данные получены экспериментальной проверкой в игре. Рост населения был практически остановлен (из-за роста населения на 31 ход доход от населения должен был бы быть 775 вместо 774 без роста. Это незначительно и не влияет на общую картину)

| Ход | Число денег | Доход за ход | Инфляция |
| --- | ----------- | ------------ | -------- |
| 1   | 774         | 774          | 0%       |
| 6   | 4501        | 627          | 19%      |
| 15  | 9328        | 469          | 39%      |
| 31  | 15110       | 280          | 64%      |


# Идеологии

Разбор идеологий в игре

### Республика

*Нет никаких бонусов и никаких штрафов.*

Ее можно оставить и не менять на другую идеологию, если вы еще не определились с тактикой игры или опасаетесь, что ситуация на карте сильно поменяется (например, нужно будет быстро переключиться на идеологию Монархия, чтобы быть готовым к обороне)

### Торговая Республика

*+100% к золоту за ход от налогов*\
*+200% к содержанию армии за ход*

Ее стоит использовать в том случае, если вы хотите развиваться мирно. Содержание армии становится очень дорогим, поэтому воевать будет тяжело. Бонус к доходу действительно большой и позволит вам скопить намного больше денег, чем с какой-либо другой идеологией.

### Демократия

*+100% к росту населения*\
*+50% к росту науки*\
*-25% к атаке армии*

Если вам нужно восстановить население или прокачать науку, то эта идеология окажется самой полезной. Штраф к атаке усложнит ведение войны. Идеология лучше всего подходит для мирной игры.

### Монархия

*+50% к обороне страны, если есть хоть один враг, у которого армия больше, чем у вас*\
*-50% к науке за ход*

Отлично подходит для обороны. Но не подходит, если планируете быстро открывать технологии. Число науки, получаемой за ход, станет меньше в 2 раза!

### Теократия

*Найм армии дешевле в 2 раза (но не содержание каждый ход. Нельзя нанимать армию, если баланс меньше 0)*\
*В вашей стране не может произойти восстание*\
*Если вашу столицу захватят, то вы мгновенно проиграете*

При игре с этой идеологией нужно помнить всегда следующее: будьте внимательны и защищайте столицу, как только можете. Всегда обращайте внимание, нет ли соседних морских провинций, с которых могут атаковать. Идеология полезна тем, что вы будете тратить намного меньше денег на найм армии. Это может пригодиться, чтобы быстро нанять огромную армию и разгромить врага. Также можно нанимать столько, сколько вы нанимаете обычно, при этом экономить деньги.

### Коммунизм

*Во время нападения вражеской пехоты на вашу сухопутную провинцию 20% урона игнорируются, из оставшегося 20% урона по вашим войскам наносится сразу, 80% урона равномерно распределяются по всем вашим провинциям (в том числе по той, которую атаковали)*\
*-40% дохода за ход*

Это, пожалуй, самая сложная для понимания идеология.\
Сразу про первый бонус кратко: Теперь при атаке вашей провинции урон вместо того, чтобы нанестись по одной провинции, будет рассеиваться по всем вашим провинциям. Рассеивается урон прямо пропорционально вашей армии в каждой из ваших провинций. Т.е. чем больше у вас армии в провинции, тем больше эта провинция получит урона. Но зато меньше урона получат другие провинции (или вообще не получат)

Пример: провинция игрока получает 10 000 урона, из них 35% игнорируется, остается (1 - 0.35 = 0.65 = 65%) 6 500 урона. Далее из них 1 300 бьет по провинции, остальной урон рассеивается по всем армиям всех провинций игрока\
Если враг атакует в одну провинцию, то он из 10к нанесет по ней урона гарантированно только 1300. 5200 равномерно распределится по всем армиям во всех провинциях. Т.е. чем больше разных армий в разных провинциях, тем лучше, т.к. меньше урона получает провинция, которую атаковали.

Когда использовать эту идеологию? Лучше всего при обороне за крупную страну. При игре за маленькие страны урону будет просто некуда рассеиваться. А в случае игры за крупную страну и наличии, как минимум, нескольких провинций с армией, можно потрясающе обороняться. Если грамотно пользоваться, то у вас невозможно будет захватить никакую провинцию, если не нанести урон, сравнимый с размером всей вашей армии.

### Фашизм

*Танковый завод производит два танка по цене одного*\
*После того, как вы объявляете кому-то войну, ваша армия получает бонус +80% к атаке на 5 ходов, после 5 ходов ваша армия получает -25% бонус к атаке до тех пор, пока вы снова не объявите войну*

У этой идеологии есть 2 варианта применения:

1. Производить танки и продавать их, так можно неплохо заработать денег
2. Использовать бонус к атаке, чтобы быстро разгромить противника.


# Детальный гайд по ведению войны

## Перемещение войск

### Порядок выполнения приказов

Приказы выполняются в порядке их выдачи. Это означает, что если вы вначале нажали кнопку танк на соседней вражеской провинции, а потом переместили туда армию, то всегда вначале туда приедет танк, нанесет урон и снесет крепость, и только потом туда придет ваша армия.

Из этого следует, что выгоднее использовать обстрел/химическое оружие/танк/самолеты/ядерное оружие перед тем, как перемещать свою армию туда. **Вначале используйте одно из видов оружия выше и только потом перемещайте пехоту, тогда атака будет эффективнее**

Этот принцип также распространяется на мультиплеер. Если Вы и ваш союзник перемещаете армию в одну провинцию, то первой в эту провинцию придет армию того, кто первый из вас отдал приказ о перемещении

### Как нужно перемещать армию

Игрокам часто непонятно, почему их провинции захватывают, когда они отдают приказ о перемещении. Разберем все это на примерах.

#### Атака с соседней провинции.

Игрок атаковал вражескую провинцию. Он захватил вражескую провинцию, но потерял свою. Почему? Это означает, что враг отдал приказ переместиться в южную беззащитную провинцию игрока до того, как армия игрока с севера напала на вражескую провинции.

**Как не нужно делать**

Оставлять незащищенной провинцию, в которую враг может успеть напасть:

![](/files/-MahhVFiDYFh_kwaFeLx) ![](/files/-MahhfkOpnEgit9Fgqzi)

**Как нужно делать**

Оставлять какое-то число армии в провинции, чтобы она была защищена

![](/files/-MahiYYkJDyUiQXygPea) \*\*\*\*![](/files/-Mahi_dvIZQBwYNCnLq9)

Атаковать превосходящими силами со всех провинций, куда враг может атаковать

![](/files/-Mahj2OBexbGm8is9jl8) ![](/files/-Mahj3p-b1VYVdQhpGKP)

Я надеюсь, что принцип понятен. В этой игре нужно держать фронт. Всегда держите армию в провинциях, которые находятся на границе с врагом.

### Найм армии происходит за один ход

Игрок нанял большую армию и атакует провинцию другого игрока, в которой нет армии, и почему-то проигрывает. В чем дело? Враг успел нанять армию. Армия, которая находится в процессе найма, превращается в настоящую армию в начале каждого хода еще до того, как обработается перемещение армии. Это означает, что если вы нанимаете 5 000 армии в провинции, то в этой провинции будет 5 000 армии еще до того, как произойдет атака врага

С ботами это работает так же, как и с игроками.

#### Пример

Игрок атакует большим числом войск вражескую провинцию, в которой нет армии. Но он не знает, что другая страна нанимает армию в этой провинции

![](/files/-MahlN9Gk-cVBBkcRxi6)

В это время другой игрок на другой стране нанимает армию.

![](/files/-Mahld7bB7uzqqyK89mI)

Происходит следующий ход. Исход боя предсказуем. Первый игрок не смог захватить провинцию, т.к. второй успел нанять армию

![](/files/-MahlmzAU_xox-TkOykB)

## Тактики ведения боя

### Глухая оборона

Используйте крепости, чтобы получить большой бонус к обороне. Делайте все, чтобы не было возможности пробить вашу оборону. Враг будет атаковать вас с очень большими потерями.

**Когда использовать:** Если враг намного сильнее вас

![](/files/-Maho7dNxrmuTTQXggZI)

### Контроль

Держите небольшое число армии в воде, чтобы заставлять противника нанимать армию на береговых провинциях и тратить деньги на ее содержание. Если же противник оставит мало армии в береговых провинциях, атакуйте все подряд (как на скрине) или найдите одну и атакуйте ее достаточно большой армией, чтобы пробить оборону

**Когда использовать:** Если у врага много береговых провинциях и вы хотите заставить его тратить много денег на содержание армии

![](/files/-MahpVhLwMdjOoF498Lp)

### Атака по всей линии фронта

Атакуйте врага из каждой своей провинции во всех возможных направлениях превосходящими силами, чтобы не дать врагу ответной атакой пробиться и захватить одну из ваших провинцию

Если какая-то из атак окажется провалена, то вы потеряете некоторое время на найм армии, а еще вам нужно будет держать армию в большем числе провинций, чтобы вас не пробили.

**Когда использовать:** Если у вас намного больше армии, чем у врага, и каждая отдельная ваша атака из многих обязательно окажется успешной.

![](/files/-MahrGlRbyP-0_itj5dF)

### Концентрация сил на одном направлении

Оставьте большую часть провинций в обороне, выберите вражескую провинцию, которую нужно захватить. Соберите превосходящие силы в соседних своих провинциях и атакуйте конкретную вражескую провинцию

За счет того, что вы наступаете не по всей линии фронта, а только на одну провинцию, вы можете собрать большое число армии для атаки именно этой конкретной провинции. Все остальные провинции держите в обороне, что позволит вам нанимать много армии не в них, а только в нужных

**Когда использовать:** Когда ваши силы ограничены, но вам нужно атаковать. Желательно, когда у вас есть возможность атаковать одну вражескую провинцию с нескольких направлений

![](/files/-MahsXVSq_xuPSU5AxSL)

### Прорыв

Вы можете собрать много армии и пробиваться внутрь врага, пробивая его оборону.

Из-за того, что внутри страны противника будет вражеская провинция, ему придется ее окружать, чтобы захватить. Это означает, что противнику придется потратить много денег на найм армии.

Из-за того, что вы будете перемещаться внутри провинции врага, вы можете сносить его постройки, получая деньги и разрушая экономику противника.

На скрине показан принцип атаки: основные силы (2633) перемещаются в одну из соседних провинций. Эта атака должна быть успешна в любом случае. Еще происходит много небольших атак в разные направления (5-39). Они проводятся на тот случай, если враг забудет нанять армию в своих провинциях.

**Когда использовать:** Когда нужно подорвать экономику противника или отвлечь его основные силы

![](/files/-MahuEqZslTD76ehGSRL)


# Решение проблем с покупками

Если вы столкнулись с какими-либо проблемами при совершении внутренних покупок

### Игра не синхронизирует покупки

1. Закройте игру (вы можете использовать кнопку Выход в игре)
2. Включите интернет. Убедитесь, что нет проблем с соединением
3. Откройте игру

Покупки должны стать доступны. Я советую проверять доступность покупок не в меню Premium, а пытаясь напрямую получить доступ к игровым функциям (например, открыть редактор сценариев)

### Неверный аккаунт Google

Игра проверяет покупки для аккаунта Google по умолчанию. Убедитесь, что аккаунт Google по умолчанию - это тот аккаунт, с которого вы совершали покупки. Аккаунт Google по умолчанию - это первый аккаунт Google, добавленный в систему

### Если ничего из перечисленного выше не помогло

Если ничего из перечисленного выше не помогло, попробуйте очистить данные игры и открыть игру


# Как играть по локальной сети?

### Создатель игры:

1. Раздает точку доступа Wi-Fi
2. Начинает одиночную игру
3. Выбирает **Открыть сервер** \_\*\*\*\*\_в меню игры

### Клиент

1. Подключается к Wi-Fi
2. Заходит в меню **Присоединиться**
3. Подключается к первому серверу (Wi-Fi Local Server)

Пробуйте подключиться к нему, даже если он не обновляются по нажатию кнопки **Обновить** и даже если там написано **Unknown server**

Если пишет **Connection error**, проверьте, подключены ли вы к Wi-Fi


# Как перевести игру на свой язык?

В игре можно создавать и загружать свой перевод

### Экспорт файлов перевода

Вначале нам необходимо получить файлы перевода игры, чтобы позже их изменить и подгрузить в игру. Переходим в следующие меню: Настройки - Dev Menu. Далее нажимаем кнопку Export translation files. На экране появится надпись, что файлы были экспортированы успешно.

![](/files/-MZmkIWUN9ATOdzkdi5c)

### Изменение перевода

Далее нам нужно найти экспортированные файлы перевода и изменить их. Открываем файловый менеджер и находим файлы по следующему пути: `Android/data/com.DenisMakhortov.ColdPath/files/`

Там будет несколько файлов в формате JSON, в них хранится перевод. Нам нужно изменить их содержимое.

Например, было:

`"scenario": "Scenario",`

Стало:

`"scenario": "my_cool_translation",`

Пожалуй, достаточно изменений на сегодня. Сохраняем изменения.

### Использование перевода в игре

После изменения файлов заходим в игру (или перезапустите, если она не была закрыта). Далее открываем Настройки. В списке доступных языков появится язык Custom, выбираем его. Если же язык Custom не появился, то проверьте файлы JSON в одном из JSON Parser Online, скорее всего при изменении была удалена запятая или кавычки.

![](/files/-MZmmWBSJ3qMlZTsNbHd)

Пользовательский перевод успешно завершен.

![](/files/-MZmmoJ69Zt3aCcE3uyS)

### Как добавить перевод в официальную версию игры?

Если вы выполнили перевод и хотите, чтобы я добавил его в официальную версию игры, то напишите мне на почту или в Discord. Пришлите файлы перевода и напишите, как я должен указать вас в меню Об игре


# Команды

Команды, доступные в игре

### Одиночная игра

* /export - записать текущее сохранение в файл.json (для поиска ошибок в игре)
* /ach - анимация получения достижения (достижения в игре не доделаны, есть только анимация)
* /uuid - отобразить uuid на экране и записать его в файл uuid.txt
* /draw\_adjacency - вкл/выкл отображение провинций, на которые можно перейти из выбранной
* /music\_on - включить музыку
* /music\_off - выключить музыку
* /nolags - нет задержек и подвисаний в мультиплеере, но должно быть стабильное соединение (режим по умолчанию)
* /nodisconnect - могут быть подвисаний и задержки, но играть можно при нестабильном соединении с большим пингом (выбирайте, если вас часто кикает в мультиплеере)
* /profile - профилировать производительность игры в течение определенного времени и сохранить отчёт в файл
* /hide \<seconds> - спрятать интерфейс

### Мультиплеер

**Для всех серверов**

* /help - отобразить список команд в игре
* /ping - проверить пинг
* /uuid - отобразить uuid на экране и записать его в файл uuid.txt
* /select - выбрать провинцию для того, чтобы потом с ней взаимодействовать
* /load - загрузить карту и сценарий с сервера в одиночную игру
* /profile - профилировать производительность игры в течение определенного времени и сохранить отчёт в файл
* /hide \<seconds> - спрятать интерфейс

**Команды стандартных плагинов, если не вырезаны владельцами сервера**

*Players*

* /players - список игроков и отображение, кто нажал след. ход, а кто нет
* /m <ник> <сообщение> - личное сообщение

*Premium*

* /rc - сменить страну (не более 3-х раз за игру)
* /pass <ник> - разрешить игроку зайти на официальный сервер, даже если у него нет лицензии
* /setcolor r g b - установить цвет страны (RGB 0 - 255). Пример: /setcolor 255 0 0 - красный
* /rtr - начать голосование за начало новой игры

*Admin*

* /kick <ник> - кикнуть
* /mute <ник> - замутить
* /unmute <ник> - снять мут
* /ban <ник> <длительность в часах> - забанить
* /banip <ник> <длительность в часах> - забанить по IP + стандартный бан
* /setmap <карта> - установить след. карту
* /setscenario <карта> <сценарий> - установить след. сценарий
* /nextgame - закончить эту игру и начать следующую
* /scenarios - список сценариев
* /shutdown - выключить сервер


# Редактор сценариев

Зайти в редактор сценариев можно следующим образом: Настройки - Dev menu - Scenario editor. Дальше на экране появится меню редактора. Сейчас распишу меню редактора понятным языком. Все Dev menu (меню разработчика) сделано на английском языке. Я не знаю, буду ли переводить эту часть или нет, не хотелось бы увеличивать размер данных, необходимых для перевода игры.

1. Set map (выбор карты)
2. Load scenario (загрузить какой-либо сценарий из существующих. Можно загрузить опред. сценарий и уже на его основе создать свой)
3. Edit scenario (редактировать сценарий)
4. Save scenario (JSON) (сохранить сценарий в формате json. Файлы этого формата можно экспортировать с помощью кнопки Load scenario в Dev\_menu. Это формат данных для загрузки сценария в клиенте игры)
5. Save scenario (Lua) (этот формат сценариев пригодится тем, кто хочет создать сценарий для своего сервера. Файл этого формата можно будет закинуть в папку сценариев сервера и играть по интернету на этом сценарии)
6. Menu (выйти в главное меню игры)

Теперь разберем подробнее меню Edit scenario (редактировать сценарий).

1. Scenario settings (настройки сценария. Здесь можно изменить название сценария и год начала)
2. List of civilizations (список стран. Тут можно добавить новую страну, изменить существующую или удалить)
3. Provinces (открыть карту для редактирования принадлежности провинций)
4. Buildings (редактор построек)
5. Еще не готово. Тут можно будет добавить что-то еще
6. Back (назад)

Пройдем по этим пунктам еще подробнее:

1. Scenario settings. Здесь существует следующее: Scenario id - это название сценария. Вы можете его изменить на любой другой. Year - год начала. Technology level (0-21) - здесь можно указать уровень технологий, открытых по умолчанию в игре
2. List of civilizations. Здесь находится список стран. Если выбрать какую-то страну из списка, то можно изменить ее название, цвет или удалить страну из списка. Внизу есть кнопка Create - она добавляет новую страну. Дальше вы можете ее отредактировать так, как вам нужно
3. Provinces. При переходе сюда открывается карта. Сверху есть две кнопки. Одна пустая, а вторая со значком карандаша. Если нажать первую, то при выборе провинции ничего происходить не будет. А если вторую, то при клике на провинцию она станет принадлежать той стране, что написана внизу экрана. При нажатии на кнопку Civilization можно выбрать страну из списка для редактирования или создать новую
4. Buildings.

   Change - выбрать другую постройку

   Кнопки управления:

   1\) пустая - ничего

   2\) значок карандаша - строить выбранную постройку при нажатии на провинцию

   3\) красный крестик - снести все постройки при нажатии на провинцию

   4\) красный значок карандаша - снести выбранную постройку при нажатии на провинцию

Создание сценария кратко:

1. Настройки - Dev menu - Scenario editor Выбираете карту и сценарий и редактируете
2. В меню редактора не забываете нажать кнопку Save scenario (JSON), чтобы сохранить данные сценария по пути, который снизу слева. (если у вас не сохраняет, то проверьте разрешение приложения на запись файлов)
3. Заходите в Настройки - Dev menu. Выбираете Load scenario. Сценарий автоматически загрузится по тому пути, по которому обычно экспортируется. Удалить сценарий можно кнопкой Remove custom scenario. Загруженный сценарий появится в меню создания игры. Его можно будет выбирать точно так же, как и встроенные в игру (сценарий можно будет еще выбрать для редактирования в редакторе сценариев. Но после этого обязательно нужно будет его сохранить, удалить последний и загрузить файл)

![](/files/-MYBFD0_pHp4Xo4W8NYX)


# Редактор карт


# Обзор

Редактор карт является отдельным приложением с открытыми исходниками. Редактор карт, как и сама игра, создан в игровом движке Defold.

Рабочая папка по умолчанию:\
Windows: папка приложения\
Android: "Android/data/com.DenisMakhortov.ColdPathMapEditor/files/"

Исходники редактора: <https://github.com/JAlHund/cold-path-map-editor>

Если вы хотите увидеть сообщения консоли (например, вылетает и не понятно почему), вы можете скачать игровой движок Defold, исходники и открыть проект редактора карт в нем


# Установить изображение

Установка и редактирование изображения

Для того, чтобы создать карту, я очень рекомендую найти что-то, что вы возьмете за основу. (В данном случае будет использоваться карта британских островов. Скачать ее можно тут: <https://raw.githubusercontent.com/JAlHund/cold-path-map-editor/main/source.png>)\
Требования к изображению:\
1\) меньше 4096x4096\
2\) Границы должны быть залиты чистым черным (RGB: 0, 0, 0)\
3\) Сухопутные провинции чистым белым (RGB: 255, 255, 255)\
4\) Водные провинции должны быть залиты этим цветом (RGB: 180, 210, 236)

После того, как вы нашли подходящее изображение, закиньте его в нужную папку (подробнее разделе Обзор) и переименуйте в source.png\
Далее запустите редактор и выберите Map Creator.

Если загруженное изображение меньше 4096x4096, то оно появится в левом нижнем углу. В этом ничего страшного нет! Ограничения в игре выставятся нормально. Просто используемое пространство меньше максимального

Если вы хотите отредактировать карту, то нажмите Image Editor. В этом меню вы можете редактировать изображение, сохранять его (не саму карту, а именно изображение карты, модифицированное изображение, которые вы загрузили) с помощью кнопки Save или подгружать с помощью кнопки Load

Описание кнопок на скрине:

1. Инструмент: ничего (просмотр), карандаш, линия
2. Цвет: цвет сухопутных провинций, цвет границ, цвет воды
3. Размер карандаша

![](/files/-MYBOx-qJn-cRsq9X-ba)


# Настройка провинций

Когда вы считаете, что карта нарисована верно, нажмите back (если вы в меню редактирования изображения). Далее, нажмите Autogenerate. Редактор автоматически поделит карту на провинции. Если вы хотите объединить территории в одну провинцию (например, острова), то нажмите Province Editor, нажмите на значок пипетки сверху, кликните по провинции, к которой хотите отнести что-то. Цвет будет захвачен, далее нажмите сверху F (заливка) и кликните по территории, которую хотите отнести к провинции Обычно автогенерация хорошо справляется, если карта правильно нарисована.

Кнопка New province устанавливает цвет заливки в новый цвет сухопутной провинции. (в редакторе карт на этом этапе у каждой территории должен быть свой уникальный цвет, т.к. редактор различает провинции по нему. Если у разных территорий один цвет, редактор будет считать их за одну провинцию. Также он делит провинции по цвету. Если провинция водная, то у нее цвет blue в формате RGB должен быть больше или равен 225) Если автогенерация не залила нужную территорию, а вы хотите, чтобы в ней была сухопутная граница. То жмите эту кнопку и заливайте нужную территорию Кнопка New water устанавливает цвет заливки в новый цвет водной провинции.

После того, как вы все сделали, нажмите кнопку Export map и подождите, все необходимые файлы запишутся в папку exported\_map

![](/files/-MYBPS2l5XE0oypvM6FM)


# Проверка карты в редакторе

Чтобы проверить, как будет выглядеть карта в игре, закройте редактор, снова откройте и выберите Map editor

У вас загрузится карта, так, как она будет выглядеть в игре. Также в этом режиме вы можете изменить центр провинции (откуда будут рисоваться иконки). Для этого нажмите на прямоугольник справа от надписи Change offset. Если прямоугольний зеленый - включен режим изменения центра провинции, если красный - выключен. Вы можете изменить центр провинции, кликая по ней

Внимание! Сохраняются изменения при клике на переключатель режима сверху. Т.е. после того, как вы измените центр провинций, обязательно нажмите на ту кнопку


# Загрузка в игру

После того, как вы создали карту, вам нужно ее переместить по опред. пути, чтобы загрузить ее. Всегда актуальный путь прописан в левом нижнем углу в редакторе сценариев.

На данный момент это:\
Android: Android/data/com.DenisMakhortov.ColdPath/files/\
Windows: D:/ (Внимание! На windows файл должен называть не exported\_map, а ColdPathexported\_map. Также и с файлом сценария. Не game\_data.json, а ColdPathgame\_data.json Пока не критично, но хорошо бы исправить и сделать автосоздание папки Cold Path при ее отсутствии)

Итак, вы создали карту, положили по нужному пути. Далее зайдите в игру. Новая игра - Карта - выберите Custom Map. У вас прогрузится карта, созданная вами. Сценарий, который там есть, - автоматически сгенерированный. В нем есть только одна страна. Этот сценарий нужен лишь для того, чтобы на его основе сделать свой. Поэтому далее нужно открыть Редактор сценариев, выбрать пользовательскую карту (Custom map), и создать свой сценарий для этой карты. Далее его нужно экспортировать (Export to JSON), потом подгрузить (Load scenario в Dev menu в настройках). Готово! Вы можете играть на своем сценарии на своей карте!

Как играть по сети? Пока нельзя. Нужно будет написать проверку на наличие карты у игроков, которые присоединяются + хорошо протестировать это. Пока отложу


# Ограничения редактора

Лимит на число и размер провинций:\
<число провинций> - <максимальный размер>\
1024 - 124x124\
256 - 252x252\
64 - 508x508\
16 - 1020x1020\
4 - 2044x2044\
(124x124 вместо 128x128 из-за extrude borders, установленного в 2. Это нужно, чтобы не было неправильного отображения текстур. См. раздел Common texture problems на форуме движка)

Пример: вы можете создать тысячу очень маленьких провинций (менее 124x124), но можете создать только 4 размера 1500x1500 (например)

Нельзя подгрузить изображение карты размером более, чем 4096x4096. Это ограничение я установил. Такого размера карты должно быть достаточно. Чем больше размер изображения карты поддерживается, тем больше нужно заготовить текстур для этого, следовательно выше требования к устройству (Можно изменить в исходниках)

Игра не может обрабатывать более 1024 провинций. Это лимит


# Участие в разработке

Исходный код полностью открыт и доступен по ссылке: <https://github.com/JAlHund/cold-path-map-editor>\
Каждый может принять участие. Но что-то подсказывает, что делать буду только я, поэтому правила внесения вклада напишу основные:\
1\) Всегда тестировать изменения\
2\) Один Pull Request - одна задача (чтобы было проще проверить)\
Это касается, если вы хотите внести свои изменения в мой репозиторий. Вы можете клонировать и делать все, что угодно.

Чтобы работать над редактором, вам нужно скачать игровой движок Defold, загрузить исходники и открыть в движке проект редактора карт


# Советы по изменению исходников

### Настроить сглаживание провинций.

Редактор карт автоматически применяет метод полей расстояний, чтобы сделать провинции более качественными и избежать эффекта лесенок. Если границы провинций слишком гладкие, то вы можете изменить значение в файле libs/drawpixels/src/drawpixels.cpp\
Ниже пример изменения силы размытия с 2 до 1. Вы можете настраивать это, как вам нужно\
Найдите функцию blur (в поиске введите "static uint8\_t \* blur") и ниже найдите:\
`int box = 2; // set 1 to have a 3x3 box`\
Измените значение 2 на 1 (было `int box = 2;`, измените на `int box = 1;)`

### Лагает Defold при работе с редактором карт.

Решение: откройте файл main/main.script и измените строку `IMAGE_DATA_PATH = ""` на, например, диск D `IMAGE_DATA_PATH = "D:/"` Главное, чтобы была указана папка за пределами проекта. Также удалите image\_data и exported\_map файлы в папке проекта (сохраните, если они вам нужны. Это данные изображения карты и экспортированная карта)

После изменения IMAGE\_DATA\_PATH данные карты будут сохраняться не в папку проекта, а по указанному пути. Меньше файлов в папке проекта - меньше файлов обрабатывает Defold


# О глобальных серверах

Что такое глобальный сервер

#### Как создать свой сервер?

1. Арендуйте vps сервер на Linux. Желательно Debian или Ubuntu, так как в примерах далее будут использоваться команды, которые 100% работают на этих системах. Возможно запустить и на остальных, но вам придется самостоятельно принимать решения и отходить от инструкции
2. Установите нужные зависимости и загрузите сервер с github. Это первоначальная настройка сервера, и она должна быть выполнена только один раз
3. Настройте сервер для себя.
4. Запустите сервер и играйте вместе с друзьями

#### Что можно менять на стороне сервера?

Вы можете:

1. Добавить свои сценарии и карты
2. Написать свои плагины, которые разнообразят игровой процесс
3. Переписать всю игровую логику так, как вам нужно, путем изменения lua файлов (например, изменить поведение ИИ, построек и вообще почти всего, что только можно)

#### Как подключиться к созданному серверу?

Есть два варианта:

1. Ввести ip:port в разделе прямое подключение
2. Добавить ваш сервер в список глобальных серверов игры и подключаться, кликнув на свой сервер в списке серверов

Для того, чтобы сервер был добавлен в список серверов, свяжитесь с разработчиком игры. Сервер игры также должен быть:

1. Стабильным. Никаких регулярных вылетов, поломок
2. Иметь правила и модерацию. Запрещено банить без причины или писать нецензурную причину бана
3. Не обходить встроенную в игру систему покупок

На эти сервера могут зайти любые игроки сразу после скачивания, и если там будет бардак, у них сложится плохое впечатление об игре, что отразится на рейтинге и покупках


# Установка сервера

#### Аренда сервера

Для начала вам нужно арендовать сервер (ну или использовать ваш компьютер, если это позволяет провайдер)

В этой теме я буду стараться писать конкретные ОС, на самом деле это не так важно. Сервер можно запустить и на Windows, но я буду разбирать запуск и настройку сервера на конкретном Linux Debian, чтобы не было путаницы. На всех остальных системах вы сможете сделать по аналогии

Вначале нужно арендовать подходящий сервер. Без проблем подходит VPS с 512 МБ ОЗУ. Сервер игры хорошо оптимизирован (сам себя не похвалишь, никто не похвалит), если вы будете держать один сервер, то вам этого должно хватить.

После того, как вы его купили, вам на почту придет:

1. ip адрес сервера (который вы будете использовать для подключения)
2. логин и пароль

ОС: debian9 (можно и другую, но в этом обсуждении будет использоваться именно она)

#### Программы

Для того, чтобы взаимодействовать с сервером на ПК, вам нужно скачать:

1. Putty - SSH клиент, чтобы соединяться с сервером и управлять им
2. Любой FTP клиент (например, FileZilla, если он доступен на тарифе арендованного сервера. Если же недоступно подключение по FTP, то качайте WinSCP)

Вы также можете управлять сервером с помощью телефона. Например, на андроид вы можете использовать следующие программы:

1. Termius для подключения по ssh
2. CX проводник для работы с файлами сервера по ftp или sftp

#### Первоначальная настройка сервера

Итак, команды в этом пункте вы должны прописать только один раз. Это первоначальная настройка, вы пропишите эти команды вначале, потом можете забыть про это

Итак, подключаемся к серверу по IP, вводим логин и пароль.

Далее пишем следующие команды (если требует ввода и показалась надпись "Do you want to continue? \[Y/n], то нажмите на клавиатуре y)

Обновляем данные о репозиториях

```
apt update 
```

Устанавливаем LuaJIT

```
apt-get install luajit
```

Устанавливаем LuaSocket:

```
apt-get install lua-socket
```

Устанавливаем LuaSec

```
apt-get install lua-sec
```

Устанавливаем Screen

```
apt-get install screen
```

Устанавливаем редактор nano (чтобы быстро редактировать код в консоли)

```
apt-get install nano
```

Устанавливаем Git, чтобы скачать самую новую версию сервера для Cold Path

```
apt-get install git
```

Все, мы с этим отделались. Больше на этом сервере ничего из этого делать не нужно

#### Загрузка сервера и его запуск

Мы еще не скачали сервер, а к этому лучше подготовиться. Итак, прописываем команду

```
screen -S server1
```

(это нужно, чтобы при выходе из консоли сервер оставался работать в фоне. Так же это очень помогает тем, что помогает переключаться между открытыми программами в консоли) Далее создаем папку, в которой будет наш сервер

```
mkdir server1
```

Смотрим, какие элементы есть в этой папке

```
ls
```

Отлично, папка создалась. Теперь переходим в нее

```
cd server1
```

В эту папку мы и закинем наш сервер. Прописываем следующую команду, чтобы скачать самую новую версию сервера:

```
git clone https://github.com/JAlHund/cold-path-server
```

Или просто загрузите скачанные исходники на сервер другим способом Мы скачали копию сервера на сервер. Теперь перейдем в папку сервера

```
cd cold-path-server
```

Прописываем следующую команду, чтобы увидеть список элементов

```
ls
```

Да, все на месте. Даем права скрипту на запуск

```
chmod +x start.sh
```

Запускаем сервер следующей командой

```
./start.sh
```

Как видим, наш сервер запустился, и теперь мы может подключиться к нему в игре Выбираем Прямое соединение в меню Присоединиться и пишем наш ip:port По умолчанию это 5555


# Настройка сервера

В прошлом пункте мы запустили сервер. Отлично! Мы уже сейчас можем играть на стандартной версии сервера. Но я уверен, что вы теперь хотите настроить его под себя Выключим запущенный сервер (CTRL + C) Настроим время на ход

```
nano server_settings.lua
```

Оно указано в секундах и по умолчанию равно 180. Давайте изменим на 210, чтобы было 3.5 минуты С помощью стрелок на клавиатуре дойдите до этого числа и измените его (но не набирайте цифры на Numpad, набирайте их с помощью цифр, расположенных над буквами) Отлично, изменили. Теперь нужно сохранить. Нажмите CTRL + X Потом y Потом enter Таким образом, вы можете редактировать файлы на сервере. Редактировать можно очень и очень многое. Запустим снова наш сервер Перейдем в основную папку сервера Запускаем сервер

```
./start.sh
```

Теперь мы можем смотреть на то, что происходит в консоли. Также мы можем свернуть текущее окно. Наберите на клавиатуре: CTRL + A CTRL + D Мы вышли из экрана сервера. При подключении к серверу после того, как отключитесь, вы будете в такой же ситуации. Чтобы снова загрузить экран сервера, пропишите

```
screen -r server1
```

## Добавление кастомного сценария

По умолчанию на сервере установлена карта и сценарий от активного игрока parkourcat. Это сделано, чтобы вам было проще поставить свои кастомные карты и сценарии, опираясь на существующий пример

Итак, мы хотим добавить свой сценарий на сервер. (если вы сейчас только подключились к серверу, то не забудь ввести команду screen -r server1 из прошлого пункта, чтобы перейти в экран сервера. В случае, если вы перейдете и сервер запущен, то выключите его командой CTRL + C)

Вначале вы должны были создать сценарий в редакторе сценариев и экспортировать его в виде файла .lua Полученный файл вам нужно закинуть на сервер в папку scripts/scenarios/<подходящая карта>

Дальше нужно определиться:

1. вы хотите, чтобы этот сценарий запускался при старте сценария
2. вы хотите, чтобы этот сценарий был одним из тех сценариев, которые автоматически начинаются после конца игры

Если первое, то вам нужно отредактировать файл start.lua Открываем этот файл с помощью редактора

```
nano start.lua
```

Находим строку

```
game_data = require "scripts.scenarios.euro.std"
```

Меняем ее на

```
game_data = require "scripts.scenarios.<карта>.<сценарий>"
```

Далее, как обычно, сохраняем CTRL + X вводим y жмем enter

Если второе, то нам уже нужно отредактировать стандартный плагин game\_switch (вы тоже можете писать свои плагины, но это отдельная и достаточно сложная тема. Для того, чтобы писать плагины, нужно программировать. Но это открывает очень большие возможности) Переходим в core/server/plugins

```
cd core/server/plugins
```

Редактируем плагин game\_switch

```
nano game_switch.lua
```

Дописываем нужный сценарий по аналогии со сценариями, которые уже определены И по традиции CTRL + X Вводим y Жмем enter Переходим в папку сервера

```
cd ../../..
```

(вверх на три уровня)

После проделанных действий запускаем сервер ./start.sh

## Добавление кастомной карты

1. Создайте карту в редакторе карт.
2. Создайте на сервере папку maps.
3. Папку exported\_map переименуйте в id карты и положите в папку maps.
4. Добавьте свой сценарий, сделанный на этой пользовательской карте, на сервер

Игрокам ничего устанавливать не надо, карта подгрузится автоматически при заходе в игру.


# Плагины

На серверах есть разные плагины. Каждый плагин - независимая сущность. Плагин может отслеживать разные события сервера, а еще и как-то реагировать на них с помощью определенного сервером списком команд.

## Как установить плагин

1. Первый способ. Через редактирование таблицы plugins\_list внутри plugins\_manager.lua
2. Такой же, как и первый, но можно там же не указывать поле data, а только order, а сам плагин с расширением .lua закинуть в папку plugins
3. Второй способ и самый удобный. Просто закинуть нужный плагин в папку plugins с расширением .lua, и он автоматически подхватится. Больше не нужно руками их добавлять в текстовом редакторе, просто переместить в папку. Если нужно настроить порядок вызова плагинов (вначале один, потом другой), то смотрите второй способ применения. Все варианты использования есть в плагин менеджере

## Список команд

* call\_function - вызвать какую-то функцию. Это может быть как серверная функция, так и зарегистрированная в общем пространстве функция другого плагина
* register\_function - зарегистрировать функцию, ее можно будет потом вызывать с помощью call\_function. Полезно, чтобы дать возможность другим плагинам получать какую-то инфу. Например, плагин system определяет функцию кика с соответствующим сообщением. И эту готовую функцию может использовать любой другой плагин
* register\_command - зарегистрировать команду. Например, мы хотим, чтобы при вводе команды /test игроку присылалось сообщение abrakadabra
* set\_data - установить данные (нужно для взаимодействия между плагинами)
* get\_data - получить данные (нужно для взаимодействия между плагинами). Например, нужно узнать ник игрока
* remove\_data - удалить данные
* send\_data - отправить данные. Можно отправлять данные клиенту. Правда, клиент будет реагировать только на те данные, список которых определен на его стороне. Например, можно с помощью этого плагина заставить игрока обновить данные карты
* set\_server\_state - установить состояние сервера (готов к взаимодействию, выключен, запускается)
* start - запустить сервер

### Какие события плагин отслеживает?

* init - запуск сервера
* verify\_registration - верификацию игрока (сервер проверяет, пускать ли игрока в игру или нет)
* on\_player\_registered - регистрацию игрока на сервере (когда игрок заходит, то ему выдается страна, он добавляется в список игроков)
* on\_player\_joined - момент, когда у игрока прогрузилась карта (например, отправлять ему просьбу отобразить правила раньше этого момента не имеет смысла, т.к. игрок в меню)
* on\_player\_disconnected - отключение игрока от сервера
* on\_data - данные, которые пришли от клиента
* before\_next - событие перед началом след. хода
* game\_over - завершение игры
* attribute\_message - оформление сообщения

## Разбор стандартного плагина afk

```
-- это нужно для работы модуля
local M = {}

-- подключаем модуль таймера
local timer_module = require "core.timer"

-- переменные для работы с функциями других плагинов или сервера: отправить данные, вызвать функцию, получить данные
local send_data
local call_function
local get_data

-- таблица с данными последней синхронизации с клиентами, хранят таймер и последнее время
local last_sync = {
    -- client = {
    --     timer_id,
    --     last_time
    -- }
}

-- ждем столько сек, если нет ответа, то кик
local afk_sec = 30

-- проверяем клиента
local function check_client(client)
    -- если текущее время минус время последней синхронизации больше 30 сек, то кикаем
    if socket.gettime() - last_sync[client].last_time > afk_sec then
        call_function("kick", client, { "", get_data("clients_data")[client].name, "lost connection"})
    end
    -- шлем сообщение клиенту, на которое он должен ответить
    local t = {
        type = "ping",
        data = {}
    }
    send_data(to_json(t), client)
end
-- вызывается один раз вначале. Тут мы определяем нужные нам функции
function M.init(api)
    send_data = api.send_data
    call_function = api.call_function
    get_data = api.get_data
end

-- вызывается в случае регистрации игрока
function M.on_player_registered(client)
    -- заполняем данные синхронизации нового клиента
    last_sync[client] = {
        -- создаем таймер, который каждые 30 сек проверяет наличие соединения
        timer_id = timer_module.every(afk_sec, function()
            check_client(client)
        end),
        last_time = socket.gettime()
    }
end

-- если клиент отключился, то удаляем данные
function M.on_player_disconnected(client)
    last_sync[client].timer_id:remove()
    last_sync[client] = nil
end

-- если игрок прислал ответ, то обновляем данные синхронизации
function M.on_data(data, ip, port, client)
    if data.type == "pong" then
        last_sync[client].last_time = socket.gettime()
    end
end

return M
```


# Game Data

game\_data - это глобальная таблица со всеми данными о текущей игре. Вы можете напрямую работать с ней, чтобы менять поведение игры на сервере.

## Как узнать, что она содержит

Узнать содержимое любой таблицы можно, используя встроенную функцию `debug_log(game_data)` результат она запишет в файл log в корень сервера

## Советы по изменению

Старайтесь не изменять этот файл самостоятельно, а использовать готовые модули. Например, если вы хотите, чтобы две страны начали воевать друг с другом, то подключите в начале плагина модуль relations (отношения между странами)

```
local relations = require "core.relations"
```

А в самом коде плагина в нужный момент вызовите

```
relations.register_war(land1, land2) 
```

## Содержание game\_data

Здесь не будет перечисляться все содержание, так как оно очень большое. Только основное, что может пригодится чаще, чем другое

| поле       | краткое описание         |
| ---------- | ------------------------ |
| difficulty | уровень сложности        |
| queue      | последовательность ходов |
| step       | текущий ход              |
| lands      | страны                   |
| provinces  | провинции                |

**Данные страны**

Данные страны хранятся в `game_data.lands[land_id]`, где land\_id - ид страны (не название, а именно id)

Основное, неполное содержание этой таблицы:

| поле     | краткое описание          |
| -------- | ------------------------- |
| ideology | идеология                 |
| money    | число денег               |
| economy  | данные о доходах/расходах |
| allies   | союзники                  |
| enemies  | враги                     |

**Данные провинции**

Данные провинции хранятся в `game_data.provinces[province]`, где province - ид провинции

Содержание этой таблицы:

| поле  | краткое описание                                                                  |
| ----- | --------------------------------------------------------------------------------- |
| water | является ли водной (true/false)                                                   |
| o     | ид страны, которая ей владеет                                                     |
| p     | население                                                                         |
| a     | таблица с данными об армии в этой провинции (key - id страны, val - число армии)  |
| l\_a  | нанимаемая в данный момент армия, которая будет доступна на след ход              |
| r     | таблица с ресурсами (как заполнять, можно посмотреть в файле fill\_resources.lua) |


# Советы

**Написание плагина**

Для реализации своего плагина берите за основу какой либо существующий. Подсматривайте существующие возможности в стандартных плагинах

**Убрать проверку лицензии при подключении (сделать сервер бесплатным для входа)**

Откройте core/server/plugins/verifier.lua и замените verification\_mode с "kick" на "ignore" (чтобы входили без лицензии)

**Как переименовать карту**

Измените строку id в файле map\_info.json и строку map в файле scenario.json и во всех остальных файлах сценариев для этой карты, если они существуют

Для карты, установленной на сервере, дополнительно измените название папки карты и указание карты в плагине game\_switch и, если указан, в start.lua

**Как запустить сервер на Windows**

Закомментируйте в файле `plugins_manager.lua` строки, где подгружаются кастомные плагины из папки автоматически.

Было:

```
if not plugins_data.HOST_IS_PLAYER then
    load_custom_plugins()
end
```

Стало:

```
--if not plugins_data.HOST_IS_PLAYER then
    --load_custom_plugins()
--end
```

**Как запустить сервер на Windows без luassl**

Таким образом, вы сможете запустить сервер, используя только lua и luasocket.

Замените строки в файлах:

*verifier.lua*

```
local verification_mode = "kick"
```

***

```
local verification_mode = "ignore"
```

*server\_settings.lua*

```
verify_uuid = true,
```

***

```
verify_uuid = false,
```

*environment.lua*

```
ssl = require "ssl"
```

***

```
--ssl = require "ssl"
```

## Кратко о том, что можно менять на сервере

На сервере можно менять очень и очень многое. Нельзя добавить новый ресурс, так на стороне клиента его нет. Но можно сделать, что ядерное будет делать земли непригодными для заселения навсегда.

Можно ребалансить игру, как угодно. Можно переопределять поведение существующих построек, как душе угодно (но клиент будет видеть армию на водных провинциях с помощью маяка, даже если на стороне сервера он не дает этот бонус, т.к. это вписано в код на стороне клиента)

На сервер можно добавлять пользовательские сценарии и играть на них без каких-либо проблем. Возможно, будет не хватать перевода, но и это можно исправить, если экспортировать данные перевода, дописать в них перевод на нужные языки и разослать игрокам, чтобы поставили этот перевод в настройках

## Структура проекта:

#### Корень

.git - данные гита

assets - тут лежат данные о том, с каком провинции на какую можно перемещаться на разных картах

core - ядро игры

defnet - модуль, использующийся для облегчения работы с сетью

scripts - разные скрипты

.gitignore - какие данные не надо отправлять в систему версий

admins.dat - список админов (их uuid)

banned.dat - список забаненных по uuid

banned\_ip.dat - список забаненных по ip

chat.dat - тут хранятся все сообщения, отправленные в чат

convert\_to\_global.bat - батник, который одним кликом переводит исходники игры в исходники сервера (они немного отличаются). Эта штука нужна мне чисто для автоматизации

convert\_to\_global.lua - то же самое, что и выше, только тут код на lua, эту штуку вызывает батник

environment - всякие глобальные функции. Вроде вывода таблиц на экран, функций кодирования данных в JSON для отправки по сети, а еще определение глобальных модулей, которые должны быть доступно во всех скриптах, например, luasocket

game\_data.json - текущее сохранение сервера

log - лог сервера. Какие плагины и когда загружались, когда какие действия происходили

luaxxhash.lua - вспомогательный модуль, который нужен был для проверки, корректно ли пришли игровые данные на устройства (пока не используется, но пригодится в случае переписывания системы отправки данных)

README.md - описание сервера

server\_crash - файл с данными о всех падениях сервера

server\_settings.lua - настройки сервера (порт, название, время на ход и т.д.)

start.bat - батник для старта сервера. Внутри в цикле вызывается след. файл, чтобы сервер рестартовался после падения автоматически

start.lua - скрипт lua для старта сервера

start.sh - то же самое, что и start.bat, только для linux

#### Папка core

ai - боты

server - основной скрипт сервера и разные плагины

army\_functions.lua - взаимодействие армий. Найм, перемещение, разные виды оружия

buildings\_calc\_functions.lua - модуль обработки действий от построек

calc\_functions - функции, которые рассчитываются каждый ход (сколько денег тратится на содержание армии, на сколько вырастет население)

core.lua - ядро, все возможные действия в игре определены здесь. В зависимости от того, какой режим игры (сервер, клиент, одиночная) над этим скриптом находится определенная оболочка. Например, если режим игры одиночный и игрок переместил армию, то модуль одиночной игры вызывает модуль ядра и приказывает отрисовать изменение на карте. Если же игрок на сервере и не хост, то модуль клиента отправляет соответствующее сообщение на сервер, а сам вызывает модуль ядра, чтобы тот изменил игровые данные, т.к. действие совершено

event\_system.lua - система событий. Пример: когда кто-то объявляет кому-то войну, то вызывается зарегистрированная в этой системе функцию. Сейчас используется только для балансировщика сил.

game\_values.lua - игровые значения. Например, сколько стоит найм армии, когда начинается инфляция, раз в сколько ходов можно менять идеологию

global\_functions.lua - глобальные функции. Например, найти путь от одной провинции до другой, узнать список соседей провинции, получить перевод какой-либо страны, посчитать очки страны

ideology.lua - модуль, в котором описана работа идеологий. Например, какой бонус к золоту в зависимости от выбранной идеологии или как должна происходить атака, если выбран коммунизм

offers.lua - система сообщений между странами. Например, кто-то отправил кому-то торговлю или объявил войну

relations.lua - отношения между странами. Начать войну, узнать кто с кем воюет. Узнать, вассал ли какая-то страна

timer.lua - модуль таймера. Чтобы каждые 3 минуты происходила смена хода или каждые 30 сек сервер проверял соединение


# Возможные проблемы

#### Исправление некорректного отображения русских символов

<https://serverfault.com/a/894545>

Надо выполнить для всех экранов (screen) или выполнить в корне и потом пересоздать экраны

#### У игроков не работают премиумные функции

Проверьте файл verification\_server в корне сервера на то, соответствует ли он такому же на github. Или свяжитесь с разработчиком

#### Server does not start

Try to start server using `./clear_start.sh` or `luajit start.lua` and check output


