This page describes what to implement in all of the classes required for a new game. If you prefer to read about a more dynamic approach to implementing a game (adding functionality incrementally in various classes), check out this page instead.
The diagram below is an overview of the classes to be implemented (in blue). The area of each box is a rough guide to the relative amount of effort for an ‘average’ game.
- Game: This is mostly just a container to tie everything else together and despite its name has very little game-specific code. All the real work is done in the default implementation in the framework. When a Game is run it holds
- The Players (implementations of the Player interface, whether Human or AI, detailed in Implementing an AI
- The Forward Model
- The current Game State
- GameState is the core. It holds all of the data that describes the current state of the game.
- ForwardModel complements GameState. It contains the logic of the game rules, and is used to advance the GameState by applying Actions to it. It is also responsible for generating the list of Actions that can be taken by the current player in a given GameState. This should be kept stateless - with any state information stored in either GameState or TurnOrder. The game rules are often split between ForwardModel and the individual Actions, with the Actions containing the logic specific to them (this is encouraged to reduce the amount of code in ForwardModel).
- TurnOrder encapsulates the logic of determining the current (and next) player. It also stores the state of who the current player is. This can also trigger game rules related to the end of a turn, which sometimes can be a more natural fit here than in ForwardModel.
- Components are things like a board, playing pieces, cards, decks of cards. Generally the framework-provided Components will suffice, but game-specific ones can be added where needed.
- Parameters are static game settings, such as board size, number of players, rule variants being applied or the cost of buying a Dreadnought. They do not change during a game, but might differ between games.
- Actions are the moves that Players make. When it is a Player’s turn, Game will give them a copy of the current GameState and a list of Actions that can be taken. They pick one, return their choice, and then the ForwardModel will apply this to the master GameState to progress the game.
A list of the games currently implemented, with notable features in their technical implementation can be found here. A good idea is to look through the code of an existing game that most closely reflects the one you want to implement.
Then, create a new package for the game with the same name in the
games package (e.g.
"games.foobar"). Then follow these steps:
Implement core classes
Define basic game information and data
Implement game-specific actions and/or rules
Actions extend the
core.actions.AbstractAction.java abstract class (or any of the generic actions available in the
- Implement the
execute(AbstractGameState gameState)method, which should modify the given game state according to the purpose of the action, and return true if the action was executed successfully, or false otherwise.
- Implement the
copy()method, copying all variables in your class. Do not hold any references in your actions, primitive types only! This is important for the correct objects to be updated by the AI when copying game states (use the
AbstractGameState.getComponentById(int componentId)method to retrieve components, passing the
Component.getComponentId()method result as a parameter).
- If your action requires a card to be played, implement the
getCard(AbstractGameState gameState)method as well, which should return the card used for this action (usually discarded afterwards).
- Override the
toStringmethods, including all variables in your class in the implementations and a short informative message in the toString method.
Rules extend the
core.engine.RuleNode.java abstract class (or any of the generic classes available in the
core.engine package). You may use these in the forward model to set up and more easily control the game flow.