Skip to content

Core.GridSystem.SingleEntityGrid

Dennis Steffen edited this page Jan 4, 2026 · 1 revision

SingleEntityGrid

The class is a generic utility designed to manage objects (entities) on a 2D coordinate system. It uses a dictionary to map integer coordinates () to specific instances of type . SingleEntityGrid<T>``PointInt``T

Key Features and Behavior

  1. Coordinate-Based Storage: It doesn't use a fixed-size 2D array. Instead, it uses a , meaning it only consumes memory for the cells that actually contain an entity. Dictionary
  2. Single Entity per Cell: As the name suggests, each key can only point to one entity. If you a new entity on an occupied cell, it overwrites the previous one. PointInt``Register
  3. Area Support: It allows you to register or remove an entity over a range of cells using a (rectangle). This is useful for large objects that occupy multiple tiles. Rect
  4. Grid Wrapping ()stayInGrid: The method has a unique feature where if is true, it performs a modulo operation (% 100). This suggests the grid is intended to "wrap around" within a 100x100 area. Get``stayInGrid

Method Breakdown

  • Register(PointInt cell, T entity): Places an entity at a specific X, Y coordinate.
  • Register(Rect cells, T entity): Fills all coordinates within the rectangle's bounds with the same entity reference.
  • IsOccupied(PointInt cell): A quick way to check if a tile is "blocked" or has something in it.
  • Get(PointInt cell, bool stayInGrid = false): Retrieves the entity. If the grid wraps, it ensures the coordinate stays within the 0-99 range.

Usage Examples

Here are a few ways you might use this class in a game context:

1. Basic Setup and Placement

If you are building a tile-based game, you might use this to track buildings or walls.

// Define a grid for Buildings
var buildingGrid = new SingleEntityGrid<Building>();

// Place a small 1x1 building (like a Lamp)
PointInt lampPos = new PointInt(10, 5);
buildingGrid.Register(lampPos, new Building("Street Lamp"));

// Check if a spot is free before building
PointInt targetPos = new PointInt(10, 5);
if (!buildingGrid.IsOccupied(targetPos))
{
    buildingGrid.Register(targetPos, new Building("House"));
}
else
{
    Console.WriteLine("Cannot build here: Spot occupied!");
}

2. Handling Large Objects (Multi-tile)

If you have a large structure, like a 3x3 "Command Center", you can register it across all the tiles it covers.

var commandCenter = new Building("Command Center");
// Define a rectangle: Left=5, Top=5, Width=3, Height=3
Rect area = new Rect(5, 5, 3, 3); 

// This marks all 9 tiles as occupied by this one building
buildingGrid.Register(area, commandCenter);

// Later, if we check any tile within that 3x3 area, we get the same building
if (buildingGrid.TryGet(new PointInt(6, 6), out var entity))
{
    Console.WriteLine($"Found: {entity.Name}"); // Output: Found: Command Center
}

3. Using the Indexer and Wrapping

The indexer allows you to treat the grid like a simple 2D array, and you can use the logic for "infinite" or looping worlds. stayInGrid

// Accessing via Indexer (standard access)
var entityAtOrigin = buildingGrid[new PointInt(0, 0)];

// Accessing with wrapping logic (e.g., checking position 105, which wraps to 5)
PointInt farPos = new PointInt(105, 5);
var wrappedEntity = buildingGrid.Get(farPos, stayInGrid: true); 

// Removing an entity
buildingGrid.Remove(new PointInt(10, 5));

Important Note

The method contains a hardcoded value: . This implies that this specific implementation is tailored for a world size of 100x100. If your game world is larger or smaller, you would need to modify that specific line or make the grid size a variable. Get``cell = new PointInt(cell.X % 100, cell.Y % 100);

Clone this wiki locally