1 Grid-System
John McCardle edited this page 2025-10-25 20:57:05 +00:00

Grid System

The Grid System is McRogueFace's core spatial container for roguelike game maps. It provides tilemap rendering, entity management, FOV (field of view), and pathfinding integration with libtcod.

Quick Reference

Related Issues:

  • #124 - Grid Point Animation (Tier 1 - Active)
  • #123 - Grid Subgrid System (Tier 1 - Active)
  • #114 - CellView API (Tier 1 - Active)
  • #113 - Batch Operations for Grid (Tier 1 - Active)
  • #64 - Grid-Entity-GridPointState TCOD Updates
  • #50 - Grid Background Color (Closed - Implemented)

Key Files:

  • src/UIGrid.h / src/UIGrid.cpp - Main grid implementation
  • src/UIGridPoint.h - Individual grid cell (visual layer)
  • src/UIGridPointState.h - Per-entity perspective/knowledge
  • src/UIEntity.h / src/UIEntity.cpp - Entity system (lives on grid)

API Reference:

Architecture Overview

Three-Layer Design

The Grid System uses a three-layer architecture for sophisticated roguelike features:

  1. Visual Layer (UIGridPoint)

    • What's displayed: tile sprite, colors, animations
    • Shared by all viewers
    • File: src/UIGridPoint.h
  2. World State Layer (TCODMap)

    • Physical properties: walkable, transparent, cost
    • Used for pathfinding and FOV calculations
    • Integration: libtcod via src/UIGrid.cpp
  3. Perspective Layer (UIGridPointState)

    • Per-entity knowledge: what each entity has seen/explored
    • Enables fog of war, asymmetric information
    • File: src/UIGridPointState.h

This architecture follows proven patterns from Caves of Qud, Cogmind, and DCSS.

Grid → Entity Relationship

Entity Lifecycle:

  • Entities live on exactly 0 or 1 grids
  • grid.entities.append(entity) sets entity.grid = grid
  • grid.entities.remove(entity) sets entity.grid = None
  • Entity removal handled automatically on grid destruction

Spatial Queries:

  • Currently: Linear iteration through entity list
  • Planned: SpatialHash for O(1) lookups (see #115)

Sub-Pages

Common Tasks

Creating a Grid

import mcrfpy

# Create 50x50 grid with 16x16 tile size
grid = mcrfpy.Grid(50, 50, 16, 16)
grid.texture = mcrfpy.createTexture("tileset.png")
grid.pos = (100, 100)  # Screen position

# Add to scene
mcrfpy.sceneUI("game").append(grid)

Details: See src/UIGrid.cpp::PyInit() for constructor implementation

Setting Tile Properties

# Access individual cell
cell = grid.at((x, y))

# Visual properties
cell.tilesprite = 42  # Sprite index in texture
cell.color = mcrfpy.Color(255, 255, 255)

# World properties (TCOD integration)
grid.walkable((x, y), True)   # Can entities walk here?
grid.transparent((x, y), True)  # Can see through?

Implementation: src/UIGrid.cpp::walkable(), src/UIGrid.cpp::transparent()

FOV and Pathfinding

# Compute field of view from entity position
grid.compute_fov(entity.x, entity.y, radius=10)

# A* pathfinding
path = entity.path_to(target_x, target_y)

Implementation:

  • FOV: src/UIGrid.cpp::compute_fov() (TCOD integration)
  • Pathfinding: src/UIEntity.cpp::path_to() (uses TCOD A*)

Performance Characteristics

Current:

  • Grid rendering: O(visible_cells) - renders only viewport
  • Entity rendering: O(entities) - culls out-of-bounds (see src/UIGrid.cpp::render())
  • Static grids: Inefficient - redraws unchanged cells every frame

Optimizations In Progress:

  • #116: Dirty flag system - only redraw on changes
  • #113: Batch operations - reduce Python/C++ boundary crossings
  • #115: SpatialHash - O(1) entity spatial queries
  • #123: Subgrid system - divide large grids into chunks

Profiling: Press F3 in-game to see grid render metrics (see Performance-and-Profiling)

Design Proposals

Active architectural evolution:

Known Issues & Limitations

Current Limitations:

  • No tile-level animation (planned: #124)
  • Large grids (>200x200) can have rendering overhead
  • Entity iteration is O(n) for spatial queries

Workarounds:

  • Keep grids reasonably sized (< 100x100 for best performance)
  • Use entity culling (automatically enabled in UIGrid::render())
  • Profile with F3 overlay to identify bottlenecks

See Also: