2-Player Strategy Game with a Custom Replay Feature
A two-player, turn-based game played locally on a 10x10 grid. The game features randomly generated fleets of seven ships in various sizes: two 1x1, two 2x1, one 3x1, one 4x1, and one 5x1. Players take turns selecting coordinates to launch attacks, aiming to sink their opponent's fleet. The first player to sink all of their opponent's ships wins.
The game records replays after each match, allowing players to review and playback their moves.
Created with Unity 2021.3.13f1
Clone/download repository and open up the project with Unity.
It is currently recording the entire state of the board
Replays are saved in .json
format in Application.persistentDataPath
directory
i. e. (Appdata/LocalLow/DefaultCompany/Battleships
)
It is only injecting the player actions and not reading the entire state. Replay module will play the most recent recorded replay. It can be accessed from the main menu.
At the current state of affairs, it's possible to play/pause replay on demand. Note that if the action has already been processed, it will be passed to the injector, and replay will be paused after the particular action. This might be changed in the future.
Although not fully featured, it is designed with flexibility in mind and could potentially support usage across similar projects in the future
Replay module consists of various interfaces and classes that implement them. For replay to be successfully recorded and saved to the disk, we rely on ReplayData
class, which implements IReplayData
interface.
IReplayData
public Task<bool> SaveToFile();
public void UpdateState(List<IReplayStateData> stateToUpdate, IReplayStateData stateData);
IReplayStateData
Empty abstraction for storing data objects in ReplayData
.
Example:
public class PlayerData : IReplayStateData
{
// ... some player data
}
IReplayRecorder
(partial modularity) Note: IPlayerAction
will be abstracted to IReplayDataCapsule
. Inject a concrete ReplayDataCapsule
to persist data to the replay state.
public void PersistReplayDataCapsule(IPlayerAction action);
public Task<bool> SaveReplay();
Example implementation (from current version):
public void PersistReplayDataCapsule(IPlayerAction playerAction) {
var replayData = new ReplayData(); // creates an empty static state
replayData.staticData = new List<IReplayStateData>() {
/* some stateful data (i. e. player data) */
};
var myDataCapsule = new ReplayDataCapsule()
{
playerAction = (IReplayStateData) playerAction
// ... desired state
}
replayData.UpdateState(replayData.stateHistory, myDataCapsule); // push state
}