Overview
MineWars is a multiplayer real-time strategy game, inspired by Minesweeper and Civilization. Players battle for territory and control over cities. The objective of the game is to eliminate other players by capturing their cities.
PvP confrontations happen via Minesweeper-like gameplay. Players place mines and other items on their own territory to defend it and challenge their opponents. They see digits hinting at the locations of enemy items.
There is an in-game economy. Cities accumulate money based on the territory the player owns, which the player can spend to deploy items, build infrastructure, or perform offensive attacks.
A good MineWars player knows how to strategically build their empire: manage their economy and build structures to set themselves up for success. They can make good use of the map's varied geography. They can also out-Minesweeper their opponents in the raw fight for territory.
Game Longevity and Our Promise to the Community
We live in an era where people's beloved games are increasingly made unplayable and inaccessible when the developers decide to abandon them, thanks to online-only gameplay and DRM. We are firmly against such practices. We believe that the fans of a game should be able to enjoy it forever.
As such, MineWars will always provide support for LAN gameplay and community servers.
While We Officially Support the Game
We intend to keep running official servers and to keep developing and updating the game for as long as possible, given enough funding.
However, official servers are not the only way to play the game.
Every game install will come with a dedicated server binary, allowing anyone to host their own unofficial servers. Though, this version of the server may differ from the one we use for official game servers. It may have a different feature set (missing some features we'd like to only support on official servers, but also adding some extra features to facilitate community server operation).
When We No Longer Officially Support the Game
Should we go out of business or decide to abandon MineWars for any reason, here is the plan:
We will fully open-source everything: client and servers. We may have to delete some parts, if they contain secrets or other sensitive information, but other than that, everything will be open-sourced.
Open-Source Client Repository
Even while the game is officially supported, MineWars is a partially-open-source project. A large part of the game client (written in the Bevy game engine) is open-source, because we'd like the Bevy game dev community to be able to benefit from our work: learn from how we did things and be able to copy some of the tech we developed for MineWars.
All official game releases are proprietary. The full source code for the official builds of the game (as distributed through official channels) is not available.
However, a somewhat cut-down version of the game can be built from the public GitHub Repository. All the source code in that repository is dual-licensed as MIT/Apache2, and so is completely free (as in freedom) for anyone to do whatever they want with it.
What is included in the open-source repository?
It includes the majority of the game client, which is where most of the interesting technology in MineWars is.
However, the following features are not included:
- The ability to play or host the main MineWars game modes.
- Procedurally-generated MineWars maps (for any game mode, editor, etc.)
- Networked multiplayer
- Anything related to integration with 3rd-party services like Steam and Discord
Notably, you can do the following:
- Play Minesweeper (not MineWars) offline
- Watch replays of MineWars games
- Use the scenario editor to create custom maps
Contributing
The code in the GitHub repo is what is actually used for official builds. It is not a separate stripped-down code dump. The official proprietary version of the game depends on the code in the public repo and extends it with additional stuff.
If you make contributions to our open-source repo, your contributions will be included in future official updates for the game, too. :) You will be credited for your contributions.
Game Design
Target Audience
Who is this game for? What makes it fun and appealing?
Game Appeal
Intense Time Pressure and Conflict
Intense fast-paced high-pressure gameplay.
You have to be constantly engaged and making decisions, be good at managing your time and attention. Be fast and decisive.
Every second is an opportunity cost. If you are not doing something useful, you are falling behind other players. If you make good decisions quickly, you pull ahead.
You are racing for domination.
Gameplay Variety
Large variety of interconnected game mechanics give multi-dimensional gameplay. The game mechanics fit well together and have cross-cutting implications.
Every decision has consequences. You are constantly considering your opportunity cost – making trade-offs about where to invest your time, attention, and resources.
The diversity of gameplay mechanics gives players the chance to develop their own unique playstyles and try different strategies every game, making the game exciting to replay.
Emotional Moments
Emotional tension from facing the consequences of your mistakes and poor decisions.
Emotional reward from making good decisions that pay off, and from exploiting the mistakes and vulnerabilities of other players.
Skill-based Gameplay
You get better at the game as you play more. Your skill and experience are the primary things that determine your success, not chance (and certainly not pay-to-win).
The gameplay effects due to the randomness of the procedurally-generated map and spawn location are quickly dwarfed by the consequences of your skills and decisions.
Macro Play
MineWars is fundamentally a real-time strategy game. You build your empire by capturing cities, taking control of the map, constructing infrastructure, and managing resources.
As you become more experienced, you reduce your cognitive overhead. You become more decisive with your actions.
Build intuition and instincts for how to react to different situations. What game mechanics to focus your attention on. How to adapt to the map's geography.
Learn how to plan well for the progression of the game and set yourself up for success.
Micro Play
The Minesweeper-inspired gameplay is how you fight other players.
Get good at parsing the Minesweeper digits. Glance at the screen and instantly know what to do, where to click.
Get good at your defense game. Know effective mine/decoy formations and quickly deploy them appropriately to the situation.
Infinite Replayability
The procedurally-generated map guarantees that every game is a unique experience.
Learn to navigate the unique geography of each particular map and your spawn position in it.
Also, competitive PvP games are replayable by nature …
Social Dynamics
… your opponents are other humans that also learn and get more skilled, and everyone has their own unique playstyle.
Play psychological mind-games with your opponent.
Alliances Extension may greatly expand the scope for this.
Audience
The highly-determined competitive strategy player is the primary target of this game.
Spectating Experience
Such a game is likely to also be engaging to watch, not just play.
There is a whole separate e-sports-like potential audience for this game.
Some people may be more interested in spectating and analyzing the matches of other players, rather than playing the game themselves. Offering good spectator and replay experiences can provide a lot of value to the community.
Being able to watch offline replays, not just live matches, is also a valuable tool for analyzing matches and learning from prior experiences. Game replay and analysis features would be valuable to both spectator/analyst and to player audiences.
Who do you play against?
The playerbase could also be categorized based on who they most likely want to play with.
Some players may prefer to play against their friends or at local tournaments. They may prefer a LAN session.
Some players may prefer to play against strangers. They may prefer online matchmaking.
Some players may prefer to play with a semi-restricted number of people on a community server.
The above is just a list of possibilities. It is not necessarily a development goal to support all of these multiplayer modes, but it's important to point out that it would increase the playerbase.
Gameplay and Rules
Note: everything subject to change, as we play-test and balance the game.
Note: many of the concepts are interconnected; by necessity, this document cannot introduce them in isolation, and each section may refer to concepts not yet explained (if you are reading in order).
Gameplay Objective
In MineWars, a number of players compete for ownership over cities and territory.
There are a number of cities in various locations on the map. Each player begins the game with one starting city.
A player must own at least one city at all times; otherwise is eliminated from the game. The objective of the game is to eliminate other players.
Game Over Condition
Lose
If a player loses the last city they own, they are out of the game. All territory they own becomes neutral. They may continue to spectate the game.
Win
If a player is the last one standing, they are the winner of the game.
Score
During the game, there can be a scoreboard allowing players to judge the progress through the game, based on their (and other players') stats.
The most important number is the "cities owned". It indicates the size of each player's empire.
There can be a mini-scoreboard on-screen at all times, showing the number of cities for each player in the match.
Additionally, players can bring up a detailed scoreboard, which provides more stats. Some example things we can include:
- "Kills": number of times another player has stepped on a player's mine
- "Deaths": number of times the player has stepped on another player's mine
- "Captures": number of times the player has captured a city
The Map: Cities and Geography
The game is intended to be played on procedurally-generated maps. Every game happens on a new and unique map.
However, we also support hand-crafted pre-made maps.
Map Geography
The game map is a procedurally-generated fully-contiguous island/continent.
There are several types of tiles:
Water is everything outside of the playable area. Non-interactive.
Land is an interactive tile, forming the playable area.
Fertile Land gives extra resources. Otherwise, it plays like Land.
Foundation is a land tile that has been used up by the player (via harvesting or construction). This tile generates no resources. Otherwise, it plays like Land.
Destroyed Land is a tile where an explosion has occured (from a mine or strike). Once a tile is converted into destroyed land, it generates no resources. Otherwise, it plays like Land.
Mountains and Forests are generated in random clusters of multiple adjacent tiles. They can only be indirectly captured as an entire cluster, by capturing all adjacent land. They give large amounts of resources when owned by players. No gameplay actions can happen on these tiles, and they do not display digits.
Generation
The whole playable area must be contiguous. Everything outside of the playable area is Water.
There may be rivers, which are single-tile-thick strips of water. They must not divide the land / break the contiguity of the map.
Lakes/Mountains/Forests, can be generated by creating small clusters of water/mountain/forest tiles.
Land next to Water can be converted to Fertile Land.
Cities
At map generation time, a number of cities are placed randomly. The generation algorithm aims to position them in diverse geographical locations, with a large distance between cities.
All tiles adjacent to the city tile must be land; cities cannot be located next to mountains, forests, or water.
The location of cities, and a visualization of the extents of their regions, is always visible to all players, even behind fog of war. Everyone knows how many cities each player owns at all times – it is important to judge the progression of the game and to plan strategies. The exact cities (who owns what cities) is not known, except for neighboring regions.
Every player knows the owner of foreign cities in regions neighboring the regions that are controlled by the player.
Starting Cities
Given the random nature of the map, it is important that players are not left feeling like they (or another player) got an unfair spawn location.
Because of this, we need a solution to give players some agency over the randomness, to prevent someone spawning with a large unfair advantage.
Current proposal:
Ban Stage (no pick)
At the start of the session, before the game begins, there is a ban stage.
Players are shown an overview of the map and all the city locations.
Players are given 15 seconds to place a vote for up to 2 cities.
The votes are revealed to other players after the time elapses.
The highest-voted city is banned. Nobody will spawn there.
If a player does nothing during this stage, they just do not contribute any votes. If all players do nothing, no cities get banned.
The process may be repeated multiple times depending on game mode, to ban multiple cities.
Spawn locations are picked randomly from the remaining cities.
Regions
Each tile on the map is associated with a city. All tiles that are associated with a given city are collectively known as that city's region. The region is the city's "area of responsibility".
The city's resource points are accumulated from all the tiles in its region that are owned by the same player that owns the city. The city generates income for the player, based on the amount of available resources.
Regions are generated with the map, ahead of time, and cannot change during the course of a game.
Out-of-region vs. In-region gameplay
In foreign regions (where the player does not own the city):
- owned tiles do not generate resources
- disconnected (non-contiguous) land ownership is not allowed
Generation
Due to the randomness and geographical diversity of the map, some cities will naturally be considered more attractive to players, which could lead to power imbalances. To counteract this, the map generation algorithm strives to keep cities balanced in resource availablitity. Regions will be computed so that similar amounts of total resources are available in each region.
The algorithm starts from the location of each city and gradually expands the region in the area around it, similar to a "floodfill" or "breadth-first-search" algorithm, until every playable tile on the map has been assigned to a city. At every iteration of the loop, the region with the fewest total available resources is selected for expansion.
When there are multiple candidate tiles (the search frontier), they are prioritized as follows:
- Any ResClusters (Mountain/Forest), sorted by closest distance to the city
- Any Regular (or other) land, sorted by farthest distance from other cities
Land tiles are assigned one-at-a-time. Mountain/Forest tiles are assigned as a whole cluster (clusters are never split between regions).
Starting Mines and Decoys
On world generation, a large number of mines and decoys are randomly scattered around the map, in all the neutral unexplored areas. Other items are not generated.
This serves to impede the initial expansion of players' territories. It also allows players to capture them and potentially sell them for precious early-game money, while their cities' income is still rather low due to a lack of territory.
The early-game stage of MineWars, before encountering another player, is hence more like a glorified single-player minesweeper experience, as each player tries to form some initial territory and prepare for their first PvP encounter, while being mindful and trying to figure out the randomly-placed initial mines.
Territory and Ownership
MineWars is a game of territory. Players must expand to claim resources and progress through the game.
Visibility
Areas away from the player's territory are covered by "fog of war". The player can see 3 tiles away from tiles they own.
The entire map's geography is shown to all players at all times, there are no areas that are completely "black".
Mountain tiles are always treated as a cluster. If you can see one tile of the cluster, you see them all.
Within fog-of-war tiles, the player sees:
- Current tile kind (if changed due to harvesting, explosions, etc.)
- Explosions
- Skulls
Within visible tiles, the player also sees:
- The ownership of the tile
- Completed Structures (incl Roads)
- Smokes
On a player's own territory, the player also sees:
- Items
- Pending Structures
Ownership of Territory
Each tile on the map can have an owner: one of the players in the game. The owner is indicated by a color highlight on the tile. Every player has a color. For accessibility reasons, the colors should be customizable client-side. Players do not get to pick the exact colors displayed to others.
At the start of the game, all tiles are neutral, except for the starting cities of the players and all tiles adjacent to them.
Owned tiles provide Resources to the city of the region they are associated with, if the player owns the city.
On owned Land, the player gets:
- the ability to deploy Items on the tile
- the ability to perform various actions on the tile and on adjacent unowned tiles
- the ability to build structures
- the ability to Harvest the tile, if the player owns the region's city
- visibility of surrounding tiles
- a digit (like Minesweeper) indicating how many (if any) items exist on adjacent unowned tiles
("unowned" here means: neutral or owned by another player)
Capturing Territory
Land
Land is captured simply by clicking on it. You can only do it if you own at least one adjacent tile.
After being captured, the land is protected for 2.5 sec, meaning it cannot be captured by another player. This gives the new owner a chance to deploy items to defend it, preventing the game from turning into a clickfest.
If the tile is known empty (there is no adjacent digit), the game will autoexpand. All safe land (up to any tiles with digits) will be recursively captured instantly, like in Minesweeper.
If there is an adjacent digit, that indicates the tile is potentially unsafe -- a risk to the player.
If the tile contains any Items, their respective effects will be triggered when the player attempts to capture the tile (see their respective docs for more detail):
- Mines will explode, giving the player a Death timeout
- Decoys will break / do nothing, and the tile will be captured as if it was empty
- Smoke Traps will "blind" the player
Player strategy: if they think the tile is empty or a decoy, they should capture it, breaking any decoy. If they think the tile contains a dangerous item, they can either Strike the tile to destroy it, or try to safely surround and capture the item.
Autoexpand
When land is known safe, the server should auto-claim it for you. The game should be designed to reduce any tedious clicking around. This should be recursive and happen instantly.
It can account for player flags, to mark tiles to avoid.
Clusters
Mountains and Forests are always owned as a cluster. If there are multiple adjacent tiles of one of these types, the player cannot own them individually; they are captured all at once and lost all at once.
To capture a cluster, surround it on all sides by capturing all adjacent land tiles. If there are multiple adjacent clusters (say, a forest next to a mountain), or if any of the adjacent land contains Items or Structures, all of those tiles are grouped together for the purpose of capturing. The player must surround the entire group (capture all adjacent safe tiles), gaining control of all the clusters, items, and structures, at once.
A player only maintains ownership of a mountain or forest cluster while they maintain ownership of all adjacent land tiles. You immediately lose ownership of the entire cluster if another player captures even a single adjacent land tile.
Note that only land tiles are counted. If there are adjacent clusters (forest next to a mountain), it is possible to lose one while keeping the other.
Items
When there are Items deployed on Land, you can capture the items by surrounding them. Capture all safe tiles around them.
If there are multiple adjacent tiles with items on them, they are treated as a Cluster, similar to mountains/forests.
When the items have been successfully surrounded, all the land tiles are automatically captured by the player. The items are sold for money. See the Economy section for more info.
Player strategy implications: This rewards the player for playing the game carefully and taking the time to treat foreign items as a puzzle to be solved, rather than simply striking the tiles to destroy the items. Striking is quick and easy, but costs money, and destroys the land's resources. Capturing the items is time-consuming and requires mental effort to solve the minesweeper digits puzzle, but rewards the player with money and keeps the land intact. If the digits are ambiguous, you can use Reveal, or Strike.
Cities
To capture a city, the player must surround the city, by capturing every land tile adjacent to the city's tile. The player must then hold all adjacent tiles for a duration of 5.0 sec.
The city remains owned by the player until another player does the same (captures every adjacent land tile and maintains ownership for duration).
See the Economy section for further implications of capturing cities.
Structures
Roads
Road tiles are treated as land tiles for the purpose of capturing.
However, note that cities only count as connected if there is a path that is fully owned by the player. Upon losing even a single tile, the connection is broken.
Barricades
Given that barricades connect mountain clusters, they have implications for the ownership of those clusters. They make it effectively impossible to capture each of the mountain clusters individually. However, each cluster can still be lost individually.
When a player surrounds both clusters together with the barricade between them, they capture the barricade along with both clusters.
Watch Towers
Watch Towers are captured by surrounding them, similar to cities. If they are built adjacent to a cluster, they need to be captured together with that cluster. If they are built between clusters, they effectively work as a Barricade.
Bridges
Bridges are built on water, and therefore have no ownership. However, they allow a player to capture tiles on the opposite side of the water, if they own tiles on one side.
Economy
The Economy is a core part of the game. Each city generates income for the player, which can be spent to perform gameplay actions.
Money
Each city has a Bank. The Bank is the total money of the city.
The player can spend money to:
- Build structures
- Deploy items
- Perform actions
The actions are funded by the city of the region of the tile where the action takes place.
In foreign regions (where the player does not own the local city), actions are funded by the nearest city by distance.
If a city has active road connections to other cities, then they will fund the actions collectively. The cost of the actions is split between all connected neighboring cities, proportionally to the total amount of money each city has in its bank. The local city's contribution is weighted double.
If a city is captured by another player, 50% of the money will stay in the city and be usable by the new owner, and the remainder will be lost.
Income
Each city constantly generates/accumulates money. The rate of income is determined by the total resources owned by the city; that is, the sum of the resources of each owned tile within the city's region. It can be reduced due to ongoing construction. It can be affected by Policy.
Neutral cities (not owned by any player) do not generate any income.
Resources
Each tile provides a certain number of resource points, counted towards the city of the region where the tile is located, if the player owns both the city and the tile.
Resources given by each tile owned:
- Regular Land: 1 Res/sec
- Fertile Land: 2 Res/sec
- Destroyed Land and Foundation: 0 Res/sec
- Forest: 5 Res/sec
- Mountain: 7 Res/sec
Further, each city has 25 Base Res: the minimum amount of resources inherent to the city, regardless of any owned tiles in the region.
Policy
Players may tune a few different parameters that affect the resources of a city and their usage:
- Construction Rate: What % of resources goes towards any in-progress structures, instead of generating Income.
- Export Rate: How much do we help (% of max) connected cities with their spending.
- Import Rate: How much help (% of max) do we accept from connected cities.
Harvesting Tiles
Players may *harvest tiles (one tile at a time) to instantly claim a large sum of resources. They are awarded to the city of the region the tile belongs to.
This is a one-time action. After harvesting, the tile is converted to Foundation and produces no more resources for the remainder of the game.
The player must own both the tile and the city whose region it belongs to.
This mechanic exists to give players more options for survival in tense situations. They can accelerate their current production one-time, at the cost of foregoing all the potential resources they could have accumulated from the tile over time and also potentially worsening the natural protection they get from the map's geography.
Harvest bounties (resource given when harvesting a tile):
- Destroyed Land and Foundation: not harvestable (0 Res)
- Regular Land: 100 Res
- Fertile Land: 250 Res
- Forest: 420 Res
- Mountain: 600 Res
Harvest delay:
- Destroyed Land and Foundation: not harvestable (0 Res)
- Regular Land: 5 sec
- Fertile Land: 5 sec
- Forest: 15 sec
- Mountain: 30 sec
Constructing Structures
The player may construct infrastructure on land that they own, if they own the city in the region. When the player wants to build something, the city's resources will go towards the structure and the city will not generate income until construction is complete.
If construction is canceled before it is completed, 50% of the spent resources are instantly reclaimed and the remaining resources are lost.
Bulldozing Structures
Any structures on land owned by the player can be bulldozed. This returns 25% of the resource cost of the structure back to the player.
The reward is counted towards the city of the tile's region, if owned by the player, or the nearest city by distance otherwise.
Capturing Foreign Items
If a player captures a tile that contains an item, the item is instantly sold, giving the player:
- Mine: 75% of the usual cost
- Decoy: 50% of the usual cost
- Smoke Trap: 0% of the usual cost
The reward is counted towards the city of the tile's region, if owned by the player, or the nearest city by distance otherwise.
Costs
The cost of everything is determined using a multiplier applied to a Base Unit; this helps negate the unpredictability of the random procedural world generation. This is calculated once at the start of the game, based on the generated map, and remains fixed throughout the game.
The Base Unit is roughly representative of how powerful cities could get in a given game session, and is calculated as follows:
- The arithmetic mean of the available resources in each region
This should help give relatively well-balanced costs with varying map configurations.
The final amounts are rounded up to the nearest 100.
Cost sheet (TODO playtest and balance):
Items:
- Decoy: 2.0
- Mine: 3.0
- Mine (upgrade from decoy): 3.0
- Flashbang: 8.0
Structures:
- Road: 1.0
- Barricade: 20.0
- WatchTower: 30.0
- Bridge: 5.0
Actions:
- Strike: 1.0 + 2.0 * NTiles
- Reveal: 5.0
- Smoke: 0.5
Starting money:
- If a player captures a neutral city: 10.0
- The initial (spawn) city of each player starts with: 16.0
PvP Combat
Player encounters happen on "front lines"; that is, when your territory reaches that of another player.
You can try to capture another player's territory, just like you do neutral land at the start of the game.
Everyone is incentivised to set up defenses by deploying items and building structures on their territory, to protect themselves from other players advancing into it.
Similarly, everyone is incentivised to attack and advance into other territories, in their attempt to play towards the game's overall objective: eliminating the other players.
Digits
Every player-owned tile will show a Minesweeper-like Digit, to indicate the total number of Items on adjacent tiles not owned by the player.
Further, an Asterisk (*) will be displayed with the digit, if there are any Decoys. The player can use this hint/information to figure out where decoys might be and decide if they want to try and risk stepping on those tiles.
The game client can provide a feature to switch digits to "enemy preview" mode, where the other players' digits are displayed instead, to allow the player to visualize how their defensive item formations would be seen by others.
Defensive Play Overview
When you own territory, you do not want to leave it undefended and easy to capture. Also, remember, if a player clicks on a "known safe" tile (with no digit), they can capture large swaths of territory in a single click!
Therefore, as you gain new territory, you want to set up formations of defensive Items to protect it. The presence of items will stop an invader's expansion and force them to solve a Minesweeper digit puzzle.
It is very important to use creative and clever formations of defensive items (mines, decoys, traps), and empty tiles, in order to create a challenging Minesweeper puzzle for the other player. The more variety, the better. For example, using too many items without leaving empty tiles will make the digits very easy to figure out. Ditto for not using decoys.
At the front line itself, you need to be especially careful. Deploying some additional items in real-time can be helpful to confuse the opponent, if they are actively trying to invade.
You can use Smokes to conceal specific digits for the enemy. This gives you an opportunity to deploy your items without immediately giving away information about what you are doing.
If you have a large territory, you might have multiple fronts, possibly with multiple other players. You need to keep an eye on all of them.
Further, you can build Structures within your territory. Barricades allow you to make use of geography (mountain clusters) to limit mobility and make it difficult for a future invader to advance into key locations. Watch Towers will give you visibility in case you lose the surrounding territory.
Offensive Play Overview
At the front line, you might decide to attack and advance into enemy territory.
To do this, you need to solve the Minesweeper puzzle. Use the digits to figure out where enemy items are, and determine what tiles are safe to step on.
You want to avoid dangerous items, and step on tiles that are safe). Decoys make the puzzle more challenging: you need to account for them when you mentally parse the digits + asterisks.
If you need to advance quickly, you can use the Reveal action (which costs a lot of money), to immediately learn what is on an enemy tile. Or you can strike.
If you think you know where dangerous items is located, you have options for dealing with them:
- Strike the tiles (offensive action), causing explosions that destroy the item and the land it stands on. Costs money.
- Carefully surround the items by stepping on adjacent safe tiles, capturing them. Rewards you with money.
- Just step on the tile anyway and suffer the consequences. ;) Probably best reserved for dire situations.
This presents an interesting tradeoff:
If you value your time and have money, you can play quickly and recklessly, striking enemy tiles to destroy items. You can be even more reckless and just strike enemy tiles, regardless of whether you think there is an item there, and not even bothering with the Minesweeper puzzle. This costs even more money and will destroy a lot of land, removing valuable natural resources.
On the other hand, if you want to take your time to play carefully and methodically, solving the Minesweeper puzzle can allow you to capture the enemy items. This way, you don't spend any money on your invasion. In fact, you gain money as a reward for the items you find. You also do no damage to the natural resources on the map. You may use the Reveal action to get hints, when in doubt.
Explosions
Stepping on a mine, and strking tiles, cause explosions.
Explosions are visible to everyone, even behind fog of war. Causing them will reveal your activity to 3rd-parties.
Explosions convert tiles to Destroyed Land, causing them to produce no more resources for the rest of the game.
All Gameplay Actions
This page describes all gameplay actions that a player can perform.
Most actions have a Cooldown to prevent abuse. This is the amount of time that must pass between successive invocations of the same action.
Some actions also have a Delay. This is the amount of time between when the action is initiated and when it is completed.
The game client should display a progress indicator to visualize Cooldowns and Delays. Cooldown indicators should be displayed within the game UI/HUD, where the action is triggered. Delay indicators should be displayed on the tile where the action is being performed.
Capture Land
Cooldown: 0.125 sec. Delay: 0.25 sec.
Attempt to capture a foreign land tile. Any items on the tile will be triggered and their effects applied to the player. If the tile has a digit value of zero, adjacent tiles will be automatically captured, recursively.
The player may place Flags, to mark locations they don't want to step on. Auto-expansion will account for the flags, expanding around them.
Strike
Cooldown: 1.0 sec. Delay: 1.0 sec.
Cause an Explosion on the given tiles. Destroys any Items on the marked tiles. Converts the tile kind to Destroyed Land.
Costs money.
Can be applied to any Visible tile.
The game client should allow the user to first "mark"/"flag" the tiles selected for a strike. This displays Marks on the map, on the marked tiles. This happens entirely client-side. Then, the user can confirm the selections, to launch the strike. The marks disappear and all the marked tiles are submitted as a single action to the server.
Reveal
Cooldown: 1.0 sec. Delay: 0.25 sec.
If the tile contains a mine or decoy, it is displayed to the player. The revealed item is displayed until either of the following occurs:
- Explosion, destroying the item
- Tile is captured by the player
- Any of the digits on adjacent owned tiles changes
If the tile contains a trap, the trap is activated.
Can be applied to any Visible foreign tile.
Costs money.
Smoke
Cooldown: 1.0 sec. Delay: 0.5 sec.
Places a Smoke on an enemy tile, concealing the digit on that tile. The other player cannot see any digit on that tile for the duration of the smoke.
This gives the player an opportunity deploy items on their territory, while limiting how much information is revealed to the opponent.
The smoke lasts 5.0 sec.
Costs money.
Can be applied to any tile that is owned by another player and is adjacent to a tile owned by the player.
If an explosion occurs on a smoked tile, the smoke is instantly cleared.
Deploy Item
Cooldown: 1.0 sec. Delay: 0.5 sec.
Place an Item on a tile that is owned by the player.
The item is purchased using money from the city's region (if owned), or the nearest city by distance (if unowned). The cost may be spread out between multiple cities, if there are active road connections.
Items can be deployed only to empty (not containing a structure or item) land tiles.
Additionally, decoys can be "upgraded" to mines.
Initiate Construction
Cooldown: 0.5 sec. Delay: 0.0 sec.
Place a Structure on a tile that is owned by the player.
The player must own the city of the region.
The Structure is not ready immediately. When placed, it is in "pending" mode, and the city is set to "construction" mode.
While a structure is "pending", it will not perform its intended effects. Instead, it will accumulate "construction points" based on the city's resources. The player should be able to see the progress.
While a city is in "construction" mode, part of its resources are directed towards construction progress, instead of generating income.
If there are multiple "pending" structures in a given region, they are processed one-by-one, in a queue, in the order they were submitted by the player.
When building roads, all selected tiles are submitted as a single action.
Bulldoze Structure
Cooldown: 2.0 sec. Delay: 5.0 sec.
Remove a Structure from a tile, recovering part of its value.
Harvest Tile
Cooldown: 1.0 sec. Delay: depends on tile kind.
Instatly claim a sum of resources (counted either towards income or construction, based on the current state of the region's city).
The player must own the region's city.
The amount gained depends on the tile kind.
The tile kind is changed to Foundation, meaning it will give no resources for the rest of the game.
Items
Items are defensive things that you can deploy onto land tiles that you own. If another player attempts to capture the land, they will suffer the effect of the item.
Once deployed, you cannot remove your own items from the tiles they are on.
Every player sees Digits on tiles they own, indicating the total number of items on adjacent tiles they do not own.
Mines
Mines will explode when stepped on, resulting in the offending player receiving a Death Timeout. This adds to the "Death" count of the offending player and to your "Kill" count.
All players in the match will be notified of this event. The explosion effect and location will be seen by all players. The tile where the explosion occurs will become visible (no fog) for all players for a duration of 2.0 sec.
A skull decal will be left behind to commemorate the occasion.
During the timeout a player cannot perform any game actions. All of their cities pause production for the duration.
The timeout duration is 10 seconds.
The tile will be converted to Destroyed Land, thereby providing no more resources for the remainder of the game.
Decoys
Decoys are harmless and will break when stepped on. The other player will successfully capture the tile.
The purpose of decoys is to confuse the other player and make the Minesweeper digits puzzle more difficult for them to solve.
The presence of a decoy will add an asterisk (*) to the digits other players see on adjacent tiles. This provides a hint to them, without directly revealing the actual location of the decoy.
Smoke Traps
All tiles adjacent to the trap's tile, that are owned by the offending player, will have their digits obscured with Smoke.
Similar to a Decoy, a Smoke Trap will add an asterisk (*) to adjacent digits. This will trick players to fall into the trap.
Structures
There are several structures that can be built by players to give them a stategic advantage. Structures are built on land, using the production points of the city whose region the land is part of. The player must own the city and the land.
When a structure is placed on a tile, the underlying tile kind is changed to Foundation.
Structures can be bulldozed to reclaim part of their value. After bulldozing, the underlying tile kind is changed to Destroyed Land.
Structures are destructable. They take 1 damage from adjacent explosions and 2 damage from direct explosions (on the same tile).
Strike can be peformed on structures, causing direct damage. Adjacent damage can be caused by nearby mine explosions or strikes.
Built structures are visible to other players behind fog of war.
Roads
HP: 3.
Roads serve to connect cities. An active road connection brings numerous benefits.
Roads do not have a direction, they are simply a kind of grid tile; each tile either has road built on it, or not. The "path" / pathfinding algorithm simply follows grid tiles. That is, a road tile is considered connected to any adjacent road tiles. (think Civ-like road behavior)
Two cities are considered to have an active road connection iff:
- there is an uninterrupted path of roads between them (the pathfinding algo must be able to reach one city from the other by following road tiles)
- both cities are owned by the same player
- all tiles along the path must be owned by the player
- the path may not cross other regions / all tiles along the path must be part of either city's region
Roads allow gameplay to still occur on the tile. The tile is playable like a land tile. The tile can be captured like land, Items can be placed, Digits are displayed, etc.
Therefore, it is possible for a mine to explode directly on a road. This is another possible way to damage roads, as well as a Strike.
Note that this means an enemy can interrupt a road connection between two cities simply by capturing or destroying a single road tile along it. Roads are very vulnerable. This encourages players to invest in redundant road networks with backup paths.
Mountain Barricades
HP: 8.
Mountain Barricades block mobility by closing gaps/chokepoints between mountains.
The player must own the land tile to build on, the city of the tile's region, and also the adjacent mountains.
The barricade effectively prevents the opponent from capturing ownership of either mountain cluster, unless they surround everything and capture both mountain clusters + the barricade all at once, or destroy the barricade.
A barricade longer than one tile is counted as a single structure. It is constructed all at once and destroyed all at once. Cost adds up, but HP does not. Therefore, longer barricades become prohibitive to build and vulnerable / easier to destroy.
Watch Towers
HP: 6.
Watch towers give visibility of the surrounding area (radius of 5 tiles).
They can be built on any player-owned land tile, as long as the player owns the city of the region. If adjacent to a mountain or forest, the player must also own the mountain or forest.
They can be captured in a way similar to cities: the opponent must surround them by capturing the adjacent tiles.
If built adjacent to mountains/forest, they need to be captured with the mountain cluster.
Note: towers can effecively be used in place of barricades. A tower, if built between two mountain clusters, will effectively behave like a barricade that also gives visibility.
Hence, balance must be kept to keep both structures viable. Towers should be more expensive to build and easier to destroy (in that scenario, not too easy to destroy on open land either).
Bridges
HP: 4.
Bridges can be built on Water tiles, as long as there is Land on two opposing adjacent tiles. Effectively, this limits them to straight sections of single-tile-thick rivers.
Bridges allow land to be captured and roads to be built across the water, thus reducing the impact of the rivers as a geographical feature to segment the map and impede movement.
More Ideas to Explore
This is a list of additional gameplay ideas to be explored after we have a playable demo/MVP.
Grid Style
Compare whether the game plays better on a hexagonal grid or a square grid.
Strong personal preference for hexagonal, but maybe we should play-test both?
Alliances
Temporary friendly relations between players.
During the game, a player can propose an alliance to another player, which the other player can accept or reject.
The following extra rules apply to allied players:
- Full visibility of each others' territory
- Digits are not revealed
- Protection from offenses
- Cannot capture each other's land
- Cannot use Smoke
- Cannot Strike in each other's territory or adjacent to the border
- Trade
- Can connect each others' cities with roads
- (maybe?) in-game chat / comms
The alliance can be canceled by either player at any time.
If all other players are eliminated, the alliance automatically breaks. They must then fight each other to determine the final winner of the game.
Premade Maps
Perhaps it could be interesting to play on a handcrafted map, instead of procedurally generated?
There is a replayability argument to be made.
Procedurally generated maps make the game replayable, because every match is unique. Player skill comes from adaptability -- being able to figure out the best strategy on an unknown map.
Fixed maps make the game replayable, because players can learn them, and apply better strategies the next time they play. Similar to games like Counter-Strike, this raises the skill ceiling, as players can learn a map and rely on their familiarity and knowledge of how to play it most effectively.
For this to work at its best, we need a map/scenario editor.
As a cheap alternative, we can also provide the ability to specify a seed for the usual procedural generation algorithm. However, that would obviously only allow replaying the same randomly generated map multiple times. It would not enable completely custom handcrafted maps.
City Population / Sustenance Cost
This is just a reserve game design idea that should only be added if the game otherwise proves to be very challenging to balance (particularly in the late-game when players have a large and very productive empire).
Introduce an additional variable on cities, can be called "population" or "sustenance". This is a base number of Resources that is subtracted from the city's total resources, to slow down the production rate.
As the game advances, its sustenance cost can rise, preventing it from becoming too productive in the late-game.
Additional things that this number could be used for:
Building progression
Require a minimum population number for certain structures, preventing them from being constructed too early in the game.
Starvation
If the city fails to cover its sustenance cost for an extended period of time ("starvation"), it could be destroyed / removed from the game.
For example: if the sustenance cost is currently X, and the city has less than X total resources, a timer (say, one minute) starts. If the timer elapses, the city is turned to ruin. If the player manages to recover some land within the timer, as soon as the city has at least X resources, it leaves "starving" state and the timer resets.
This would make cities non-permanent and allow the total number of cities on the map to be reduced in the late-game.
When a player is eating away at the opponent's territory, the oppenent's city's resources fall drastically. The risk of starvation puts extra pressure on the defender to defend the territory in the region of the city.
This also puts pressure on the attacker: if they want the city, they must commit to reaching and capturing it as quickly as possible, before it has starved. Alternatively, if they want the city gone, they could deliberately starve the city by playing slowly.
Game Modes
The game client can offer a variety of different modes to offer gameplay experiences for different users' tastes.
These are just interesting ideas to try out. I honestly don't know what game modes we will end up with after playtesting. :)
MineWars Game Modes
These are variants of the MineWars real-time competitive multiplayer game, as described in gameplay.
Elimination (classic)
- Players: 4.
- Cities: 8.
- Map size: 64.
Balanced experience. The goal is to balance strategy and action.
Plenty of breathing room for players to grow their empires and establish their strategies. The map is big, plenty of space and resources. There are more cities than players, meaning neutral cities are available for taking.
Leads to distinct "early game", "mid game", and "late game" gameplay.
Early game is the initial exploration, to establish a presence on the map, before the player has encountered another player. This feels a bit like singleplayer Minesweeper -- you try to expand into neutral territory while uncovering the random pre-seeded mines.
Mid game starts from your first encounter with another player. You now need to worry about your border / battlefront, offense and defense. The midgame is a battle for survival, your goal is to eliminate weaker players and prepare for the final duel.
Late game is when there are only two empires left on the map and the other players have been eliminated. The two remaining players are likely the strongest, with big empires, and need to battle to determine the final winner.
Mayhem
- Players: 6
- Cities: 6
- Map size: 48
- Reduced production costs
- No Ban stage
Game mode designed for frantic action and less room for strategy. The progression of the game effectively moves faster. The idea is to lead to a short early game and frantic mid game.
There are more players than in a classic game, and there are exactly as many cities as there are players, so players are forced into PvP confrontations almost immediately. The map is smaller and more claustrophobic.
Duel
- Players: 2
- Cities: 5
- Map size: 32
With only two players, effectively skips from early game to late game, skipping the mid game. The map is smaller and tighter, to keep the game time shorter and prevent it from becoming boring from the early game taking too long. There are plenty of cities for the players to battle over.
Duos
- Two players control one empire
- Empires: 3 (6 players)
- Cities: 6
- Map size: 48
Adds some teamwork and cooperation to the mix. Reliant on having communication between the teammates.
Turn-Based MineWars
GAME DESIGN WIP!! This will need a lot of revision!
Alternative turn-based Duel, for those who prefer a slower-paced methodical game, instead of the frantic action of regular MineWars.
- Players: 2
- Cities: 5
- Map size: 24
Map must be tiny, due to the slow-paced action of turn-based gameplay.
There is no fog of war, all tiles have a Visibility state of at least Limited.
Turn time limit: 10 seconds.
Within each turn, players have a quota of actions they may perform:
- Capture up to 3 land tiles.
- Deploy up to 3 items.
- Queue up production items for their cities.
... blah blah blah ... todo todo
Singleplayer MineWars-like
Game modes that can be played offline, sharing some mechanics with the regular multiplayer MineWars.
MineWars vs. AI/bots
(considered out of scope for now)
MineWars Playground
For experimentation: allow one client to control all views/empires.
MineWars-like Minesweeper
Like Minesweeper, the goal is to capture all safe tiles on the map.
Classic Minesweeper
Game modes without any of the fancy MineWars mechanics. Just simply click on tiles and avoid mines. The goal is to claim all safe tiles in the quickest time possible. May be made more forgiving by giving players multiple lives.
We can offer some diversity in terms of map styles. Choose between: square grid (like good ol' Minesweeper), hex grid, MineWars map.
Singleplayer
Just play by yourself.
Co-op
Multiplayer session, where all players share the same color/territory and lives.
PvP
Multiplayer session, but every client gets their own color/territory, lives, and stats for how much of the map they have explored. At the end, players are ranked on who has explored the most.
Project Planning
Notes about the management of the project.
Monetization Ideas
This page describes various monetization ideas that could be implemented for MineWars.
Premium Accounts
Players could purchase an upgraded account that unlocks extra features that are intended for more competitive players who are more serious about the game.
This may include:
- features that help you improve your skills
- options that help you avoid players who are cheating
- …
It could be marketed with some language that appeals to competitive players, like: "Pro Competition Upgrade" or something.
It could offer features like:
Replay History
Non-premium players can only download a replay of the game they just played, at the end of each game. The server will not store replays.
Premium players could have replays of their past games stored with their account for later retrieval.
There could also be an option to get a link/code for sharing a replay to let other people watch it.
Premium-only Online Multiplayer
Have the option of filtering the online multiplayer game mode, to only play with other premium players. This should reduce the likelihood of encountering cheaters.
Spectator Visibility Settings
Decide whether you want to be visible to spectators in online games.
Unlocks new preferences in the game settings, like:
- Anyone can see me (default for non-premium players)
- Only my friends can see me
- Nobody can see me
- Manual Whitelist
- In-game toggle and confirmation
(just examples of the possibilities)
If you reduce or disable your visibility to spectators, you can be confident that untrusted players cannot cheat/ghost by abusing the spectator view.
Game Settings
Here we keep track of all the ideas for what aspects of the game should be customizable and exposed in the game's settings.
These are just ideas to explore, not a plan to commit to. Some of these might never be implemented.
Camera Behavior
- Screen Shake: on/off
- Jump tweening transition duration
- Move camera on screen edge
Gameplay Behavior
- Show region highlight:
- based on cursor location
- based on camera location
UI
- Show minimap: on/off
- City UI:
- Floating
- Sidebar
Control Scheme
Mouse/Keyboard
// TODO
Touchscreen
// TODO
Accessibility Options
Flashbang Alternatives
Allow changing the white flashbang to black or a custom color.
Colorblindness: color remapping
Allow selecting a custom color for each of the up-to-6 players in a match.
Should allow tweaking colors completely, selecting both a bright and dim shade for each player.
Should ideally have a UI color picker and a preview render to see what it looks like in context.
Colorblindness: tile patterns
Provide "patterned" alternatives which could be used instead of the base flat color tile.
Achievement Ideas
Minesweeper Pro
Win a multiplayer game without ever stepping on a mine.
Suicidal
Die over 20 times in one game.
Lucky
Step on 5 decoys in succession.
High Redundancy
Have at least 3 different road routes between the same 2 cities.
Maximum Redundancy
Have at least 3 different road routes between every pair of cities in an empire of at least 3 cities.
Environmentalist
Win a game without harvesting any tiles.
Pacifist
Win a game having captured more mines than you have destroyed.
Kaboom!
Explode at least 5 enemy mines (and only mines) with a single strike.
Tricked You!
Another player attempted a strike on your tiles, but hit only decoys.
Uh ... that was totally on purpose!
Strike multiple enemy tiles and only hit safe tiles.
All-Seeing
Cover over 1/3 of the map with observation towers.
Maze
Connect 5 or more nearby mountain clusters with barricades.
Important City
Recapture the same city 5 times in a single game.
Comeback
Win a game where you had only 1 city when another player had 4 or more.
Millionaire
Accumulate $1,000,000.
Post-War Apocalypse
Win a game where over 80% of the land was destroyed.
Divide and Conquer
Split another player's territory into two.
Left Unprotected
Capture 10 or more tiles of another player's territory all at once.
Can't Blind Me!
Mark and strike at least 3 enemy items (decoys excluded) while flashbanged.
Reckless
Strike at least 100 empty tiles during a game.
Smoke Mid Everyday
Smoke a tile in a narrow passage.
Blitzkrieg
Strike over 10 tiles at once.
Mass Resource Extraction
Harvest all mountains and forests in a region.
Notes / Philosophy
UI design
Don't tell ppl what everything is. Entice exploration. Show the options and ppl will want to play with them to see what they do.
Don't teach ppl any "game meta", only how to use the basic mechanics. Let ppl discover their own play style.
UI should be visually intuitive, easy to control with different input devices.
Input devices
Touch > Mouse+Kbd > Gamepad
Server Admin Handbook
This chapter is a guide to hosting MineWars game servers.
We believe in the power of community. One of our development goals for the project is to embrace that and provide rich support for unofficial game servers. Here you can learn how to set up your own.
Everything you need is distributed with your standard game install. You will find all the files necessary alongside the game's executable, wherever it is installed on your computer.
Introduction
The Host Server
The Host server is where gameplay actually happens. This is the most important piece of the puzzle.
It is possible to have a setup with only a Host server. Players can connect directly to it and play the game. It might not be the most user-friendly experience, but it will work. Notably, the Host server alone is not capable of providing any services outside of the actual gameplay, such as lobbies, accounts, matchmaking, etc. You connect and get directly thrown into a game, that's it.
However, this is perfectly fine for many use cases. Such a configuration is simple and easy to set up. Perfect for LAN parties, tournaments, etc.
The Host server is multi-session. One Host server instance is capable of running many parallel gameplay sessions (possibly even thousands, depending on your hardware).
See Session Configuration to learn more about hosting many sessions on one server.
More Complex Setups
If you are really serious about MineWars server hosting and you would like a more complex setup with extra features such as:
- For users: services outside of gameplay: accounts, lobbies, etc.
- For admins: management of the Host server(s): runtime configuration, session management, load balancing, telemetry, etc.
See Runtime Management to learn more.
The Config File
The Host server needs a config file. Don't worry. We provide some example configs for you, which you can probably use as-is without modification.
See Tutorial and Examples to get started.
Security
MineWars requires encryption. Encryption requires keys and certificates.
However, don't worry about it. To make things easy for you, we provide some default pre-made certificates that will just work out of the box. The example config files that come with the game use them. Everything is already set up for you.
If you are more serious about security and would like to customize things, see the page on Security to learn more. There are also various other optional security features beyond encryption.
Hardware Requirements
The MineWars server is very efficient on resources. You can run it on pretty much anything. Especially if you do not plan on running many simultaneous gameplay sessions.
However, it is designed with multithreading and scalability in mind. Hence, we recommend a computer (or virtual machine) with at least 2 CPU cores.
We focus on talking about the CPU, because other resources are unlikely to be a limitation. MineWars uses very little RAM and network bandwidth. If you have many users, you will almost certainly run into CPU limitations before anything else.
Overprovisioning
The Host server is designed to degrade gracefully in performance. When overloaded, it will keep running just fine, but players may experience subtle increases in latency. The server can manage many gameplay sessions and players, but the game might start to feel less responsive during times when there is heavy activity and the CPU is very busy.
If you care about ensuring the best performance (such as for a professional competitive LAN tournament), we recommend one CPU core per session, or at least 4 CPU cores, whichever is more. Extra cores cannot hurt.
If you care about hosting many users on weak hardware (such as if you'd like to offer an online service for many players, on a budget), you will need to decide how much degradation you consider acceptable.
Think of it this way: imagine you have 8 CPU cores. If you host 9 parallel sessions, what are the chances that all 9 of them will need the CPU at the exact same time? Pretty low. Now, if you have 100 (or 1000) sessions, what are the chances? Much higher.
When it happens, users will need to wait for their turn on the CPU. The server tries to be fair, but if these situations happen often, players will start to feel that their inputs become less responsive, and the server might start to miss its timer deadlines (timer-based gameplay mechanics like respawning and construction might have their results delayed). It will worsen the gameplay experience. When it gets bad enough that you consider it unacceptable, it's time to upgrade your hardware. ;)
Tutorial and Examples
You can find the Host server executable alongside the game client executable
in your game's install folder. It is called mw_hostsrv
.
Open a terminal and run it from the command-line. You need to specify the
config file. There are some example config files in the cfg/examples/
folder.
./mw_hostsrv --config cfg/examples/simple.toml
Session Configuration
The Host server is quite flexible with its session management. Some of the possibilities include:
- Any number of preconfigured sessions. Specify what you want in the config file.
- Multiple "presets" for different kinds of sessions, game modes, etc.
- Specify how many you want from each preset.
- Additional sessions created automatically, as players join. Based on a "preset" you specify in the config file.
- If the server is full.
- If a player connects and requests to join a session ID that does not exist.
- Additional sessions created dynamically at runtime, upon request. See Runtime Management.
- Any combination of the above.
Session IDs
Every session that is currently running on your Host server has a Session ID.
Upon connecting, players can specify which Session ID they would like to join.
If they don't specify anything, the server will automatically pick a session for them. This means you could set up a community server with multiple sessions and people will just join a random available session upon connecting by default.
Having your players enter a special magic number to enter a specific session is not a very user-friendly experience. Though it is fine for LANs and such.
If you would like to provide your users with a better experience, you need to also set up an Auth Server.
Presets
In your config file, you can create any number of "presets", where you specify session parameters (like the game mode, number of players, map to play on, etc.).
The number of players for the session is specified using the wait_plids
,
wait_subplids
, max_plids
, max_subplids
options.
"Plids" are the "logical" players. Think each of the different territories/empires in a MineWars game.
"SubPlids" are the clients controlling each Plid. Use this to create sessions where multiple people control the same in-game territory. The value is per-Plid.
The wait_*
options specify how many players to require to join the session
upfront, before gameplay begins.
The max_*
options specify the maximum number of players that can join
the session. If greater than the respective wait_*
option, additional
players may join mid-game. If less than the respective wait_*
option,
will override it.
You can also configure a session to auto-restart after game over. This is useful for preconfigured sessions.
Maps
You can play on either procedurally-generated maps or pre-existing maps loaded from files.
Generated Maps
If you would like to play on a procedurally-generated map, you can configure the parameters like map size, number of cities, etc.
For Minesweeper game modes, you can also play on Flat
maps. This is a classic
simple grid with no special features (no geography, no cities). MineWars
game modes cannot be played on Flat
maps.
Map Files
If you would like to play on a custom pre-existing map, specify the path to a map file to load.
Maps loaded from files are cached. Each file path will only be loaded once and stored in RAM. If you have many sessions using the same map file, it will not need to be loaded again. However, the server will detect if the map file is modified and attempt to automatically reload it if so. The new map data will only apply to any new sessions started after reloading.
Preconfigured Sessions
You can configure a fixed number of sessions to run using your various presets.
These sessions will be set up as soon as you launch the Host server.
If you'd like the server to keep running and start a new game after game over, enable autorestart in the presets you use for your preconfigured sessions.
Otherwise, after all sessions finish, if Automatic Sessions and Runtime Management is disabled, the server will shut down, as there is nothing more to do.
Automatic Sessions
You can configure the server to automatically set up new sessions when players connect.
WARNING: this feature is intended for LANs and other safe environments. Do not enable Automatic Sessions on Internet-facing servers! It is a major DDoS risk!
If players connect without specifying a Session ID, and there are no sessions
available for them to join, the server will create a new session using the
preset you specify in the autosession
option.
If players connect and want to join a specific Session ID that does not
exist on the server, the server will create a new session using the preset
you specify in the autosession_on_request
option.
Dynamic Sessions
Additional sessions can be created at runtime. See Runtime Management.
Security
The Host server offers extensive security features:
- Encryption (mandatory)
- Client Authentication
- IP address control
- Player Expectation
- Protocol abuse detection (rate limiting, anti-cheat, etc.)
Encryption
All connections to the server must be encrypted using TLS (the same kind of encryption used for HTTPS in browsers).
If you would like to use your own certificates, you can use the mw_certgen
CLI tool to generate and sign them.
TODO: show examples and elaborate on different possibilities and why you might want to use non-default certificates.
Client Authentication
Further, it is possible to configure the server to require clients to also have a certificate. This can be used to limit clients allowed to connect.
IP Address Control
The Host server can use an IP List file to limit which IP addresses are allowed to connect. An IP List is just a plaintext file with one IP address per line.
It can be set to DenyList or AllowList mode. DenyList will reject the IP addresses in the file and allow everyone else. AllowList will only allow the IP addresses listed in the file.
IP Address Control only applies to unexpected players. Player Expectation bypasses it. Which makes sense, because with Player Expectations, you are effectively pre-screening your players and explicitly authorizing specific connections.
Player Expectation
This is the most powerful security feature. At runtime, using RPC or an Auth server, the Host server can be told to expect specific incoming connections. It will then accept connections if they match the expectation.
The expectation is registered for a specific IP address and can include additional restrictions:
- A specific TLS client certificate
- A specific "token"/password
- A specific Session ID to join
- A specific Player ID to play as
When the server gets an incoming connection from the respective IP address, it will enforce all the extra criteria. The player will only be allowed to join if they meet all the criteria in the expectation.
Further, it is possible to disable unexpected players altogether, only allowing clients to connect with expectations. This makes your server inaccessible to anyone you have not explicitly authorized.
Player Hand-Off from an Auth Server
Player Expectation is extremely powerful with an Auth server, because the Auth server can automate it. This is called "player hand-off".
Players connect to the Auth server for services such as user accounts, lobbies, matchmaking, etc. The Auth server decides what sessions to set up for them on the Host server, and which Host server they will play on (if there are multiple).
When players are ready to play, the Auth server can automatically set up a new dynamic session for them on the Host server and submit expectations for the exact players who will play in the new session.
It can also generate single-use TLS certificates and tokens for each player, just for that session, for additional security.
The players are then redirected to the Host server. They must connect from the same IP address, authenticate with their newly-issued single-use certificate and token, and join their designated session.
Protocol Abuse Detection
After a player has already connected and joined a session, you might want to detect and punish any abusive behavior. The Host server has an abuse-detection subsystem, which all player input passes through. It can apply a series of checks and issue verdicts.
The Host server we publish with the game only offers rate limiting and rudimentary gameplay-specific checks (checking for gameplay patterns that are obvious and blatant cheating).
Our official Host servers may have additional anti-cheat measures. We will not disclose any details of how they work.
In the future, we may add support for custom plugins, allowing you to integrate 3rd-party anti-cheat solutions. This is not supported yet.
The abuse detection subsystem can keep track of a "suspect score" for each player, which is accumulated based on all the checks that are performed on the inputs from that player. If a player is deemed suspicious enough, a punishment can be issued, such as an automated warning, report, kick, timeout, or ban.
All of the above is configurable.
Appendix: Understanding Server Security
To understand how to protect ourselves against attacks, we need to learn to think like an attacker. An attacker is not concerned with what the software is designed to do, they are concerned with what it can do. If they can find clever and creative ways to get it to do things in a way that is not normally intended, they could potentially use that to abuse and exploit.
Blast Radius
The term "blast radius" refers to how many players are affected if something goes bad (for example, if a server crashes or is successfully attacked).
MineWars Host servers, being designed to host many sessions and many players, can have a very large blast radius. This makes them vulnerable and lucrative to attackers.
To reduce the blast radius, consider hosting more servers with fewer sessions each, instead of lots of sessions on fewer server. Of course, this is only feasible if you can afford it.
DDoS Resilience
DDoS attacks are the most commonly-attempted attacks against game servers in general. Game servers (for any game) typically do not contain sensitive information. If someone has an incentive to attack a server, usually it is to try to take it down, or to otherwise worsen the experience for legitimate players. Hence, DDoS resilience is one of the most important considerations for game server admins and developers.
Fortunately, nowadays it is quite difficult to DDoS a server by just spamming it with pings or other unwanted traffic. Modern computers and networks are too fast for that; they can just drop the packets. An attacker would need access to a very large amount of resources to successfully overwhelm a network.
Effective DDoS attacks rely on a principle called "amplification". That is: finding a way to trick the server to spend a lot of resources with less input. Any feature of the server which could be abused in such a way is a DDoS risk.
The first place to look is how the server handles connection attempts. Connecting to a MineWars server means negotiating encryption. This is an amplification vector. An attacker could overwhelm the server with many connection attempts that it does not intend to allow to actually connect, causing the server to spend CPU and RAM on validating certificates, only to have the connection closed immediately.
A MineWars Host server can be made resilient to such an attack by using Player Expectation and disallowing unexpected players. By having players go through an Auth server first, the Host server is protected. The Host server simply ignores all connection attempts it does not expect.
Another DDoS vector is automatic sessions. An attacker could connect many game clients, causing the server to create lots of sessions and run out of RAM. Do not enable this feature on Internet-facing servers! It is intended for LANs. Internet-facing Host servers should use either preconfigured or dynamic sessions.
After a player has actually joined a session, there is not much they can abuse, as they cannot connect additional clients. Further, the player protocol is monitored and rate-limited. You can adjust the rate-limiting configuration.
Auth Servers
The Auth server is less lucrative for DDoS attacks, because it does not affect gameplay and is not performance sensitive. If attacked, it might only affect players who have not yet joined a game, and the server operators. Players who are already in-game are unaffected. To protect an Auth server, consider putting it behind a commercial DDoS protection service, such as Cloudflare. Auth servers are not performance sensitive and it is okay if they are accessed through a slow proxy. Further, consider having multiple Auth servers for redundancy.
Runtime Management
As discussed in the introduction, the Host server alone is more than enough for many use cases.
If you simply want to host a LAN game, or a LAN party or tournament with many game sessions, or even a basic online server with preconfigured sessions that people can just connect to and play, you don't need anything more than just the Host server with an appropriate config file.
This page will teach you how to grow beyond that. How to manage your server while it is running, to dynamically reconfigure it, set up additional sessions, etc.
RPC vs HostAuth
There are two ways to manage a Host server: RPC and an Auth server (HostAuth).
So, what is the difference?
RPC allows external software to connect to the server to tell it what to do.
HostAuth allows the server to connect to external software to be managed.
So the basic difference is in who initiates the connection. This makes them suitable for different use cases.
RPC is well-suited for performing one-off actions manually and for scripting. Connect to the server's RPC interface, send it some commands, done.
HostAuth is well-suited for automated management. It also has additional capabilities, notably in terms of sending extra data, like:
- Telemetry, statistics, performance monitoring
- Reports for abusive players
- Replays of game sessions for saving
RPC
To use RPC, you must enable it in the config file. There are various options available to secure it.
Please do not expose RPC to the Internet. This is a major security risk! Restrict it to your LAN or localhost.
The easiest way to use RPC is via the mw_hostrpc
CLI tool. It lets you
just send commands. It is also designed to be suitable for scripting. It
can also just generate the message and output it to you instead of sending it.
The RPC protocol itself is based on the RON format and is human-readable
and writable. If mw_hostrpc
doesn't do something you need, or you need
low-level control, you could just write your own messages and send them
via netcat or something. Or more likely, generate something with mw_hostrpc
and then edit it.
The Auth Server
The Auth Server is an optional extra server you can run to manage your Host server(s), specifically the sessions on them and the players connecting to them.
It is responsible for dealing with your users outside of gameplay.
It can offer various (optional) features to players, including:
- Listing of available sessions they can join
- Letting them choose what session to join
- Letting them see info about the players in different sessions
- Letting them see info about other players who have not yet joined a session.
- Letting them enter a session as a lobby with specific other players.
- Letting them create their own sessions
- Letting them create custom game configurations
Basically, a pre-game lobby sort of menu interface.
To you, the admin, it can also offer some compelling features:
- Increased security for your Host server(s)
- Monitoring of multiple Host servers
- Automatically selecting an appropriate Host for players, based on their ping, server load, etc.
Basically the job of the Auth server is to have players connect to it first, instead of connecting directly to the Host server. It can let players decide how they want to play the game and who they want to play with. Then, it can actually set up a session for them on a Host server and redirect them to it.
It also allows you to control who you allow to play on your servers.
MiniAuth
Your game install comes with MiniAuth, a limited version of the Auth server we use for the MineWars official multiplayer. It offers all of the above features. However, it does not have "account services" (user accounts/login). It cannot support integrations and authentication with proprietary platforms like Steam. That is the only difference from the official version of the Auth server we use internally.
Setting Up MiniAuth
Similar to the Host server, you basically need to have a config file and
then run mw_miniauth
. We provide example config files you can use as a
starting point.
./mw_miniauth --config cfg/examples/auth/simple.toml
To actually use it, you need to also configure your Host server(s) to connect
to it. The settings are in the [hostauth]
section of the Host server
config file.
The Host server will connect to the Auth server to be managed.
A Host server can be configured to connect to multiple Auth servers for redundancy. All of them will have equal capabilities. Any of them can create sessions and hand-off players to it.
Now that you have an Auth server, you probably also want to change some other things in your Host server config:
- Disable unexpected players, to allow players to only connect via the Auth server
- Disable any preconfigured and automatic sessions. Put your session presets in the Auth server config instead.
That is, unless, for whatever reason, you want to still allow players to connect to your Host server directly. You could have a "hybrid" setup, where you have a Host server with some preconfigured sessions and also have the Auth server set up additional sessions. If players connect to your Host server, they are treated as "unexpected" and join the fixed sessions. If they connect via the Auth server, they will be treated as "expected" and join the session the Auth server set up for them.
Why you would want such a configuration, I don't know … :D
The User Experience
Your players should connect to your Auth server instead of your Host server. The MineWars game client is capable of automatically detecting what kind of server it is connecting to. Users don't need to do anything different.
From a user's perspective: if they connect to a Host server, gameplay starts immediately. If they connect to an Auth server, they are presented with a menu and lobby interface first, if any of those features are enabled on the Auth server. That is the difference in the user experience.
If none of the special lobby / session browser servers are enabled on the Auth, the game client just gets automatically redirected to the Host, and gameplay starts immediately, just as if it had connected directly to the Host.
MineWars Data Format
The MineWars Data Format is the file format and encoding used to store MineWars
game data. Specifically, this is the format of *.minewars
files that can
store maps and replays. It is implemented in the mw_dataformat
Rust crate.
The Data Format is capable of storing:
- Map Data
- Other parameters and metadata of the game session
- A stream of gameplay updates for all players in the game, multiplexed together, with timing information, to allow for watching a replay of a game.
It is not to be confused with the MineWars Player Protocol, which is what is used over-the-wire for communication between the Game Client App and Host Server for networked multiplayer gameplay.
The Player Protocol does internally use the Data Format for some purposes, such as:
- Transmitting the map data and configuration metadata to start a game session (Initialization Sequence).
- Encoding of most gameplay updates/events during gameplay (Game Update Messages).
- Multiplexing the PoVs of all the players in the game for sending to spectators (Framing).
However, the Player Protocol also does a lot more. The full Player Protocol is proprietary and not publicly documented.
The Player Protocol and the Data Format are versioned separately (and separately from the MineWars client and server software), but both of their versions are important for compatibility.
Reusing the encoding of map data and gameplay updates between all of these use cases (live gameplay, spectation, replay files) makes it easier to implement all of this functionality in MineWars. That is the design goal of the Data Format.
General Properties of the Data Format
This is a custom purpose-built compact binary format.
All multi-byte values are encoded as big endian and unaligned.
All coordinates are encoded as (row: u8, col: u8)
(note (Y,X) order).
In places where a sequence of multiple coordinates is listed, it is recommended
to encode them in sorted order. This helps compression.
Some places use a special encoding for time durations:
Bits | Meaning |
---|---|
0xxxxxxx | x milliseconds |
10xxxxxx | (x + 13) centiseconds |
11xxxxxx | (x + 8) deciseconds |
PlayerId: a value between 1-15 inclusive.
PlayerSubId: a value between 0-14 inclusive.
You will also need to bring a LZ4 implementation supporting raw blocks.
The lz4_flex
Rust crate is perfect. :)
File Structure
A MineWars File contains the following, in order:
File Header
The file header has the following structure:
[u64; 3]
: checksumsu32
: length of compressed frame data in bytesu32
: length of uncompressed frame data in bytes
If compressed length == uncompressed length, the frames data is stored uncompressed.
If compressed length < uncompressed length, all the frames are compressed as a single big LZ4 block.
Checksums
The file begins with 3 SeaHash checksums.
The first checksum covers:
- the remainder of the file header, incl. the following 2 checksums
- the header part of the Initialization Sequence
The second checksum covers:
- the data of the Initialization Sequence (everything after the header)
The third checksum covers:
- all the frames data
Initialization Sequence
After the File Header follows the Initialization Sequence.
Frames
After the IS follow frames of game updates
Note: neither the length of the IS nor the start offset of the frame data are encoded in the file header. The IS Header must be parsed to compute that.
It is thus impossible to read the frames from a MineWars file without decoding the IS first.
Initialization Sequence (IS)
The IS is what sets the general configuration and metadata of the game and encodes the initial state of map that the game will be played on.
Header
It begins with a header:
- (
u8
,u8
,u8
,u8
): Data Format Version u8
: flagsu8
: map size (radius)u8
:max_plid
(bits 0-3),max_sub_plid
(bits 4-7)u8
: number of cities/regionsu32
: length of compressed map data in bytesu16
: length of the Rules datau16
: length of the Cits names data
The flags
field is encoded as follows:
Bits | Meaning |
---|---|
----0--- | Game uses a hexagonal grid |
----1--- | Game uses a square grid |
xxx--xxx | (reserved bits) |
Map Data
Then follows the map data.
If compressed length < uncompressed length, the data is LZ4 compressed.
If compressed length == uncompressed length, the data is raw/uncompressed.
The compressed length is stored in the header. The uncompressed length must be computed from the map radius.
First, the map data is encoded as one byte per tile:
Bits | Meaning |
---|---|
----xxxx | Tile Kind |
xxxx---- | Item Kind |
Tile Kind: same encoding as the "Tile Kind Update" message below. Item Kind: same encoding as the "Reveal Item" message below.
The Item Kind is useful for spectators and replay files, so that they don't need to start with a long sequence of "Reveal Item" messages at tick 0 for all the initial items on the map. Other use cases (such as "map files") may just always set it to zero.
The tiles are encoded in concentric-ring order, starting from the center of the map. The map data ends when all rings up until the map radius specified in the header have been encoded.
Each ring starts from the lowest (Y,X) coordinate and follows the +X direction first:
Square example:
654
7.3
012
Hex example:
4 3
5 . 2
0 1
(0
is the starting position, assuming +X points right and +Y points up)
After the map data, regions are encoded the same way: one byte per tile, in concentric ring order. The byte is the city/region ID for that tile.
If the number of cities/regions is 0, this part of the map data is skipped.
City Info
First, locations for each city on the map:
(u8, u8)
: (y, x) location
Then, names for each city on the map:
u8
: length in bytes- …: phonemes
The name uses a special Phoneme encoding (undocumented, see source code), which can be rendered/localized based on client language.
Game Parameters / Rules
Then follow the parameters used for the game rules, in this game.
// TODO
Game Updates and Framing
A Frame is a collection of game updates that happen together at the same time. It encodes the point of view of every player in the game who is involved + a special global spectator view. All of these "streams" are stored together inside the frame.
Note: it is not a requirement that all game update messages from the same timestamp are encoded together. They may be fragmented into multiple frames. Subsequent frames would just have their time offset set to zero.
Such fragmentation is necessary if the frame payload exceeds 256 bytes in length.
There are three kinds of frame encodings: Homogenous, Heterogenous, Keepalive.
Homogenous Frames
Homogenous frames are frames where every participant gets the same data. The data is only encoded once and assumed to apply to all participating streams.
Homogenous frames have the following structure:
u16
: Headeru8
/u16
: participation masku8
: length of data payload in bytes - 1- [ ... data payload ... ]
The top bit (bit 15) in the Header must be 1
, indicating that this is a Homogenous
Frame. The remaining 15 bits represent the time delta since the previous frame, in
milliseconds, and must not be all-ones (the max value is reserved for Keepalive Frames).
The participation mask is a bitmask indicating which PlayerIds the frame applies to. Bit 0 represents the global spectator view.
The size of the participation mask depends on the max_plid
field in the
Initialization Sequence. u8
if max_plid <= 7
, u16
if max_plid >= 8
.
The data payload is the player protocol update messages. All of the players listed in the participation mask must receive the entire identical data payload.
Heterogenous Frames
Heterogenous frames are freams where each participant gets different data. The data for each participating stream is included in the frame.
Heterogenous frames have the following structure:
u16
: Headeru8
/u16
: participation mask[u8]
: lengths of each player view's portion of the data payload - 1- [ ... data payload ... ]
The top bit (bit 15) in the Header must be 0
, indicating that this is a Heterogenous
Frame. The remaining 15 bits represent the time delta since the previous frame, in
milliseconds, and must not be all-ones (the max value is reserved for Keepalive Frames).
The participation mask is a bitmask indicating which PlayerIds the frame applies to. Bit 0 represents the global spectator view.
The size of the participation mask depends on the max_plid
field in the
Initialization Sequence. u8
if max_plid <= 7
, u16
if max_plid >= 8
.
The size of the lengths array is equal to the number of 1
bits in the
participation mask. Each value represents the length of the data for that
player's view, - 1.
The data payload is the global spectator view + each player's view (in the order of the bits in the participation mask), concatenated together.
Each view's data is the player protocol update messages for that view.
The total length of the data payload is the sum of the lengths of each view's data, as given in the Heterogenous Frame Header described above.
Keepalive Frames
Keepalive frames are to be used if the time delta since the last frame is too long to be represented in a single frame header. It is an empty frame with no data payload, just used to advance time.
It is encoded as a frame with the time delta field being all-ones (the maximum value). The topmost bit is unimportant/ignored.
Keepalive frames have the following structure:
u16
:-111111111111111
Note: there is no participation mask, no data length field, no data payload
Game Update Messages
Updates for the players are encoded as any number of messages concatenated together. Each message is a variable-length byte sequence.
Each message is at least one byte long. The type of the message is determined by magic bits in that first byte (similar to opcodes in CPU instruction set encodings). The first byte may also have bit-fields embedding data into it, for some message types.
Opcode Summary
Quick table summarizing the opcodes of all the message types. A few are left unused, reserved for future use.
Bits | Message Kind |
---|---|
00000000 | Player Update |
00000001 | Tremor |
00000010 | Smoke Start |
00000011 | Smoke End |
00000100 | City MoneyInfo |
00000101 | City Transaction |
00000110 | City ResInfo |
00000111 | City TradeInfo |
000010-- | -- |
0000110- | -- |
00001110 | Debug |
00001111 | Flag State |
0001---- | Reveal Item |
00100000 | Structure Gone |
0010---- | Structure HP |
0011---- | Explosions |
0100---- | Construction Queued |
01001111 | Construction Update |
0101---- | Reveal Structure |
01011111 | -- |
0110---- | Digits (single) |
0111---- | Tile Kind Update |
1000---- | Digits (multi) |
1------- | Ownership Updates |
The patterns must be checked in the correct order, so that more specific bit sequences are matched first.
Messages Documentation
Here is the complete list of game update messages and their encodings:
Player Update
Something notable happened with a specific player.
Assembly:
PLAYER plid status ...
PLAYER plid/sub status ...
Encoding:
Bits | Meaning |
---|---|
00000000 | (opcode) |
The next byte:
Bits | Meaning |
---|---|
----xxxx | PlayerId |
xxxx---- | PlayerSubId |
PlayerId is the gameplay plid (view) that is affected.
PlayerSubId is the individual user/client, in game modes where multiple people can control a single in-game plid.
For messages that apply to all PlayerSubIds of a given PlayerId, the PlayerSubId field must be all-ones.
The next byte specifies the message kind (what happened):
Bits | Meaning | Granularity | Assembly | Class |
---|---|---|---|---|
00000000 | Joined | PlayerSubId | JOIN | Notification |
00000001 | Ping/RTT Info | PlayerSubId | RTT millis | Unreliable |
00000010 | Timeout | Either | TIMEOUT millis | Notification |
00000011 | TimeoutDone | Either | RESUME | Notification |
00000100 | Exploded | Either | EXPLODE y,x killer | Notification |
00000101 | LivesRemain | Either | LIVES n | Notification |
00000110 | Protected | PlayerId | PROTECT | Notification |
00000111 | Un-Protected | PlayerId | UNPROTECT | Notification |
00001000 | Eliminated | PlayerId | ELIMINATE | Notification |
00001001 | Surrendered | PlayerId | SURRENDER | Notification |
00001010 | Disconnected | PlayerSubId | LEAVE | Notification |
00001011 | Kicked | PlayerSubId | KICK | Notification |
00010010 | MatchTimeRemain | Either | TIMELIMIT secs | Notification |
10001000 | Capturing City | Either | CITCAPTING citid millis | PvP |
10001001 | Capture City | Either | CITCAPTURE citid | PvP |
10001010 | Contested City | Either | CITCONTEST citid | PvP |
... | (reserved) |
Then follows the data payload for the given message kind.
Tremor
Some explosion occurred at an unknown location. Client should shake the screen lightly.
Assembly:
SHAKE
Encoding:
Bits | Meaning |
---|---|
00000001 | (opcode) |
Smoke Start
A tile was smoked.
Assembly:
SMOKE y,x
Encoding:
Bits | Meaning |
---|---|
00000010 | (opcode) |
Followed by the coordinate of the tile.
Smoke End
A tile is no longer smoked.
Assembly:
UNSMOKE y,x
Encoding:
Bits | Meaning |
---|---|
00000011 | (opcode) |
Followed by the coordinate of the tile.
Debug
Special message reserved for use during development.
Assembly:
DEBUG i y,x
Encoding:
Bits | Meaning |
---|---|
00001110 | (opcode) |
Followed by:
u8
magic value- Tile coordinate
Flag State
Report the presence or absence of a flag on a given tile.
Assembly:
FLAG p y,x
(p == plid, 0 == no flag)
Encoding:
Bits | Meaning |
---|---|
00001111 | (opcode) |
Followed by:
Bits | Meaning |
---|---|
0000---- | (reserved) |
----pppp | PlayerId |
Reserved bits must be zero.
p
is the PlayerId that placed the flag. Zero means no flag.
Followed by the coordinate of the tile.
Construction Update
Update on the progress of a pending structure.
Assembly:
BUILD y,x current rate
Bits | Meaning |
---|---|
01001111 | (opcode) |
Followed by the coordinates of the tile.
Followed by u16
indicating current accumulated units.
Followed by u16
indicating rate of construction.
Digits (+ Implied Capture)
The specified tiles are owned by the player and display the given Minesweeper digit.
Can be used to capture tiles, if the tile is not owned by the player.
Can be used to update digits on owned tiles, when they change.
Assembly:
DIGITS d/y,x ...
DIGITS d*/y,x ...
Compact (single) Encoding:
Bits | Meaning |
---|---|
0110---- | (opcode) |
----x--- | Asterisk |
-----xxx | Digit Value |
Followed by the coordinate of the tile.
Multi-tile Encoding:
Bits | Meaning |
---|---|
1---0000 | (opcode) |
-xxx---- | Tile Count - 1 |
Followed by the coordinates of the tiles.
Followed by the digit for each tile, two digits packed into one byte:
Bits | Meaning |
---|---|
x------- | asterisk N |
-xxx---- | digit N |
----x--- | asterisk N+1 |
-----xxx | digit N+1 |
(this encoding allows them to be easily read when inspecting a hex dump)
For an odd number of tiles, the final digit is ignored (should be encoded as zero).
Structure Gone
The structure on the given tile is removed.
Used when a built structure is destroyed or bulldozed. Used when a pending (unbuilt) structure is canceled.
Assembly:
NOSTRUCT y,x
Encoding:
Bits | Meaning |
---|---|
00100000 | (opcode) |
Followed by the tile coordinates.
Structure HP
The HP of a structure changed.
Assembly:
STRUCTHP y,x hp
Encoding:
Bits | Meaning |
---|---|
0010---- | (opcode) |
----xxxx | HP |
HP must be > 0.
Followed by the tile coordinates.
Explosions
Explosions have occurred.
If the client should know what item was destroyed, send a "Reveal Item" first.
Assembly:
EXPLODE y,x ...
Encoding:
Bits | Meaning |
---|---|
0011---- | (opcode) |
----xxxx | Tile Count - 1 |
Followed by the coordinates of the tiles.
Construction Queued
A new structure is pending construction.
Assembly:
BUILDNEW y,x {road|bridge|wall|tower}
Encoding:
Bits | Meaning |
---|---|
0100---- | (opcode) |
----xxxx | Structure Kind |
The Structure Kind is:
0000
: Road0001
: Bridge0010
: Wall0011
: Tower- other values reserved
Must not be 1111
.
Followed by tile coordinate.
Followed by u16
indicating total points required to complete construction.
Reveal Structure
There is a structure on the specified tile.
Used both when revealing foreign structures and also when own structures finish construction.
Assembly:
STRUCT y,x {road|bridge|wall|tower}
Encoding:
Bits | Meaning |
---|---|
0101---- | (opcode) |
----xxxx | Structure Kind |
The Structure Kind is:
0000
: Road0001
: Bridge0010
: Wall0011
: Tower- other values reserved
Must not be 1111
.
Followed by tile coordinate.
City MoneyInfo
Reports how much money a city has.
Assembly:
CITMONEY i money
CITINCOME i money income
Bits | Meaning |
---|---|
00000100 | (opcode) |
Followed by:
u8
: City IDu32
: current money- [
u16
: current income rate]
The top bit (bit 31) of money indicates whether the
income is reported too. The income field is only
present if this bit is 1
.
The remaining 31 bits are used for the money value.
City Transaction
Reports that a city has gained or spent a given sum of money.
Assembly:
CITTRANS i spent
Bits | Meaning |
---|---|
00000101 | (opcode) |
Followed by:
u8
: City IDi16
: the amount of money
City ResInfo
Update on the resources of a city.
Assembly:
CITRES i res
Bits | Meaning |
---|---|
00000110 | (opcode) |
Followed by:
u8
: City IDu16
: the amount of resources
City TradeInfo
Update on the export/import policy of a city.
Assembly:
CITTRADE export import
Bits | Meaning |
---|---|
00000111 | (opcode) |
Followed by:
u8
: City IDu8
: Export rateu8
: Import rate
Tile Kind Update
Changes the base tile type.
Assembly:
TILE y,x {water|regular|fertile|destroyed|foundation|mountain|forest}
Encoding:
Bits | Meaning |
---|---|
0111---- | (opcode) |
----xxxx | Tile Kind |
The Tile Kind is:
0000
: Water0001
: (reserved)0010
: Mountain0011
: Forest0100
: Destroyed Land0101
: Foundation0110
: Regular Land0111
: Fertile Land- ... : (reserved)
Followed by tile coordinate.
Reveal Item
There is an item on the specified tile.
Used both when revealing foreign items and also when acking own deployed items.
Assembly:
ITEM y,x {none|decoy|mine|trap}
Encoding:
Bits | Meaning |
---|---|
0001---- | (opcode) |
----xxxx | Item Kind |
The Item Kind is:
0000
: None0001
: Decoy0010
: Mine0011
: Trap- ... : (reserved)
Followed by tile coordinate.
Ownership Update
Multiple tiles are now known to be owned by the specified player id.
Assembly:
OWNER p y,x ...
Encoding:
Bits | Meaning |
---|---|
1------- | (opcode) |
----xxxx | PlayerId |
-xxx---- | Tile Count - 1 |
The PlayerId must not be zero.
Followed by the coordinates of the tiles.
If any of the tiles are of a clustered tile kind (mountain, forest), it is assumed that the ownership update applies to the entire cluster. There is no need to list every tile coordinate of the cluster.