Mobile Unit Movement in OpenRA - guidebee/OpenRA GitHub Wiki

Mobile Unit Movement in OpenRA

This document explains how different unit types (ground, naval, and air) move within the game world and utilize the 3D coordinate system in OpenRA.

Coordinate Systems in OpenRA

OpenRA uses several coordinate systems to represent positions in the game world:

1. World Position (WPos)

WPos is the most fundamental 3D coordinate system, representing positions in the game world with:

  • X and Y define the horizontal position
  • Z defines the vertical position (height above terrain)
public readonly struct WPos
{
    public readonly int X, Y, Z;
    // ...
}

2. Cell Position (CPos)

CPos represents discrete grid cells in the map:

  • X and Y are the grid coordinates
  • Layer represents different movement layers (0 for ground, others for tunnels, etc.)
public readonly struct CPos
{
    public readonly int X, Y;
    public readonly byte Layer;
    // ...
}

3. Map Position (MPos) and Projected Position (PPos)

These are intermediate coordinate systems used for map representation and projections. They help handle terrain height and isometric perspectives.

Locomotor System

The Locomotor system is central to unit movement in OpenRA. It handles:

  1. Determining terrain passability
  2. Managing movement speeds on different terrain types
  3. Handling collisions and obstacles
  4. Supporting different movement layers (ground, bridges, tunnels, etc.)

Mobile Unit Types and Movement

Ground Units

Ground units use the Mobile trait with a specific Locomotor to move across the terrain.

public class Mobile : PausableConditionalTrait<MobileInfo>, IIssueOrder, IResolveOrder, /* ... */
{
    // ...
}

Key characteristics:

  1. Terrain Interaction: Ground units move along the terrain surface, affected by slopes and terrain types.

  2. Z-Coordinate Handling: The Z coordinate is automatically calculated based on the terrain height.

    public void SetPosition(Actor self, CPos cell, SubCell subCell = SubCell.Any)
    {
        // ...
        var position = cell.Layer == 0 ? self.World.Map.CenterOfCell(cell) :
            self.World.GetCustomMovementLayers()[cell.Layer].CenterOfCell(cell);
        position += self.World.Map.Grid.OffsetOfSubCell(subCell);
        position -= new WVec(0, 0, self.World.Map.DistanceAboveTerrain(position).Length);
        // ...
    }
  3. Movement Types: Ground units have different movement types (tracked, wheeled, etc.) that affect their speed on various terrains.

  4. Custom Layers: Ground units can also move in special layers like tunnels and bridges using CustomMovementLayerType:

    public static class CustomMovementLayerType
    {
        public const byte Tunnel = 1;
        public const byte Subterranean = 2;
        public const byte Jumpjet = 3;
        public const byte ElevatedBridge = 4;
    }

Aircraft and Flying Units

Aircraft use the Aircraft trait which implements specialized movement in 3D space:

public class Aircraft : PausableConditionalTrait<AircraftInfo>, /* ... */
{
    // ...
}

Key characteristics:

  1. Full 3D Movement: Aircraft explicitly manage all three dimensions (X, Y, Z).

  2. Cruise Altitude: Aircraft typically maintain a specific altitude defined by CruiseAltitude:

    public readonly WDist CruiseAltitude = new(1280);
  3. Flight Behaviors:

    • Taking off: Vertical movement to reach cruise altitude
    • Landing: Controlled descent to land on airfields or terrain
    • Cruising: Maintaining altitude while moving horizontally
    • Hovering (for VTOL aircraft): Maintaining position in the air
  4. Aircraft Motion: Aircraft move using specialized flight vectors that consider speed, facing, and altitude:

    public WVec FlyStep(int speed, WAngle facing)
    {
        var dir = new WVec(0, -1024, 0).Rotate(WRot.FromYaw(facing));
        return speed * dir / 1024;
    }
  5. Terrain Interaction: Aircraft calculate their height above terrain using DistanceAboveTerrain:

    public WDist DistanceAboveTerrain(WPos pos)
    {
        // Apply ramp offset
        var cell = CellContaining(pos);
        var offset = pos - CenterOfCell(cell);
        // ...
    }

Movement Activities

Units move by executing various activities that handle movement logic:

  1. Ground Units:

    • Move: Basic movement to a cell
    • MoveWithinRange: Move to within a specified range of a target
    • MoveTo: Move to a specific location
    • LocalMove: Fine-grained movement within a cell
  2. Aircraft:

    • Fly: Basic flight movement
    • Land: Controlled descent to landing sites
    • TakeOff: Vertical ascent from ground
    • FlyFollow: Following a moving target
    • FlyOffMap: Exit the map bounds

3D Coordinate Transforms

When units move, several coordinate transformations take place:

  1. Cell to World Position:

    public WPos CenterOfCell(CPos cell)
    {
        if (Grid.Type == MapGridType.Rectangular)
            return new WPos(1024 * cell.X + 512, 1024 * cell.Y + 512, 0);
    
        // For isometric maps
        var z = Height.TryGetValue(cell, out var height) ?
            724 * height + Grid.Ramps[Ramp[cell]].CenterHeightOffset : 0;
        return new WPos(724 * (cell.X - cell.Y + 1), 724 * (cell.X + cell.Y + 1), z);
    }
  2. World Position to Cell:

    public CPos CellContaining(WPos pos)
    {
        if (Grid.Type == MapGridType.Rectangular)
            return new CPos(pos.X / 1024, pos.Y / 1024);
    
        // For isometric maps
        var u = (pos.Y + pos.X - 724) / 1448;
        var v = (pos.Y - pos.X + (pos.Y > pos.X ? 724 : -724)) / 1448;
        return new CPos(u, v);
    }

Terrain and Elevation

Terrain elevation affects unit movement through:

  1. Ramps: Sloped terrain represented by CellRamp structures:

    public readonly struct CellRamp
    {
        public readonly int CenterHeightOffset;
        public readonly WVec[] Corners;
        public readonly WVec[][] Polygons;
        public readonly WRot Orientation;
        // ...
    }
  2. Height Map: A height value for each cell:

    public CellLayer<byte> Height { get; private set; }
  3. TerrainInfo: Properties defining how units interact with terrain types

Physics and Movement Calculations

Movement calculation includes:

  1. Speed Calculations:

    // For ground units
    public int MovementSpeedForCell(CPos cell)
    {
        var terrainSpeed = Locomotor.MovementSpeedForCell(cell);
        var modifiers = speedModifiers.Value.Append(terrainSpeed);
        return Util.ApplyPercentageModifiers(Info.Speed, modifiers);
    }
    
    // For aircraft
    public int MovementSpeed => !IsTraitDisabled && !IsTraitPaused ?
        Util.ApplyPercentageModifiers(Info.Speed, speedModifiers) : 0;
  2. Direction and Facing: Units maintain facing (direction) during movement:

    public WAngle Facing
    {
        get => orientation.Yaw;
        set => orientation = orientation.WithYaw(value);
    }
  3. Vertical Movement: For aircraft, vertical movement is calculated with:

    public static bool VerticalTakeOffOrLandTick(Actor self, Aircraft aircraft,
        WAngle desiredFacing, WDist desiredAltitude)
    {
        // ...
        var maxDelta = aircraft.Info.AltitudeVelocity.Length;
        var deltaZ = (desiredAltitude.Length - dat.Length).Clamp(-maxDelta, maxDelta);
        aircraft.SetPosition(self, aircraft.CenterPosition + new WVec(0, 0, deltaZ));
        // ...
    }

Pathfinding

Pathfinding uses the coordinate systems to navigate units through the world:

  1. Units calculate paths through cells considering terrain, obstacles, and passability
  2. Aircraft can navigate directly through 3D space, subject to altitude constraints
  3. Each locomotor type has its own set of movement rules for different terrain types

Summary

OpenRA's movement system is a sophisticated framework that:

  1. Handles multiple coordinate systems for different purposes
  2. Supports different unit types with specialized movement behavior
  3. Incorporates terrain elevation and features into movement calculations
  4. Provides realistic 3D movement for aircraft and other flying units
  5. Allows custom movement layers for specialized unit abilities

This system creates a realistic and varied gameplay experience where unit movement feels appropriate to the unit type and the terrain they're traversing.

⚠️ **GitHub.com Fallback** ⚠️