Devlog4. Designing Scalable Board Data
Introduction
While developing the multiplayer board game Dice & Domination, I wanted each tile on the board to be fully data-driven. Instead of hardcoding tile properties, I decided to use an external CSV file to control names, colors, prices, rent, and other attributes. This made updates faster and allowed designers to edit data without touching code.
How I Read and Utilized a CSV File in Unity
Workflow Overview
Our team’s designer provided the initial data in an Excel spreadsheet. I cleaned up the formatting (e.g. removing inconsistent text and special characters), then exported it to CSV format. This CSV was then imported into Unity and parsed using a custom script.
CSV File Format
Each row in the file defines one tile and includes data:
Number, TileName, BuyingPrice, Rent, RentWithSet, SetSize, SellingPrice, Description, PowerUp, Effect, ...
🔗File: TileSheet
System Structure
To support this workflow, I split the system into three main components:
-
TilesData.cs
A plain data class. Each CSV row is converted into a TilesData object containing static values like tile number, color, and rent. -
TileCSVReader.cs
A singleton responsible for loading the CSV at runtime using Resources.Load<TextAsset>(). It parses and stores all tile data in a global list. -
TileVisualizer.cs
Attached to each tile GameObject. This component uses its tile number to find the correct TilesData, then updates visuals and stores runtime states (like ownership).
Implementation
TilesData:

TileCSVReader:
The CSV file is read using Resources.Load<TextAsset> from Resources/Form/TileSheetForm.csv. The raw text is passed to ParseCSV()
, which splits it into lines and processes each one after the header. Each line is split into fields using a regular expression to avoid breaking quoted values. To solve this, I used a regex pattern, it keeps the quoted string together as one field, even if it contains commas.
For example:
3,2859b3,Little Great Wall,200,...,"It's... kinda defensive, but cute",...
A simple Split(',') would break the description incorrectly:
["3", "2859b3", ..., "\"It's... kinda defensive", " but cute\"", ...]
Once split and cleaned, each row is mapped into a TilesData object. During this conversion, numerical fields such as price and rent are parsed using TryParseInt(), colors are interpreted through HexToColor(), and power-up types are processed via ParsePowerUp().

TileVisualizer:
When the game starts, it checks tile's assigned tileNumber and looks up matching data from TileCSVReader.Instance.
The Reset() method tries to detect the tile number automatically from the GameObject’s name. If the name contains a number, it parses it and assigns it to tileNumber.This helps speed up setup when many tiles are added into the scene at once.

Display of tile data after game starts(left) and route hierarchy (right)
In Start() method it checks if the tile’s material is already a unique instance. If not, it clones a new material. This is important because otherwise, all tiles would share the same material, and changing one tile’s color would accidentally change all others.
The main function UpdateTileVisual() handles loading the tile's data from the parsed tilesdata list. It first looks up the TilesData entry that matches the current tileNumber. Once the data is found, it sets the tile’s color by modifying its material color. Also, if the tile is owned by a player, it also displays a clan icon above the tile, using the player's assigned clan symbol from their Photon custom properties. If no owner is assigned, or if the owner has no clan icon set, the icon stays hidden.
The GetPlayerById() method searches through the Photon player list to find the player who owns a specific tile. It matches based on the player's ActorNumber, which is consistent across the network.
Gameplay Demonstration
Changing tile’s color according to its tile data
Place an ownership icon on the tile and synchronize it over the network
Icon visualization
Problems and Fixes
Problem | Solution |
Parsing errors due to commas in text fields | Switched from |
All tiles changed color together | Instantiated a new Material at runtime for each tile to prevent color overlap. |
Default tileNumber was 0 and caused warnings | Updated default to 1 and added a validation check during parsing. |
Design Patterns
- Singleton:The TileCSVReader uses a static Instance to ensure there is only one authoritative source of tile data across the game.
- Mediator: The TileVisualizer acts as a mediator between different subsystems: static tile data, rendering , and UI elements. It coordinates updates without these components needing to communicate directly with each other.
- Bridge Pattern:TileVisualizer acts as a bridge between static TilesData and rendering and UI systems.
- State Separation: Static data (price, rent, color, etc.) are stored in TilesData, while runtime data, such as ownership and ownership icon are handled by TileVisualizer.
Final Outcome
- All tile visuals and logic are driven by the external CSV file, which allows designers to tweak tiles without touching code. Also, the system is modular, scalable, and multiplayer-ready, with syncing possible through tile numbers and ownership state.
Reference
Gerenated ownership icon images. Source: ChatGPT
- [1] OpenAI, 2025. ChatGPT . OpenAI. Available at: https://openai.com/chatgpt [Accessed 30 March 2025].
- [2] Photon Engine. (n.d.). Multiplayer Game Development Made Easy. Available at: https://www.photonengine.com/ (Accessed: 30 March 2025).
Dice & Domination
A high-stakes multiplayer strategy game with domination and combat
Status | Released |
Author | Angir |
Genre | Strategy |
Tags | 3D, Board Game, monopoly, Multiplayer, Top down shooter |
Languages | English |
More posts
- Devlog 10. Score Display & Conclusion43 days ago
- Devlog9. Mode Switching System46 days ago
- Devlog8. Backend System and Camera Setup47 days ago
- Devlog7. Money and Tile Ownership47 days ago
- Devlog6. UI Display of Dice&Domination48 days ago
- Devlog5. Turn Management50 days ago
- Devlog3. Dice Rolling and Board Movement54 days ago
- Devlog2. Programming Architecture79 days ago
- Devlog1. Game Design of Dice&Domination88 days ago
Leave a comment
Log in with itch.io to leave a comment.