Repository navigation
Map Graph System
The Map Graph System represents the structure of the game map and manages player progression between map nodes.
The system is centred around the MapGraph class, which stores MapNode objects, maintains connections between nodes, tracks the player's current node, and updates node states as encounters are completed. The MapGraph system is able to procedurally generate unique combinations of connections and MapNode objects that form into distinct paths for the player to traverse in game. This generation is handled internally in the instantiation of the MapGraph class and with the MapGenerationController class.
Each MapNode has a NodeState representing its current progression state:
-
CURRENT- the node currently occupied by the player. -
AVAILABLE- a node that the player may move to. -
LOCKED- a node that is not currently accessible. -
COMPLETED- a node whose encounter has been completed.
These states are used by the map progression and UI systems to determine which nodes can be selected and how each node should be displayed.
MapGraph maintains a reference to the player's current node through currentNode.
The current node can be retrieved using:
getCurrentNode()
This allows other systems to determine the player's current position within the map graph.
Nodes can be retrieved according to their current state using:
getNodesByState(NodeState state)
The method returns a list containing all nodes whose state matches the supplied NodeState.
For example, this can be used by the map UI to retrieve all AVAILABLE nodes that should be selectable by the player.
getNodesByHeight(int height)
Returns a list of all the nodes at the provided layer or height. The layers in the MapGraph are indexed from 1.
Player movement between nodes is handled by:
moveToNode(Integer nodeId)
Before moving, the method validates that:
- the target node exists;
- the target node is
AVAILABLE; - the target node is connected to the current node.
If the movement is valid, currentNode is updated to the target node and the target node's state becomes CURRENT.
If any validation condition fails, the movement is rejected and the map state remains unchanged.
Encounter progression is handled by:
completeNode(Integer nodeId, boolean success)
When an encounter is completed successfully:
- The completed node is changed to
COMPLETED. - Connected nodes that are currently
LOCKEDbecomeAVAILABLE. - Adjacent nodes to the completed node that were
AVAILABLEare set toLOCKED.
If the encounter is unsuccessful, no progression state changes are made.
MapGraph also implements EncounterCallback, allowing encounter completion events to trigger the appropriate map progression updates.
Connections between nodes are maintained by MapGraph.
connectNodes(MapNode firstId, MapNode secondId)
creates a bidirectional connection between two existing nodes.
These connections are used when determining which nodes can be reached from the player's current position.
MapNode now has a method setHeight(Integer height) which is needed for any unit testing of map graph since a small sample of nodes result in all nodes being placed in layer 0. This is an issue as after an encounter success any previously available node in that same layer are set to locked.
-
MapGraph- stores the graph and manages progression state. -
MapNode- represents an individual node in the map. -
NodeState- defines the possible progression states of a node. -
EncounterCallback- allows encounter completion events to update map progression. -
MapGenerationController- handles procedural generation of MapGraph
Unit tests for the Map Graph System are located in:
MapGraphTest
Current tests cover node-state retrieval, encounter completion behaviour, invalid node handling, and initial current-node state.
Note for testing, Nodes have a method setHeight(Integer height) which is to ensure the nodes lie on seperate heights when testing involves completing an encounter. This is done because as a node is completed, the adjacent nodes are set to locked which would change the state of nodes unexpectedly in tests. However in normal gameplay it has no issue. If a test is failing because the states are wrong, it's likely due to this. Simply ensure the nodes are on different heights.