Devlog9. Mode Switching System


Introduction

In Dice & Domination, players can switch from the turn-based board mode to a real-time arena mode when landing on certain tiles and choose to start a battle. It allows two players to battle while others watch as spectators. When the battle ends, everyone returns to board mode and continues the game. I struggled for a long time to get  this part done. So in this blog, I will show how I coordinated player visibility, spawn locations, and battle roles across the network.

System Structure

  • PlayerController: Handles switching between board and arena player objects. It also assigns arena positions and transfers PhotonView ownership.
  • ModeSwitchManager: Manages battle start and end. It switches all players between modes, assigns roles, and restores board positions after combat.
  • BattleManager: Controls battle logic and outcome. It decides win/loss, handles payment or tile transfer, and triggers the return to board mode.

Implementation

ModeSwitchManager: 

 ModeSwitchManager handles the full transition between modes. At the start of a battle, it saves each player's board position into a dictionary using their Actor ID. This ensures that when the battle ends, everyone can return to the exact tile they came from. It then calls SwitchAllPlayersMode(true) to toggle each player's visual mode.


Arena spawn points are assigned based on player roles—Owner, Challenger, or Spectator using SetArenaPosition(). These positions are passed via RPCs to ensure all clients see the same result.  The positions are determined by finding a GameObject tagged "ArenaSpawns" in the scene and reading its children in order.


Before the battle starts, the tile’s power-up is applied to its owner. This is done using ArenaPlayerRPC.RPC_ApplyPowerUp, where the power-up type and duration are pulled from the tile’s data.

At the end of the battle, EndBattle() is called. It reads back the saved board positions and places all players back in their original spots. Each PlayerController is instructed to switch back to board visuals, and any battle UI will be destroyed.

PlayerController:

 Each player prefab includes both a boardPlayer and an arenaPlayer object. The method SwitchMode() enables one and disables the other depending on the current state. This function also toggles the matching PhotonTransformView component and transfers ownership of the correct PhotonView.


Because Unity does not support having multiple active PhotonViews per player across different character bodies, I activated only the relevant one depending on mode,  which means ownership is reassigned at runtime to make sure authority stays consistent.

BattleManager

BattleManager manages the outcome of the battle. If a player dies, the other is declared the winner. If the timer runs out, it compares both players' HP and picks the one with more health.  


 Once the result is decided,iIf the tile owner wins, the challenger pays rent; If the challenger wins, they take ownership of the tile. Payments and transfers are handled by master client through PlayerMoneyNetwork and TilePurchaseManager, and the changes will be synchronized.

Why Transfer PhotonView Ownership

Each player has two character objects: one for board mode, and one for arena mode. Also, both have a PhotonView, but Photon only allows one owned PhotonView per player at a time. If the wrong view is active or not owned, that player loses authority to sync transforms, fire RPCs, or trigger networked actions.

To solve this, the method SwitchMode() checks which mode is active and transfers ownership to the correct PhotonView. Without this, players would lose control when switching into the arena or back to the board.  

Final Outcome and Analysis

In this stage our game supports full transitions between board and battle and players are positioned correctly, assigned roles, and returned smoothly after each match. Ownership updates and transform syncing work reliably thanks to PhotonView transfer.

Design Patterns

  • Mediator:  ModeSwitchManager coordinates logic across players, UI, and arena setup without hard-coding player references.
  • Command: Each mode switch is broadcast via RPCs as network-wide commands.
  • State: Each player has two separate mode states (arena/board), and only one is active at a time.
  • Singleton: ModeSwitchManager and BattleManager follow Singleton pattern for centralized control.

Gameplay Demonstration

Start and end battle

Reference

[1] Photon Engine. (n.d.). Multiplayer Game Development Made Easy. Available at: https://www.photonengine.com/  [Accessed 2 May 2025].

Leave a comment

Log in with itch.io to leave a comment.