Airysh

Airysh

Engineer

Read Resume

Building Games with Unity: My ChessHalla Journey

Lessons learned while building a chess game in Unity using C#.

Why Chess?

Chess is the perfect game development project because:

  1. Clear rules — No ambiguity about what's allowed
  2. Complex logic — Move validation, check detection, special moves
  3. Visual feedback — Board state, highlights, animations
  4. Scalable complexity — Can add AI, multiplayer, different modes

Project Structure

ChessHalla follows Unity best practices:

ChessHalla/
├── Assets/
│   ├── Scripts/
│   │   ├── Board/
│   │   ├── Pieces/
│   │   └── Game/
│   ├── Prefabs/
│   └── Materials/
├── Packages/
└── ProjectSettings/

Core Systems

1. The Board Representation

I use a 2D array for the board state:

public class Board : MonoBehaviour
{
    private Piece[,] pieces = new Piece[8, 8];
    
    public Piece GetPieceAt(int x, int y)
    {
        if (x < 0 || x > 7 || y < 0 || y > 7)
            return null;
        return pieces[x, y];
    }
}

2. Move Validation

Each piece type has its own movement rules:

public abstract class Piece : MonoBehaviour
{
    public abstract List<Vector2Int> GetValidMoves(Board board);
    public abstract bool CanCapture(Vector2Int target, Board board);
}

public class Knight : Piece
{
    private static readonly Vector2Int[] offsets = {
        new(-2, -1), new(-2, 1), new(-1, -2), new(-1, 2),
        new(1, -2), new(1, 2), new(2, -1), new(2, 1)
    };
    
    public override List<Vector2Int> GetValidMoves(Board board)
    {
        var moves = new List<Vector2Int>();
        foreach (var offset in offsets)
        {
            var target = Position + offset;
            if (IsValidMove(target, board))
                moves.Add(target);
        }
        return moves;
    }
}

3. Check Detection

Before allowing a move, we must verify it doesn't put the king in check:

public bool WouldBeInCheck(Move move, PieceColor color)
{
    // Simulate the move
    var tempBoard = CloneBoard();
    tempBoard.ApplyMove(move);
    
    // Find the king
    var kingPos = tempBoard.FindKing(color);
    
    // Check if any enemy piece can capture the king
    return tempBoard.IsSquareUnderAttack(kingPos, color.Opposite());
}

4. Special Moves

Chess has several special moves that need custom handling:

Unity-Specific Lessons

Lesson 1: Separate Logic from Visuals

The board state (data) should be independent from GameObjects (visuals):

// Bad: Logic tied to Unity
transform.position = new Vector3(x, 0, y);

// Good: Logic separate, visuals update from state
boardState[x, y] = piece;
visualizer.UpdateBoard(boardState);

Lesson 2: Use ScriptableObjects for Configuration

Piece sprites, colors, and settings go in ScriptableObjects:

[CreateAssetMenu(fileName = "PieceConfig", menuName = "Chess/Piece Config")]
public class PieceConfig : ScriptableObject
{
    public Sprite whiteKing;
    public Sprite blackKing;
    public Color highlightColor;
    public float moveAnimationSpeed;
}

Lesson 3: Event-Driven Architecture

Components communicate through events, not direct references:

public static event Action<Move> OnMoveMade;
public static event Action<PieceColor> OnCheckmate;
public static event Action OnStalemate;

What's Next for ChessHalla

Future features planned:

  1. AI opponent using minimax with alpha-beta pruning
  2. Online multiplayer with Unity Netcode
  3. Move history and game replay
  4. Different themes and board styles
  5. Tutorial mode for beginners

Key Takeaways

  1. Start simple — Get basic piece movement working before special rules
  2. Test thoroughly — Chess has edge cases everywhere
  3. Refactor early — The first implementation is never the best
  4. Unity conventions — Follow Unity's patterns for maintainability

Repository: github.com/Airyshtoteles/ChessHalla

Built with Unity and C# — 100% game development learning project

2026 — Airysh