Grid3¶
Vanilla game type representing the scaled integer-grid coordinate system used for structure placement and room math. World coordinates are scaled by 10 (Grid3.one): a Grid3 stores integer DECIMETERS (tenths of a meter). Grid-aligned structures snap to a cell spacing derived from their GridSize.
Scale and cell math¶
Source: F0016.
World coordinates scaled by Grid3.one (10 units per world unit). Structures snap to a grid defined by their GridSize (2 world units for walls and large structures by default). One cell spans GridSize * Grid3.one.x Grid3 units (20 by default). Every grid-aligned structure's GridPosition is a multiple of this cell size plus a fixed offset.
Parity trap for checkered painting¶
Source: F0021.
Grid3 scales world coordinates by 10. Walls and large structures snap to a 2-world-unit cell grid, so every grid-aligned structure's GridPosition is a multiple of 20 Grid3 units. Naive (x+y+z) % 2 parity is the same for every structure. The checkered check works on the delta between two positions divided by cell size, which gives the cell-index distance. Parity of that distance is the checker answer.
3D checkerboard comment (F0321)¶
Source comment from NetworkPainterPatch.cs:357-371:
/// <summary>
/// 3D checkerboard parity for grid-aligned structures. Two traps make
/// the naive `(x+y+z) & 1` on GridPosition useless here:
/// 1. Grid3 scales world coords x Grid3.one (10), so one world unit
/// is ten Grid3 units.
/// 2. Walls and large structures snap to a GridSize-wide cell grid
/// (default 2 world units). One cell therefore spans
/// GridSize * Grid3.one Grid3 units (20 by default), and every
/// structure's GridPosition is a multiple of 20 (+ a fixed
/// offset). Parity on raw coords is always the same value.
/// Working from the delta between the two positions sidesteps both
/// the scale and the grid offset: the delta is always an exact
/// multiple of cellSize, so integer division yields the cell-index
/// distance and its parity is the checker answer.
/// </summary>
Integer decimeters: constructors, converters, snapping¶
Grid3 stores integer DECIMETERS (tenths of a meter). Constructors and converters, verbatim at 0.2.6403.27689:
public Grid3(Vector3 worldPosition) // line 291547
{
x = Round(worldPosition.x * 10f);
y = Round(worldPosition.y * 10f);
z = Round(worldPosition.z * 10f);
}
public Grid3(Vector3 worldPosition, float gridBy, float gridOffset) // line 291590
{
worldPosition = worldPosition.GridCenter(gridBy, gridOffset);
x = Round(worldPosition.x * 10f);
y = Round(worldPosition.y * 10f);
z = Round(worldPosition.z * 10f);
}
public readonly Vector3 ToVector3() // line 291736
{
return new Vector3((float)x * 0.1f, (float)y * 0.1f, (float)z * 0.1f);
}
public override string ToString() // line 291731
{
return $"Grid3({x}, {y}, {z})";
}
Grid snapping, GridCenter extension (230451-230459):
public static Vector3 GridCenter(this Vector3 worldPosition, float gridSquareSize = 2f, float offset = 0f)
{
float num = gridSquareSize * 0.5f;
float num2 = offset + num;
worldPosition.x = Mathf.Round((worldPosition.x - num2) / gridSquareSize) * gridSquareSize + num2;
worldPosition.y = Mathf.Round((worldPosition.y - num2) / gridSquareSize) * gridSquareSize + num2;
worldPosition.z = Mathf.Round((worldPosition.z - num2) / gridSquareSize) * gridSquareSize + num2;
return worldPosition;
}
GridController.WorldToLocalGrid (206416-206419) and LocalToWorld (206421-206424):
public Grid3 WorldToLocalGrid(Vector3 worldPosition, float gridSize = 2f, float gridOffset = 0f)
{
return worldPosition.ToGrid(gridSize, gridOffset);
}
public Vector3 LocalToWorld(Grid3 localGrid)
{
return localGrid.ToVector3();
}
(ToGrid at 230409-230412 forwards to the (Vector3, float, float) Grid3 constructor; ToGridPosition at 230414-230417 is the unsnapped decimeter conversion.)
Small-grid cell math: pitch 0.5 m with 0.25 m offset¶
Small-grid constants: SmallGrid.SmallGridSize = 0.5f, SmallGrid.SmallGridOffset = 0.25f (statics at 312036-312038; parallel consts at 292041-292043). The default (large) grid is 2 m with 0 offset.
- At registration,
GridController.Registersnaps:structure.ThingTransformPosition = LocalToWorld(structure.RegisteredLocalGrid)(206471), whereRegisteredLocalGrid = new Grid3(ThingTransformPosition)was computed inStructure.OnAssignedReference(314186). So a placed cable'sThingTransformPositionsits exactly on the 0.1 m Grid3 lattice, and for a snapped placement it IS the small-cell center. See StructureRegistration. - The cable's occupied cell key(s):
GridBounds.GetLocalSmallGrid(RegisteredPosition, RegisteredRotation)->Grid3[](one entry for the 1-cell piece; ⅗/10 for the long pieces). Equivalently for a point query:WorldToLocalGrid(worldPos, 0.5f, 0.25f)= snap to the 0.5 m cell center (centers lie on multiples of 0.5 m because offset 0.25 + half-size 0.25 = 0.5), then store as decimeter ints, so cell-key Grid3 components are multiples of 5. - Round trip for a player-facing message:
cable.ThingTransformPosition(world meters) is the number to show;cable.RegisteredLocalGrid.ToVector3()gives the same value.SmallCell.SmallGrid(the cell's ownGrid3key; see SmallCell).ToVector3()gives the cell center in meters.
Player-facing coordinate convention: world meters¶
- The logic system exposes raw world meters: a device answering
LogicType.PositionX/Y/Zreturnsbase.Position.x/.y/.z(verbatimcase LogicType.PositionX: return base.Position.x;at 308886-308891). IC10 players, autopilot scripts, and community tooling therefore treat "coordinates" as world meters.Thing.Positionis the registeredThingTransformPosition(319761). - There is no textual coordinate HUD for players in vanilla: F3 toggles the console (
KeyMap.ToggleConsole = KeyCode.F3, 43997/44065), F4 toggles the game-info panel (KeyMap.ToggleInfo = KeyCode.F4, 44066; consumer at 287004-287007SetGameInfoState, the tab menu, no coordinates). Beacons and trackers register withWaypointManagerand draw HUD markers with distance, not coordinate text. - The authoring tool shows "Reference ID: " in an
AttackWithtooltip (315158); that is the only vanilla surface printing aReferenceIdfor a placed cable, and it prints no coordinates. - No player-facing world-position-to-text formatter exists in the decompile;
Grid3.ToString()("Grid3(x, y, z)", decimeters) andPrintDebugInfoare developer-facing. A mod should format world meters itself, e.g.$"({pos.x:F1}, {pos.y:F1}, {pos.z:F1})", matching theLogicType.Positionconvention (and matching how this repo already reports positions, e.g. the CableNetwork open question quotes "world position (-1292.0, 206.0, -780.0)"). - Recommendation for a console message: world meters of the subject's
ThingTransformPositionwith one decimal, optionally plus the display name and tier names. Do not printGrid3raw integers (players cannot map decimeters to anything in-game).
Verification history¶
- 2026-04-20: page created from the Research migration; verbatim content lifted from F0016, F0021, F0321. No conflicts.
- 2026-07-14: extended with three sections from the mixed-tier cable network guard research pass against the 0.2.6403.27689 decompile: "Integer decimeters" (constructors 291547 / 291590,
ToVector3291736,ToString291731,GridCenter230451-230459,WorldToLocalGrid/LocalToWorld206416-206424,ToGrid/ToGridPosition230409-230417), "Small-grid cell math" (SmallGridSize0.5 /SmallGridOffset0.25 at 312036-312038 and 292041-292043; cell centers on 0.5 m multiples so cell-key components are multiples of 5; a placed cable'sThingTransformPositionIS its grid-snapped world position perRegister206471 +OnAssignedReference314186), and "Player-facing coordinate convention" (LogicType.PositionX/Y/Zreturnsbase.Positioncomponents in world meters, 308886-308891; F3 = console, F4 = info panel without coordinates, beacons draw distance only; the authoring-tool tooltip's "Reference ID: " at 315158 is the only vanillaReferenceIdsurface for a placed cable; no vanilla position-to-text formatter exists). The new decimeter semantics confirm and sharpen the existing "scaled by 10" sections; no prior claim contradicted. The pre-existing sections keep their 0.2.6228.27061 stamps (not re-read this pass).
Open questions¶
None at creation.