Lost Lily/Grid ToolkitDocs 1.0
Table of Contents

Retained visualization

A board view watches committed board state and tells a renderer which visuals need refreshing. The renderer keeps those objects instead of rebuilding them every frame. This is retained visualization.

Why this model helps

The board remains testable without rendering, and switching between World 2D, World 3D, and uGUI does not move gameplay ownership into scene objects.

View, modules, and renderer

GridBoardView connects four parts: a component that provides board state, a layout, presentation modules, and one renderer.

Modules produce renderer-neutral instructions called GridRenderNode values. The IGridBoardRenderer keeps the concrete visual objects associated with those nodes.

Only the parts marked for refresh are updated. The technical term for that refresh set is invalidation.

After a structure is placed

When a placement commits, GridBoardView receives the event batch and marks the affected structure and cells. Its modules rebuild only those render nodes. GridWorld3DBoardRenderer updates retained GameObjects for the matching visual keys instead of rebuilding the whole board.

Rules that keep rendering separate

  • The board remains usable without any renderer.
  • Render nodes describe presentation; they do not own gameplay state.
  • Committed batches mark the affected cell and structure visuals for refresh after state is consistent.
  • Visual intents can invalidate presentation without advancing board revision.
  • Modules declare capabilities, and setup diagnostics reject unsupported combinations.
  • Hit resolution returns logical GridHit values through the active layout/backend.

From state to retained visuals

flowchart TB
    accTitle: Retained visualization flow
    accDescr: A board view combines state and visual intents, expands invalidation, builds renderer-neutral render nodes, and delegates retained handles and hits to a renderer backend.
    A["State source"] --> B["GridBoardView"]
    C["Visual intents"] --> B
    B --> D["Invalidation expansion"]
    D --> E["Cell / structure / intent modules"]
    E --> F["Renderer-neutral render nodes"]
    F --> G["World 2D, World 3D, uGUI, or custom backend"]
    G --> H["Retained visual objects"]
    H --> I["GridHit"]

Input and backend boundaries

Input ownership remains with the game. The game asks the view to resolve a hit, decides what it means, runs actions, and publishes transient visual intents as needed.

The built-in backends share retained ownership and invalidation, but present and resolve content differently:

  • World 2D and World 3D map nodes to world-space handles and use physics-facing hit paths.
  • uGUI maps nodes below a Canvas and resolves pointer positions through GridUiBoardHitUtility.

Their supported capabilities and content types also differ. Query capabilities and provide a fallback instead of assuming that content supported by one backend works in every backend.