-
Notifications
You must be signed in to change notification settings - Fork 99
Creating a New Game: First Steps
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.
- TurnOrder encapsulates the logic of determining the current (and next) player. 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. Important: components need a
copy()method implemented, which returns a deep copy of the object, but keeping thecomponentID(from the superclass) the same. - 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:
Actions extend the core.actions.AbstractAction.java abstract class (or any of the generic actions available in the core.actions package).
- 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. - 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
equals,hashCodeandtoStringmethods, including all variables in your class in the implementations and a short informative message in the toString method. -
Important: 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 in theexecute()method, and pass theComponent.getComponentId()as a parameter in the action constructor, instead of the object reference)
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.
- Implement things.
- Use visualisation.
For easily getting your game up and running, simply create an instance of the gui.PrototypeGUI.java class to use directly with your game. This gives functionality for observing game state information, components in the game state and interaction with the game (if a HumanGUIPlayer is added) through a list of all available actions.
For further customization, create a class (e.g. "pandemic.PandemicGUI.java") extending the core.AbstractGUI.java class and put together JPanels to display all of your components (have a look at the pandemic.gui package for an example).
You can make use of generic functionality already provided in the super GUI class to add the game state information panel already defined, or the buttons that allow humans to immediately interact with the game (a HumanPlayer should be included when running for interactive functionality to work).
Run your *Game.main method (or check out more ways of running the framework)!