Cell¶
Vanilla game class representing a single voxel cell in the world grid. Used by Room.Grids and the room-neighbor scan.
Fully qualified type: Assets.Scripts.GridSystem.Cell (decompile line 272151). Namespace differs from most game-object types under Assets.Scripts.Objects; mods referencing Cell in a Harmony patch signature must using Assets.Scripts.GridSystem;.
NeighborCells 26-cell and filter to 6¶
Source: F0028.
Cell.NeighborCells returns all 26 surrounding cells (corners and diagonals included). The mod filters to 6 orthogonal neighbors by checking that exactly one axis of the Grid3 difference is nonzero.
6-neighbor filter comment (F0353)¶
Source comment from NetworkPainterPatch.cs:298-303:
Cell.NeighborCells contains all 26 surrounding cells (includeCorners:true in the Cell ctor). We want 6-orthogonal only: exactly one grid axis differs between the two cells.
Cell fields¶
Field cluster on Cell:
public static readonly ConcurrentDictionary<Cell, byte> AllCells = new ConcurrentDictionary<Cell, byte>();
public GridController GridController;
public readonly WorldGrid WorldGrid;
public Vector3 Position;
public Dictionary<Grid3, Structure> Structural = new Dictionary<Grid3, Structure>();
public List<Structure> AllStructures = new List<Structure>();
public List<Cell> NeighborCells = new List<Cell>();
public Stairs Stairs;
public bool HasLight;
Structural is the face-keyed structure map (one Grid3 key per occupied face, up to six faces plus a body per cell). AllStructures is the flat list of everything touching the cell, which the SprayPaintPlus wall and large-structure floods iterate. NeighborCells is the precomputed all-26 neighbor list (see the section above). AllCells is the global set of every cell.
AllStructures and Structural hold large-grid structures. SmallGrid-derived occupants (pipes, cables, chutes, small devices, robotic-arm rails, ladders) register in the parallel 0.5 m small grid, one occupant per typed slot on a SmallCell, not here. See SmallCell.md. This is why the mod floods pipes and cables through their dedicated network objects and reserves the large-cell BFS (AllStructures + NeighborCells) for walls and large structures.
IsBlocked / IsBlockedLight¶
public bool IsBlocked
{
get
{
Structure structural = GetStructural(Position);
...
}
}
public bool IsBlockedLight
{
get
{
Structure structural = GetStructural(Position);
...
}
}
Both resolve the structure at the cell's own Position via GetStructural and test its collision / pass flags.
A structure appears in AllStructures of every cell of its footprint¶
Cell.Add takes the cell-relative position of the occupied slot, so it is called once per cell a structure covers and each of those cells lists it. For CollisionType.BlockCustom, the branch that also fills the dedicated Cell.Stairs slot, the append is unconditional:
public bool Add(Structure structure, Grid3 relativePosition)
{
switch (structure.StructureCollisionType)
{
case CollisionType.BlockCustom:
{
Stairs stairs = structure as Stairs;
if ((bool)stairs)
{
Stairs = stairs;
}
AllStructures.Add(structure);
break;
}
case CollisionType.BlockGrid:
case CollisionType.BlockFace:
if (!AddStructural(structure, relativePosition))
{
return false;
}
break;
default:
AllStructures.Add(structure);
break;
}
return true;
}
AddStructural reaches the same list by the other two routes: it appends when Lookup.IsValid(relativePosition - Grid) is false, and it appends after Lookup.Set when the face slot is free.
Two consequences for a flood that iterates AllStructures. One object can be reported by several cells, so a walk over a cell set has to de-duplicate or accept repeats; and Thing.Cell is only one of those cells, the one the structure registered against, which is not necessarily the one Thing.GridPosition names. Measured 2026-09-23 on four Stairs-class stairwell pieces: GridPosition put all four in one cell column while Thing.Cell reported alternating landing cells two apart, and a cell flood keyed on GridPosition reached all four. See Stairs.md, "GridPosition is the bounds centre".
NeighborCells is built once in the constructor and is the full 26-cell set, never wider:
Span<Grid3> span = stackalloc Grid3[32];
int count = 0;
GridController.GetNeighborCells(Grid, span, ref count, includeCorners: true);
Verification history¶
- 2026-04-20: page created from the Research migration; verbatim content lifted from F0028, F0353. No conflicts.
- 2026-05-15: verified namespace
Assets.Scripts.GridSystem.Cell(decompile line 272151); added pre-page note for mod authors patching method signatures that takeCell. - 2026-05-22: added "Cell fields" section (with "IsBlocked / IsBlockedLight" subsection) from a room/grid/atmospherics decompile pass. Additive; existing sections unchanged. Source:
Assets.Scripts.GridSystem.CellinAssembly-CSharp, game version 0.2.6228.27061. Added related links to GridController, Structure. - 2026-06-19: noted in "Cell fields" that
SmallGridoccupants (pipes, cables, ladders, etc.) register in the parallelSmallCellsmall grid, notAllStructures; added related link to the newSmallCell.md. Game version 0.2.6228.27061. - 2026-09-23: added "A structure appears in AllStructures of every cell of its footprint" from
Cell.Add,AddStructuraland theCellconstructor, with a live measurement of four stairwells whoseThing.CellandGridPositiondisagree. Additive; nothing on the page is contradicted, and it extends rather than replaces the existing "Cell fields" description ofAllStructures. Game version 0.2.6428.27798.
Open questions¶
None at creation.