Skip to content

Game.ValidationHelpers

Assembly: Game
Namespace: Game.Objects

Type: static class

Base:

Summary:
ValidationHelpers is a utility class used by the game's placement/validation pipeline to detect placement errors for objects, networks and areas (overlaps, water/ground constraints, city/lot bounds, required road/port access, etc.). It contains the main validation entry points used by the ValidationSystem (ValidateObject, ValidateNetObject, ValidateOutsideConnection, ValidateWaterSource) and several helpers (ValidateWorldBounds, ValidateSubPlacement, CheckSurface, GetOwner, ExceedRange, Intersect). The class also defines several internal iterator structs (ObjectIterator, NetIterator, AreaIterator) used to iterate native quadtrees and perform detailed 3D/2D collision checks against existing entities and areas. ValidationHelpers uses various Game.* utilities (ObjectUtils, MathUtils, NetUtils, AreaUtils, WaterUtils, TerrainUtils) and enqueues results as ErrorData into a NativeQueue for further processing by validation/placement UI or systems.


Fields

  • public const float COLLISION_TOLERANCE = 0.01f
    This constant is used as a small epsilon/tolerance for collision checking to avoid false positives due to floating point precision when intersecting bounds, boxes, circles and cylinders.

Properties

  • None.

Constructors

  • None (static utility class).

Methods

  • public static void ValidateObject(Entity entity, Temp temp, Owner owner, Transform transform, PrefabRef prefabRef, Attached attached, bool isOutsideConnection, bool editorMode, ValidationSystem.EntityData data, NativeList<ValidationSystem.BoundsData> edgeList, NativeList<ValidationSystem.BoundsData> objectList, NativeQuadTree<Entity, QuadTreeBoundsXZ> objectSearchTree, NativeQuadTree<Entity, QuadTreeBoundsXZ> netSearchTree, NativeQuadTree<AreaSearchItem, QuadTreeBoundsXZ> areaSearchTree, NativeParallelHashMap<Entity, int> instanceCounts, WaterSurfaceData waterSurfaceData, TerrainHeightData terrainHeightData, NativeQueue<ErrorData>.ParallelWriter errorQueue)
    Performs the full validation of a placeable object instance. This is the main method used to check object collisions against:
  • other placeable objects (via objectSearchTree and objectList),
  • net edges and nodes (via netSearchTree and edgeList),
  • areas (via areaSearchTree),
  • water/terrain surface constraints (CheckSurface),
  • item/world bounds (ValidateWorldBounds),
  • sub-placement constraints relative to a building owner (ValidateSubPlacement). The method computes object bounds, resolves owner/top-level entity and attachment context, determines the object's CollisionMask, and uses nested iterators (ObjectIterator, NetIterator, AreaIterator) to detect overlapping geometry. Errors are enqueued into errorQueue as ErrorData entries. This method is heavy and designed to run inside the ValidationSystem and can use burst/native containers.

  • public static void ValidateWorldBounds(Entity entity, Owner owner, Bounds3 bounds, ValidationSystem.EntityData data, TerrainHeightData terrainHeightData, NativeQueue<ErrorData>.ParallelWriter errorQueue)
    Checks whether the object's bounds extend outside the playable city bounds (terrain bounds). If the placement is outside city limits (and not allowed by owner chain such as nodes/edges), enqueues an ExceedsCityLimits ErrorData positioned at the violating bounds' center. Respects owner chain to allow e.g. nodes/edges to avoid reporting.

  • public static void ValidateSubPlacement(Entity entity, Owner owner, Transform transform, PrefabRef prefabRef, ObjectGeometryData prefabObjectGeometryData, ValidationSystem.EntityData data, NativeQueue<ErrorData>.ParallelWriter errorQueue)
    Validates placement relative to an owning building when the object is marked essential and belongs to a building. For upgrades it enforces the upgrade maximum placement distance and enqueues LongDistance errors; for regular building sub-placement it validates lot boundaries and can enqueue ExceedsLotLimits warnings.

  • private static bool ExceedRange(float3 position, float3 forward, float width, float length, float roundness, bool circular, float2 checkPosition)
    Helper used by ValidateSubPlacement to determine if a corner/check point lies outside a building's allowed upgrade range. Returns true when the checkPosition is outside the allowed rounded rectangle or circle, depending on the composition parameters.

  • public static void ValidateNetObject(Entity entity, NetObject netObject, Transform transform, PrefabRef prefabRef, Attached attached, ValidationSystem.EntityData data, NativeQueue<ErrorData>.ParallelWriter errorQueue)
    Validates a net object (sub-object on an edge) specifically for required road/port access and clears/tracking flags. If the net object requires specific road types and those are not available on the connected sub-lanes, enqueues NoRoadAccess or NoPortAccess. If the net object is not flagged as pass-through or clear, enqueues OverlapExisting.

  • public static void ValidateOutsideConnection(Entity entity, Transform transform, TerrainHeightData terrainHeightData, NativeQueue<ErrorData>.ParallelWriter errorQueue)
    Validates placement of an outside connection (connection at map border). If the transform position is not on the terrain border as required, enqueues NotOnBorder.

  • public static void ValidateWaterSource(Entity entity, Transform transform, Game.Simulation.WaterSourceData waterSourceData, TerrainHeightData terrainHeightData, NativeQueue<ErrorData>.ParallelWriter errorQueue)
    Validates water source placement with respect to city bounds and water-source radius. Depending on waterSourceData.m_ConstantDepth it enqueues ExceedsCityLimits or NotOnBorder errors when the source lies outside allowed ranges.

  • private static Entity GetOwner(Entity entity, Temp temp, ValidationSystem.EntityData data, out Edge tempNodes, out Edge ownerNodes, out Entity attachedParent, out Entity assetStamp, out Entity edgeOwner, out Entity nodeOwner)
    Resolves and returns the top-level owner entity for a given entity (walking the Owner chain), while extracting contextual information used by iterators: tempNodes/ownerNodes (edge node remapping), attachedParent, assetStamp, edgeOwner and nodeOwner. Used internally by ValidateObject to determine the top-level parent and owner context for collision checks.

  • private static void CheckSurface(Entity entity, Transform transform, CollisionMask collisionMask, ObjectGeometryData prefabObjectGeometryData, PlaceableObjectData placeableObjectData, ValidationSystem.EntityData data, WaterSurfaceData waterSurfaceData, TerrainHeightData terrainHeightData, NativeQueue<ErrorData>.ParallelWriter errorQueue)
    Samples water/terrain over the object footprint using WaterUtils / TerrainUtils to determine:

  • whether object intersects water (InWater error),
  • missing water for shoreline/floating/underwater rules (NoWater or NotOnShoreline),
  • uses object placement flags (Floating, OnGround, Shoreline) plus CollisionMask to classify errors and severity. Enqueues InWater/NoWater/NotOnShoreline errors as appropriate.

  • public static bool Intersect(Cylinder3 cylinder1, Cylinder3 cylinder2, ref float3 pos)
    Utility that tests intersection between two cylinders (3D) with rotations and heights. If cylinders intersect, computes an approximate contact position and writes it to pos (local space of cylinder1 rotation) and returns true; otherwise returns false. Used by 3D collision checks when objects use circular geometry.


Usage Example

// Example (conceptual) showing how a mod or system could call ValidateObject.
// In practice the ValidationSystem calls this as part of placement; constructing
// all required native containers is non-trivial — shown here with placeholders.

ValidationSystem.EntityData data = /* get validation entity data */;
NativeList<ValidationSystem.BoundsData> edgeList = /* prepared edge bounds list */;
NativeList<ValidationSystem.BoundsData> objectList = /* prepared object bounds list */;
NativeQuadTree<Entity, QuadTreeBoundsXZ> objectTree = /* existing object quad tree */;
NativeQuadTree<Entity, QuadTreeBoundsXZ> netTree = /* existing net quad tree */;
NativeQuadTree<AreaSearchItem, QuadTreeBoundsXZ> areaTree = /* area quad tree */;
NativeParallelHashMap<Entity,int> instanceCounts = /* map of prefab instances */;
WaterSurfaceData water = /* water data */;
TerrainHeightData terrain = /* terrain data */;
NativeQueue<ErrorData>.ParallelWriter errorQueue = /* queue to collect errors */;

Entity tempEntity = /* temp entity for placement */;
Temp temp = /* temp component */;
Owner owner = /* owner component */;
Transform transform = /* desired transform */;
PrefabRef prefabRef = /* prefab reference */;
Attached attached = /* attached component if any */;

ValidationHelpers.ValidateObject(tempEntity, temp, owner, transform, prefabRef, attached,
    isOutsideConnection: false, editorMode: false, data,
    edgeList, objectList, objectTree, netTree, areaTree,
    instanceCounts, water, terrain, errorQueue);

Notes: - Most calls to these APIs are performed by the game's ValidationSystem; when modding you typically interact with ValidationHelpers indirectly or call specific helpers (e.g., ValidateNetObject, ValidateWorldBounds) if implementing custom placement/validation logic. - The helper methods use Unity.Collections and low-level native structures and are intended for use on validation threads — be careful to respect memory/thread-safety (Native containers, ParallelWriter) when interfacing from custom code.