Game Manual¶
Gameplay¶
Introduction¶
The Devops Game is a multiplayer online turn-based strategy game. Each student group (Team) will be represented by its own Faction in a single world shared by all the groups. A Faction can build units to generate income and conquer territory. As you conquer more territory, your Faction is able to support a bigger population of units, allowing you to have a bigger influence on the game world. However, other Factions are aiming to control the same territories, requiring you to engage in combat to defend your lands.
Unlike a typical strategy game, you won't control your Faction directly. Instead, you will program the decision logic for the Faction, which will be called by our game host server (running the game session) at the start of every new turn. A basic decision logic implementation is provided to get you started. Your goal is to improve upon this implementation in order to gain a competitive edge by adding additional intelligence to the logic that is calculating your next moves.
The ultimate goal is to be the last faction standing or to have the highest score (in case the game ends in a stalemate). A Faction is defeated if its base can be conquered by an enemy Faction.
Game world¶
The game world is a two-dimensional grid of a certain width and height (randomized within specified boundaries). Each tile in this grid represents a unique Location (e.g. Faction base). Units can move around from the Location they're on to any of its adjacent tiles, but there can never be two units on the same tile!
The entire game state can thus be described as a collection of Locations with the following properties:
- A coordinate pair, representing the position of the Location in the grid. * X increases from 0 (screen left) to the width of the map (screen right). * Y increases from 0 (screen top) to the height of the map (screen bottom).
- A boolean value indicating if the Location has a Faction base built on top (Visually represented
as
).
- A boolean value indicating if the Location has a special resource that can grant additional income (Visually
represented as
).
- A boolean value indicating if the Location is fortified by a Faction, making it harder for it to be reconquered by
other Factions (Visually represented as
).
- A boolean value indicating if the Location has been rigged with explosives. Units stepping on an enemy bomb, will be
immediately
removed from the game (Visually represented as
). Important: Only units of type SAPPER can see the true state of this attribute. Unit move input data for units of any other type, will always contain
false
as value for the mined attribute. - A reference to the Faction that currently holds the Location (Visually represented by coloring the tile in the color of the Faction). If there is no such reference, the Location is considered neutral (Visually represented by a light-gray tile fill).
- A reference to the Unit that is currently visiting the Location (Visually represented by a letter indicating the type
of Unit, drawn onto a smaller square of the Unit's Faction color e.g.
).
Important: the World map wraps around in both dimension!
A Unit on the top of the map can travel to an adjacent Location on the bottom of the map.
A Unit on the left of the map can travel to an adjacent Location on the right of the map.
Your Faction¶
Faction properties¶
The Faction you control also has a number of data properties. Some of these properties affect the moves you can make each turn, while others are an indication of your performance in the game session:
base
: A Faction has a fixed Base Location. New Units created by the Faction will be spawned on this Location. Prevent your Faction Base from being conquered by an enemy Faction at all cost! Factions who lose control over their Base Location are immediately defeated!buildSlot
: Each Faction has a single build slot. When a Faction starts constructing a new Unit, it is added to this build slot and will remain there until it is completed (the number of turns this takes depends on the Unit type). You can only build one Unit at a time! When the Unit is completed, it will be spawned at the Location of the Faction Base.gold
: The single currency of the game. When creating a new Unit, a certain amount of gold is required (depending on the Unit type). Gold is earned by letting your Units spend their turn on generating income, or by letting your Base generate income (instead of using your turn to build a unit).bombs
: The number of bombs the Faction has available to deploy. Bombs can be deployed on Locations owned by the Faction by units of type SAPPER. Bombs can be manufactured as a base move (this action costs gold).territorySize
: the extent of the territory the Faction controls, counted as the number of Locations currently owned by the Faction.population
: the number of alive Units the Faction currently has.populationCap
: the number of Units the Faction can currently support (increase your territory size to increase this cap).kills
: the number of enemy Units that were killed by your Faction.score
: the total score of your Faction. You win the game by being the only remaining Faction or by having the highest score.defeated
: A boolean value indicating if the Faction has been defeated.
Faction base¶
Each Faction is assigned a starting location, which is considered the Faction's base. The base must be defended at all cost, as losing control over it will result in immediate defeat. Each game turn, you will have to decide on a move that can be executed from your base. The available moves are:
RECEIVE_INCOME
: generate income for the Faction (500 gold). This move is free and can be used to generate gold, which is needed to perform other base or unit moves.BUILD_UNIT
: start building a new Unit of a specific type. The amount of gold this move costs, is determined by the type of Unit that is being built (see Unit overview).CONTINUE_BUILDING_UNIT
: continue building the Unit that is currently in the build slot. This move is only available when a Unit is being built. The amount of turns required to complete the Unit is determined by the Unit type. This move is free.MANUFACTURE_BOMB
: manufacture a bomb. This move is only available when the Faction has enough gold to pay for the manufacturing cost of a bomb [500 gold].MOVE_BASE
: move the Faction base to a different base location owned by the Faction. This can be useful when enemy factions are getting too close to your current base location. A Faction can obtain additional base locations by conquering the tiles on which enemy bases are located. This move is free.IDLE
: the Faction can choose to idle when there is no other possible move it can make. This move is free.
Units¶
There are 5 distinct types of Units: PIONEER
, WORKER
, FIGHTER
, CLERIC
and SAPPER
. The Unit type determines how much a Unit costs, how long it takes to build, how much health it starts with, the potential damage it can deal and what moves are available for the Unit.
The game logic we've provided, implements behavior for the basic types PIONEER
, WORKER
and FIGHTER
.
Types Overview¶
Unit | Gold Cost | Turns to build | Starting Health | Damage | Upkeep |
---|---|---|---|---|---|
PIONEER | 200 | 2 | 3 | 2 | 25 |
WORKER | 350 | 3 | 5 | 0 | 45 |
FIGHTER | 700 | 4 | 6 | 3 | 90 |
CLERIC | 500 | 5 | 4 | 1 | 60 |
SAPPER | 850 | 4 | 6 | 2 | 90 |
PIONEER¶
A PIONEER
is a "Jack of all trades, master of none". It can perform both offensive moves (e.g. conquering territories) and utility moves (e.g. generating income).
However, a FIGHTER
outclasses the PIONEER
when it comes to offensive moves, and the WORKER
outclasses the PIONEER
when it comes to utility moves.
Each Faction starts with two PIONEER
Units.
Gold Cost | Turns to build | Starting Health | Damage | Upkeep |
---|---|---|---|---|
200 | 2 | 3 | 2 | 25 |
Available moves:
TRAVEL
CONQUER_NEUTRAL_TILE
NEUTRALIZE_ENEMY_TILE
GENERATE_GOLD
ATTACK
RETIRE
IDLE
WORKER¶
A WORKER
is a pure utilitarian Unit. Its role is supporting your Faction by generating income (WORKER
Units have to ability to gather resources)
and fortifying controlled Locations.
Gold Cost | Turns to build | Starting Health | Damage | Upkeep |
---|---|---|---|---|
350 | 3 | 5 | 0 | 45 |
Available moves:
TRAVEL
CONQUER_NEUTRAL_TILE
GENERATE_GOLD
FORTIFY
RETIRE
IDLE
FIGHTER¶
A FIGHTER
focuses on offensive moves. Its role is to help fending off enemy attacks and to have a more robust Unit (compared to a PIONEER
)
to stage attacks on enemy strongholds.
Gold Cost | Turns to build | Starting Health | Damage | Upkeep |
---|---|---|---|---|
700 | 4 | 6 | 3 | 90 |
Available moves:
TRAVEL
CONQUER_NEUTRAL_TILE
NEUTRALIZE_ENEMY_TILE
ATTACK
PREPARE_DEFENSE
RETIRE
IDLE
CLERIC¶
A CLERIC
is an additional utilitarian Unit. Its role is supporting your Faction by healing friendly units and trying to convert enemy units to your Faction’s side.
Gold Cost | Turns to build | Starting Health | Damage | Upkeep |
---|---|---|---|---|
500 | 5 | 4 | 1 | 60 |
Available moves:
TRAVEL
ATTACK
PRAY
HEAL
CONVERT
RETIRE
IDLE
SAPPER¶
A SAPPER
is a combat support Unit. It can deploy and defuse bombs. SAPPER
units are immune to bombs,
but any other unit stepping on a bomb that is not in friendly territory, is immediately removed from the game.
Gold Cost | Turns to build | Starting Health | Damage | Upkeep |
---|---|---|---|---|
850 | 4 | 6 | 2 | 90 |
Available moves:
TRAVEL
ATTACK
PREPARE_DEFENSE
DEPLOY_BOMB
CLEAR_BOMB
RETIRE
IDLE
Moves Overview¶
Moves represent the interactions a Unit can have with the game world and other Units. Most moves are free, but others have a gold associated with them. The following list gives an overview of the available moves:
TRAVEL
: travel from the Unit's current Location to an adjacent Location. The new Location cannot be occupied by another Unit (otherwise theTRAVEL
move is invalid).CONQUER_NEUTRAL_TILE
: if the Unit is on a neutral Location (not occupied by any Faction), it can use this move to conquer the Location (the Location owner becomes the Unit's Faction).NEUTRALIZE_ENEMY_TILE
: if the Unit is on an enemy Location (occupied by an enemy Faction), it can use this move to make the Location neutral again. However, if the Location is fortified (by an enemyWORKER
), performing a neutralize move will only remove the fortifications. So fortified tiles effectively take two turns to neutralize!GENERATE_GOLD
: a Unit can spend a turn on generating extra income for the Faction when it is on a tile owned by this Faction. When aWORKER
Unit is on a Location that holds a resource (and is owned by the Faction), this move will grant 3x the amount of gold (by mining the resource).ATTACK
: attack an enemy Unit. The target Unit must be in a Location adjacent to the current Location of the Unit performing the attack.PREPARE_DEFENSE
: boost the defensive capabilities of the Unit. A Unit that has defenses prepared only takes half of the damage when attacked. However, the defenses are immediately destroyed after any attack.FORTIFY
[Gold cost: 250]: if the Unit is on a Location owned by its Faction, it can make the tile harder to conquer by fortifying it. Fortified tiles take an additional turn before they can be neutralized by an enemy Unit.HEAL
: heal a friendly Unit. The target Unit must be in a Location adjacent to the current Location of the Unit performing the healing.PRAY
: pray to achieve an enlightened state. Units in an enlightened state are immune to the next incoming attack. This is also the prerequisite for converting enemy units (seeCONVERT
).CONVERT
: convert an enemy Unit (the enemy Faction will no longer control this Unit as it becomes a member of your Faction). The target Unit must be in a Location adjacent to the current Location of theCLERIC
. The conversion will fail if the following prerequisites are not met:- The Cleric must be in an enlightened state (see
PRAY
) - The Faction must be able to support the converted Unit (the population cap and upkeep remains applicable).
- The Cleric must be in an enlightened state (see
DEPLOY_BOMB
[Gold cost: 25]: deploy a bomb, only possible on a Location occupied by your Faction. When an enemy unit (that is not aSAPPER
) visits the rigged Location, the bomb detonates, immediately removing the Unit from the game.CLEAR_BOMB
: defuses a bomb on the current Location.RETIRE
: the Unit retires and is removed from the game. Retiring units allows freeing up population space and reducing upkeep.IDLE
: the Unit can choose to idle when there is no other possible move it can make.
Logic Control¶
Your Faction is controlled by a Decision Logic written in Java, which must implement the FactionLogic
interface (which
you can find in the commons module of your repository, along with the other definition classes for the logic). This
implementation is then wrapped in an HTTP service so that it can be called remotely from the server running the game
session.
Each turn the game session will contact your Decision Logic to get the next move for your Base (e.g. whether to focus on income, or on building units). Subsequently, a call is made to get the next move for each alive Unit tied to the Faction.
nextBaseMove¶
This operation is used to define the decision logic for the Base move. The input for this operation is defined by the
type BaseMoveInput
, which contains all the necessary information required to make an informed decision on what the
next base move should be:
- A
GameContext
instance, providing you with up-to-date information about the current Game session, such as the Game id, the current turn number, the map dimensions, gold cost for creating units or performing moves. - A
Faction
instance, providing you with up-to-date values representing the state of your Faction, including: amount of gold, territory size, current population and cap, total amount of enemy Units killed, the current score, bonuses that are active and the current unit upkeep for the Faction. - The state of the build slot (so you can know if a new Unit can be built, or to track the progress of a Unit that is being built right now).
Your implementation should then output an object of type BaseMove
, which completely describes the move that should be
applied by the game session host. We provide a MoveFactory
which has a number of factory methods to create move
instances in a convenient way. For example:
MoveFactory.baseBuildUnit(type)
to start building a Unit of the specified type.MoveFactory.baseReceiveIncome()
to generate income for the turn instead of focusing on Unit building.MoveFactory.baseManufactureBomb()
to manufacture a bomb (adding to the faction's bomb stockpile to be used by SAPPERs).
nextUnitMove¶
This operation is used to define the decision logic for the Unit move. The input for this operation is defined by the
type UnitMoveInput
, which contains all the contextual information required to make an informed decision on what the
next move should be for a particular Unit:
- A
GameContext
instance (referring to the current Game session). - A
Faction
instance (referring to the Faction you're playing). - A reference to an instance of type
Unit
, representing the state of the Unit: the Unit type, the amount of damage it can do, the amount of health left and whether a defensive bonus is currently activated. - The current Location of the Unit (which includes information such as whether the Location holds a resource, or is fortified, ...)
- A list of neighbouring Locations: all tiles on the world map that are adjacent to the one the Unit doing the move is currently on.
Your implementation should then output an object of type UnitMove
, which completely describes the move that should be
applied to the Unit by the game session host. Reminder: use the MoveFactory
to construct Unit moves. For example:
MoveFactory.unitTravelTo(location)
to travel from the current Location to the specified Location.MoveFactory.unitAttack(otherUnit)
to attack the specified Unit.MoveFactory.unitFortifyLocation()
to fortify the Location the Unit is currently occupying.
Important
Some moves cost gold. Make sure you can afford the selected move type! The game host will ignore all invalid moves, resulting in a lost turn for the respective Unit.
Other¶
Starting Locations¶
When a new game is created, a number of starting Locations are generated spread out evenly across the world map. Each Faction is then randomly assigned one of these Locations.
A Faction's starting Location obviously can have an impact on its performance in the game, but by randomizing the assigned bases and by implementing a wrap-around World map, we've tried to create a situation that is as fair as possible.
Unit upkeep¶
Each Unit has a certain upkeep, which must be paid in gold at the beginning of every turn. The total upkeep for your
Faction can be retrieved via the Faction
instance that is part of every move input.
If a Faction is not able to pay the upkeep, a score penalty is applied (currently set at -75 points ).
A Faction can reduce its upkeep by retiring units (using the RETIRE
Unit move).
Score calculation¶
A Faction can accumulate score points in the following way:
- By neutralizing Locations owned by enemy Factions (20 points).
- By conquering neutral Locations (25 points).
- By conquering resource Locations (15 points).
- By killing enemy Units (25 points).
- By fortifying Locations in its territory (10 points).
- By healing friendly Units (via Units of type
CLERIC
) (10 points). - By converting enemy Units (via Units of type
CLERIC
) (25 points). - By defusing enemy bombs (via Units of type
SAPPER
) (15 points). - By being the Faction with the largest territory (each turn a small bonus of 10 points will be assigned to the score as long as this condition holds).
- By creating units (10 points for base units such as PIONEER, WORKER, FIGHTER and 25 points for special units such as CLERIC and SAPPER).
- Warning: when retiring a unit, this score bonus is deducted again!
Turn execution flow¶
It is important to know how the game session host handles the execution of a turn and more specifically what the execution order is of the moves for each Faction. It allows you to take on the correct assumptions when implementing your Decision Logic.
Description of the execution flow:
-
For each Faction in parallel:
- Retrieve the Base Move
- Check if a valid bonus code was redeemed and should be activated.
- For each of the Faction's Units in parallel: Retrieve the Unit Move.
-
Shuffle the list of alive Factions
-
In order of the shuffled Faction list:
- Apply the Faction Base move to the state of the game.
- Apply each of the Unit moves to the state of the game (in arbitrary order).
-
Check if any Factions were defeated this turn and if so, remove its Units and set all the Locations owned by this Faction back to neutral.
Important points to take from this:
- All moves are retrieved from the
FactionLogic
implementations before they are applied to the game state! - This means that the context information you get as input for each operation reflects the state of the world at the beginning of the turn. Changes made by other Factions or yourself will only apply the next turn and will not be visible in any of the input objects. You are responsible for preventing conflicts (e.g. don't move two Units to the same Location).
- Each turn the Faction move execution order is shuffled, because a fixed order would benefit the Factions that take a turn first.
Timeout and Exception penalties¶
Each call by the game session host to your FactionLogic
implementation is timed. If it takes longer than one second to
respond, the request is aborted and a penalty is applied by taking away a small amount of your Faction's score (
currently set at -100 points per failed request).
If the operation call results in an error (e.g. caused by a faulty configuration), the same penalty applies.