Skip to content

Game.Pathfind.PathNode

Assembly: Assembly-CSharp
Namespace: Game.Pathfind

Type: struct

Base: System.ValueType
Implements: IEquatable, IStrideSerializable, ISerializable

Summary:
PathNode is a compact, value-type representation of a pathfinding node used by the game's pathfinding system. It packs an owner Entity index, lane/segment indices, an optional curve position (quantized), and a "secondary" flag into a single 64-bit field (m_SearchKey). The struct provides convenience constructors, bit-manipulation helpers, comparisons that can ignore curve position, and serialization support.


Fields

  • private const float FLOAT_TO_INT = 32767f
    Used to quantize a floating-point curve position into a 15-bit integer range (0..32767).

  • private const float INT_TO_FLOAT = 3.051851E-05f
    Reciprocal of FLOAT_TO_INT (≈ 1 / 32767). Used to convert the stored integer back to a float curve position.

  • private const ulong CURVEPOS_INCLUDE = 2147418112uL
    (0x7FFF0000) Mask corresponding to the curve-position bits. Useful when extracting or comparing the stored curve position.

  • private const ulong CURVEPOS_EXCLUDE = 18446744071562133503uL
    (0xFFFFFFFF8000FFFF) Mask used to clear the curve-position bits while preserving other parts of the key.

  • private const ulong SECONDARY_NODE = 2147483648uL
    (0x80000000) Bit mask for the secondary-node flag (stored in the low 32 bits, bit 31).

  • private ulong m_SearchKey
    The packed 64-bit storage. Layout (low-to-high within low 32 bits):

  • bits 0..15: lane index (ushort)
  • bits 8..15: segment index (byte) (note: overlaps within low 16 bits with lane index's high byte)
  • bits 16..30: quantized curve-position (15 bits)
  • bit 31: secondary flag
  • high 32 bits: owner Entity.Index (int) The constructors and accessors read/write fields by shifting & masking this value.

Properties

  • None (no public C# properties defined). The struct exposes getters and mutators via methods.

Constructors

  • public PathNode(Entity owner, byte laneIndex, byte segmentIndex)
    Creates a node with given owner, laneIndex (stored in low byte), segmentIndex (stored at <<8). Curve position and secondary flag are unset.

  • public PathNode(Entity owner, byte laneIndex, byte segmentIndex, float curvePosition)
    Stores owner, laneIndex, segmentIndex and quantizes curvePosition into the 15-bit field (curvePosition * 32767f, truncated) stored at bits <<16.

  • public PathNode(Entity owner, ushort laneIndex, float curvePosition)
    Stores owner and a full 16-bit laneIndex, plus the quantized curve position.

  • public PathNode(Entity owner, ushort laneIndex)
    Stores owner and full 16-bit laneIndex; no curve position.

  • public PathNode(PathTarget pathTarget)
    Constructs from a PathTarget (uses pathTarget.m_Entity.Index as owner and pathTarget.m_Delta as curve position, quantized).

  • public PathNode(PathNode pathNode, float curvePosition)
    Copies an existing PathNode but replaces the curve-position with the provided float (quantized). Preserves the secondary flag and other fields.

  • public PathNode(PathNode pathNode, bool secondaryNode)
    Copies an existing PathNode but sets or clears the secondary flag according to secondaryNode.

Notes: - Quantized curve positions expect values in the range that maps correctly into 0..32767. Values outside this range may be truncated or clipped by the cast to integer.


Methods

  • public bool IsSecondary()
    Returns true if the secondary flag (0x80000000 in the low 32 bits) is set.

  • public bool Equals(PathNode other)
    IEquatable implementation: returns true when the entire packed key (m_SearchKey) matches exactly.

  • public bool EqualsIgnoreCurvePos(PathNode other)
    Compares two nodes ignoring the quantized curve-position bits. The comparison preserves the secondary flag and other fields; only curve-position bits are masked out.

  • public bool OwnerEquals(PathNode other)
    Returns true if both nodes have the same owner Entity.Index (compares the high 32 bits).

  • public override int GetHashCode()
    Returns the hash code of the packed m_SearchKey.

  • public PathNode StripCurvePos()
    Returns a copy of this PathNode with the curve-position bits cleared (curve pos removed), preserving other fields.

  • public void ReplaceOwner(Entity oldOwner, Entity newOwner)
    If this node's owner equals oldOwner.Index, replaces it with newOwner.Index while preserving the lower 32 bits.

  • public void SetOwner(Entity newOwner)
    Unconditionally replaces the owner part of the packed key with newOwner.Index.

  • public void SetSegmentIndex(byte segmentIndex)
    Sets the segment index (stored at bits <<8) while preserving other low-32-bit data.

  • public float GetCurvePos()
    Extracts the quantized curve position (bits 16..30), converts to float by multiplying by INT_TO_FLOAT (≈ 1/32767f) and returns it.

  • public int GetOwnerIndex()
    Returns the integer owner index (high 32 bits).

  • public ushort GetLaneIndex()
    Returns the stored lane index (low 16 bits returned as ushort).

  • public bool GetOrder(PathNode other)
    Returns true if this node should be ordered after the given other node when ordering by the packed key (i.e., compares m_SearchKey values).

  • public int GetCurvePosOrder(PathNode other)
    Returns the signed difference between this node's raw curve-position integer bits and the other's. Useful for ordering by curve position only.

  • public void Serialize<TWriter>(TWriter writer) where TWriter : IWriter
    Writes the owner Entity (as an Entity struct with Index set) and the lower 32 bits (uint) to the writer. Uses writer.Write(value, ignoreVersion: true) for the Entity and then writer.Write((uint)value2).

  • public void Deserialize<TReader>(TReader reader) where TReader : IReader
    Reads an Entity and a uint from reader and reconstructs m_SearchKey = ((long)value.Index << 32) | value2.

  • public int GetStride(Context context)
    Implements IStrideSerializable: returns 8 (bytes) as the stride/size used for serialization of the packed node.

Notes: - Serialization stores the owner index and the low 32-bit word (lane/segment/curvepos/secondary) so the full packed state can be reconstructed. - The struct relies on bit masks and shifts; modifying the bit layout would require updates to all related masks and methods.


Usage Example

// Example usages of PathNode
Entity entity = new Entity { Index = 12345 };

// Create a node with owner, lane (byte), segment (byte) and curve position (0..1 range)
PathNode node = new PathNode(entity, laneIndex: 3, segmentIndex: 1, curvePosition: 0.5f);

// Check curve position and secondary flag
float curve = node.GetCurvePos();
bool secondary = node.IsSecondary();

// Create a copy with a new curve position
PathNode nodeWithNewCurve = new PathNode(node, curvePosition: 0.75f);

// Strip curve position
PathNode stripped = node.StripCurvePos();

// Replace owner if matches
Entity newOwner = new Entity { Index = 54321 };
node.ReplaceOwner(entity, newOwner);

// Serialize / Deserialize (pseudo-code, depends on available IWriter/IReader)
using (var writer = /* obtain writer */)
{
    node.Serialize(writer);
}
using (var reader = /* obtain reader */)
{
    PathNode readNode = default;
    readNode.Deserialize(reader);
}

If you need, I can also provide a visual diagram of the m_SearchKey bit layout, or generate helper extension methods (e.g., safe curve-position clamping) for your mod code.