top of page

Player States

Starting Date: 08/02/2025

Ending Date: 07/04/2025

This blog is to create unique player behaviour by providing a state machine to identify the current state behaviour of the player.

Objective

The goal of this blog is to create and control unique behaviour for the player to use in the game, there needs to be a method where only one of the multiple behaviours is currently being used, meaning that the player is capable of controlling one behaviour at a time rather than all of them. These behaviours include:

  • Inactive - Does nothing

  • Start - Provides beginning events to happen before beginning the player's turn

  • Deciding - Choosing to either use a move/status card, ability or viewing their resources

  • Targeting - Selecting a player to be affected by the status card

  • Viewing - Looks at their resources and can choose which deck to look at

  • Roll - Choose to either roll the dice with the movement card's minimum and maximum values or cancel out

  • Move - Moves around the board

  • Choosing - Selecting a path to choose from

  • ​Attack - Current player attacks the defender

  • Defend - Inactive player reduces/prevents the attacker's attack

  • Item - When landing on an item space, give the player to choose from either obtaining a relic or giving someone an omen

  • Cursing - Selecting a player to obtain an omen

  • Market - Selecting a resource to purchase and leave the market once done with everything there

  • Spin - Deciding to spin the fruit machine or skip it entirely

​

The first objective is to create a state base to provide each state with suitable methods to overwrite when they're inherited, this will involve create an abstraction in order for each state to inherit the script and then overwrite the methods that they'll need to use.​

​

The second objective is to create a state machine to identify the current state and the change from the current to new state, this will involve a method in the state base to have a conditions to change to a specific state which should also apply the current state providing a method to exit the current state and a method to start the new state.

​

The final objective is to provide controls to some of the states since the player will need to input certain actions on each state that includes any inputs, this will involve using interfaces that can be use for each state to inherit and provide in their scripts.

Techniques

Abstraction

Abstraction is an object oriented programming technique that allows the abstract script to have abstract methods which any script inheriting the abstract script to overwrite the abstract methods.

​

I used abstraction to create an abstract base that involves 3 abstract methods, one called enter which will be use when a new state begins executing, another called update which aims to be used as an update method for the states and the final method called exit which executes the last method before changing to the new state.

 

This becomes very useful for the behaviours because the methods can be structure in the state machine in order for the machine to start the new state, update the state constantly and end the state once the machine changes to a new state, which leads a efficient method to organise the state machine. 

State Pattern

The state pattern is a design pattern that can provide unique states for a object, this can be use for a player or a non-playable character to provide a current state depending on the activities occurring the game. A state machine is used to identify the current state and change the state from the current to the new state with the current state executing one last method before exiting and the new state executing one method after entering as the current state.

​

I use the state machine and merge it with abstraction to create a abstract state machine which will use the state base to identify the current state and will provide the three methods in each state inheriting the state base for the state machine to call the new state's enter method when the current state has changed provide unity's update method to constantly update the update method in the state base which will check to see if the a boolean value to change the state becomes true which will change the state based on the suitable boolean set to true and finally the machine will call the current state's exit method to execute last bit of code before changing to the new state.

​

This becomes extremely useful this separates the behaviour to have single responsibilities and I can be open to create more states for the future whilst closing modifying the machine (open-closed), which allows the player to experience unique behaviour on their turn, which can lead the player to be capable of controlling one behaviour at a time rather than all of them at once.​​

Interface Inheritance

Interface in programming is a contract that provides methods which when a script inherits a interface must use the methods inside of that interface.

​

I use interfaces for the states that involves one of each control input such as up, down, left, right, view, one use, confirm, exit and cancel which each state can inherit (if required) to provide control input for the board controls to invoke the events of the interface.

​

This become suitable towards player controls when controlling each state, because using interface can make each state following liskov substitution which can provide the suitable interfaces to each state as well as separating the interface from controls to certain inputs to follow interface segregation.

Challenges

Cancel Roll to Randomise Cards

The biggest issue towards this mechanic was that during implementing the roll state, when cancelling the roll to return to the deciding state, the cards were randomised.

 

This was a major issue because the player can exploit by choosing a move card and then cancelling their roll to change the cards until they get the card they want which ignores the RNG in drawing cards.

​

This was fixed by adding another state base which instead of tracking the current state will track the previous state, which checks the previous state in order to identify if the deciding state needs to draw cards after changing from the start state or keep the cards if they're cancelling their rolls, which not only benefitted this issue, but for future issues as well such as if the player uses a status card from the target state and has selected a player, then the the deciding state will need to keep the drawn cards, which leads the players to only have the movement cards they've drawn at the start of their turn.

​

Achieved

State Machine Complete

The state machine was complete by creating all the states for the state machine to reference in the object's components and have the change method be called to provide the new state to set the previous state as the current state and the new state as the current state, as well as providing suitable interface for the player to input in the current state.  

​

This becomes very efficient for the player because they can provide actions in each state in order for them to decide on the card or path they want, target their opponent, confirm and cancel choices and leave the game, which leads the player to have suitable inputs in each state.

Conclusion

Overall, I have learnt how to provide a state machine to control and separate the player behaviour and merge the machine with abstraction in order to inherit each state with suitable methods to overwrite for the state machine to use to start the new state's implementations, update on changing state conditions and ending the current state's implementations before changing. I have also learnt that interface can be a very viable tool to use to ensure that a input is included in each state by having the state inherit each suitable interface it requires.

​

As a programmer, I feel like my skills have improved on provide singular responsibility, separating player behaviour, ensuring certain methods to be used and enabling me to add more onto a script without modifying existing implementations.

​

If a game includes multiple player behaviour, then I'm certain to use the state pattern to divide the behaviour into smaller states for the player to control in the game. In fact I'm likely use this pattern for objects besides the player such as a non playable character to divide the behaviour into suitable states.​

bottom of page