Urban Vitality P8 | UE5 Vehicle Scheduling: Garage Dispatch, Policy Arbitration, and Route Continuity

Urban Vitality series · P8 · UE5 Logic Demo

P3 examined vehicle identity, centralized updates, target-pose providers, physics ownership, and garage summons in a mature open-world runtime. P8 moves to the UE5 reconstruction: a runnable, recoverable vehicle-scheduling prototype. Its scope covers garage requests, fixed-step policy, identity continuity across presentation degradation, and route continuation after checkpoint recovery. Suspension, tires, and production vehicle presentation remain outside this article; vehicle motion and physics belong to P11, while presentation design and its L2 implementation belong to P15 and P21.

Previous article: Urban Vitality P7 | UE5 Population Orchestration: Stable Identity, Tiered Scheduling, and Representation Leases

Related foundation: Urban Vitality P3 | Open-World Vehicle Scheduling

Next article: Urban Vitality P9 | UE5 Traffic Orchestration: Dynamic Routing, Capacity Gates, and Conflict-Zone Reservations

Introduction: Traffic Scheduling Begins with Constrained Requests

A vehicle prototype often starts with boxes moving along splines. Continuous position changes are enough to suggest traffic. Open-world scheduling must also resolve the following questions under bounded capacity:

  • How many vehicle requests may enter the road at once?
  • When requests compete, which one receives a runtime identity first?
  • Which policy should run on the current fixed step when the entrance is occupied, the signal is closed, or a leader is too close?
  • Is a vehicle still the same vehicle after its presentation is degraded?
  • If a checkpoint is captured during dispatch, can queue order, identifiers, and route progress continue from the same state?
  • Does a change in debug color or geometry imply a change in authoritative logic?

The P8 acceptance map, /Game/Cyber2077/Maps/VehicleScheduling_Demo, compresses these questions into a 200-meter test corridor. It contains a garage entrance, four continuous lane segments, a signal-controlled area, two route checkpoints, and an end-of-route turnaround. The default scenario plans 18 vehicles. They are not created in one burst: requests are injected in batches, accepted into a queue, released through a cooldown, and gated by entrance spacing.

Rectangles, triangles, and debug dots are temporary representations. Green means ordinary route following, orange means yielding, and red means waiting at the signal. Geometry communicates presentation intent; color communicates the policy selected for the current step. These are separate state axes.

Demo Observation Points

After PIE starts, ACyberVehicleSchedulingDemoActor builds the four-lane route, the signal cycle, and 18 planned requests, then creates the garage runtime. The requests do not become vehicles simultaneously. The host injects them into the garage queue in batches. The garage validates identity and dependencies, sorts by priority and FIFO order, and checks capacity, cooldown, and entrance occupancy before synchronously creating a runtime vehicle. Vehicles leaving the entrance one by one are evidence that dispatch eligibility becomes true incrementally; this is not a prerecorded spawn sequence.

The HUD exposes several independent state axes. Planned, injected, dispatched, and queued counts describe request progress. Managed, Moving, Waiting, Yielding, and Turnaround describe scheduling activity. Active, Simulated, and Stub describe presentation tiers. A color or a single total cannot replace these measurements.

The GARAGE, SIGNAL, and ROUTE observation points frame the shared entrance, controlled stop line, and complete route. SAVE and RESTORE capture the scene before dispatch has completed, allow the simulation to diverge, and then restore queue state, signal phase, session-scoped identifiers, and per-vehicle route progress. This is an in-memory acceptance checkpoint for the same PIE session, not a disk SaveGame.

Demo operation Observable result Contract under test
Start PIE Requests enter in batches; vehicles leave the garage one at a time Acceptance, priority/FIFO, capacity, cooldown, and session-stable numbering
Switch to GARAGE No new vehicle is dispatched before the entrance clears Queue capacity and road-entry spacing jointly gate dispatch
Switch to SIGNAL Vehicles stop on closed and slow on yield Policy priority, stop-line scope, and fixed-step movement are separate
Switch to ROUTE Vehicles traverse four segments, preserve proxy-center headway, and turn around Route index, lane progress, leader relation, and turnaround gate
Move the presentation observer Rectangle, triangle, and hidden states change; the VehicleId set does not Identity, simulation tier, and presentation resource are independent
SAVE / RESTORE The same frame, queue, and route progress return and continue Queue, signal, session numbering, and route-continuity recovery
Overview of the P8 vehicle scheduling demo and its 200-meter route
Demo Capture 1 | The ROUTE view covers the garage, queue, signal, route checkpoints, and turnaround. The HUD reports request stages, scheduling policies, presentation tiers, and per-vehicle route progress side by side.

From the Reference Runtime to UE5: Preserve Scheduling Semantics

The vehicle system examined in P3 is much larger than this demo. It maintains an entity-keyed registry, builds a per-frame snapshot before physics, runs fixed-step work per vehicle, then reads physics output and releases strong references after physics. A stable entity ID and stub maintain identity while the full entity is only a current representation. Autopilot obtains target poses from traffic slots, speed splines, or follow targets; a set of reason bits arbitrates physics ownership with other systems. A garage summon crosses placement selection, stub creation, population-entity requests, traffic-slot attachment, and action completion.

Those are source-reading observations. The identity, eligibility, fixed-step, and recovery rules extracted for P8 are reconstruction contracts; they are not proof that the demo reproduces every reference type.

Figure 1: Evidence layers from source observations to the UE5 demo
Figure 1 | P3 source responsibilities, the contracts derived from them, and the P8 implementation belong to different evidence layers.

Five Constraints Carried into the Reconstruction

First, vehicle identity cannot depend on the current Actor. The reference runtime can retain autopilot requests before an entity is materialized, and some target-pose providers can advance stub transforms directly. Unloading a full entity does not necessarily delete identity or task progress.

Second, accepting a request is not the same as making a vehicle available. A garage summon includes resource checks, asynchronous placement, stub or entity preparation, route attachment, and completion callbacks. A synchronous return value only reports admission to one stage.

Third, the fixed step is the time boundary for control decisions. The vehicle system creates a centralized update snapshot, advances logic on a fixed step, and lets physics and post-update work finish the frame. Ownership changes, target-pose selection, and presentation interpolation all depend on an explicit order.

Fourth, autopilot is not a Boolean. Traffic slots, quest splines, and follow targets are different target sources, while several reasons can arbitrate physics enablement. Traffic ownership, entity LOD, and physics state may be combined independently.

Fifth, recovery restores identity and progress rather than old presentation objects. Per-vehicle persistent data owns detailed state; spline progress and speed can be written back so a later representation resumes from the same route position.

What the UE5 Demo Deliberately Omits

Vehicle scheduling pipeline from planned requests to checkpoint recovery
Pipeline overview | A request has no VehicleId before dispatch. Once identity is established, policy, route, presentation tier, and checkpoint data continue around that same VehicleId.

The prototype does not implement the reference entity-stub service, population attach pipeline, physics reason-bit set, traffic-slot solver, or quest spline. ACyberVehicleRuntimeActor carries authoritative runtime state, while separate demo geometry presents the result. The lowest tier is named Stub, but it still retains a runtime Actor. Here it means “do not advance and do not allocate a normal proxy,” not a complete reproduction of the reference Entity Stub.

P8 demonstrates a closed loop for session-stable VehicleIds, bounded dispatch, policy arbitration, route continuity, replaceable presentation, and checkpoint reconstruction. Production-scale entity streaming remains outside its scope.

Evidence is recorded by layer. A reference-runtime observation may justify a contract such as “identity survives representation changes,” while the UE5 class chosen to demonstrate it remains project-specific. A passing UE5 test validates the reconstructed contract in this prototype; it provides no evidence that the reference runtime uses the same queue, Actor type, or checkpoint schema. Separating the layers prevents project terminology from becoming an unsupported source claim.

The demo also narrows the meaning of “available.” A request can be structurally valid, accepted into the queue, eligible by priority, blocked by cooldown, blocked by entrance space, dispatched into a runtime Actor, or observed later after clearing the entrance. Each stage has a different owner and a different observable signal. Treating all of them as a single spawn Boolean would remove the information needed for cancellation, telemetry, recovery, and load testing.

Figure 2: The 200-meter acceptance corridor and its observation points
Figure 2 | Four lane segments form an acceptance corridor for dispatch, signals, and turnaround. They are not a complete city road network.

Ownership Is Split Across Three Runtime Layers

ACyberVehicleSchedulingDemoActor owns global scene state: the fixed-step accumulator, route definition, signal cycle, not-yet-injected requests, presentation observer, and in-session checkpoint. It creates and drives one ACyberVehicleGarageRuntimeActor rather than owning each queue operation itself.

The garage Actor owns the request queue, known lanes, aggregate capacity, and managed-vehicle set. Each ACyberVehicleRuntimeActor owns an FCyberVehicleRuntimeStatus: VehicleId, prototype, garage ID, current lane, route array and index, LaneAlpha, speed, fixed-step count, current policy, leader, presentation intent, and simulation tier.

GarageCapacity is an aggregate upper bound on managed vehicles. The entrance gate is shared by all vehicles. There are no persistent parking spaces, slot numbers, or vehicle-to-slot ownership records, so the model must not be described as a stable GarageSlot system.

Per-vehicle state still has four independent axes:

State axis Question answered Typical trigger Continuity snapshot
RuntimeState Which lifecycle state is the vehicle in? Summon, takeover, destruction Reconstructed on restore
AutopilotStrategy Which long-lived driving source is intended? Route configuration, parking, manual takeover Yes
ControlPolicy How should this fixed step respond? Signal, leader, pedestrian risk Continuity cache; recomputed after restore
SimulationTier Does route logic run, and which presentation is intended? Observer distance and budget Continuity cache; recomputed after restore

A RouteFollow vehicle may temporarily become WaitingAtSignal while also being degraded to Stub. Its route intent still exists, the current policy forbids movement, and the lowest tier suppresses the step. Collapsing these states into a single “red-light tier” or “distant tier” would make correct recovery impossible.

The ownership boundary is equally important. The demo host owns scene cadence, global route data, the signal clock, and the pending content plan. The garage owns eligibility to enter the road. The vehicle record owns its own route progress. The HUD owns none of them: it reads summaries and forwards button operations. This prevents a display feature from becoming an accidental source of truth.

A default vehicle crosses several state boundaries. Its request first receives an EnqueueOrdinal. Successful dispatch assigns a VehicleId. Summon configuration places it in Summoned/RouteFollow, and the first valid fixed step changes runtime activity to Autopilot. A signal or leader changes only the current ControlPolicy. Observer distance changes only SimulationTier. After checkpoint reconstruction, the new Actor receives the old VehicleId, route, and long-lived strategy. The Actor carries this path in the prototype, but does not define identity.


Garage Dispatch: Request Queues and Runtime Vehicle Creation

Batched Injection of Eighteen Requests

The default scenario defines 18 requests. Each contains a stable RequestId, a vehicle prototype ID, an entrance lane, and a priority. Request 0 has priority 100; the others have priority 10. This verifies that higher priority wins while equal-priority requests retain insertion order.

Configuration does not immediately place all requests in the garage queue. The demo keeps PendingDemoDispatchRequests and attempts to inject up to three requests every ten fixed steps. The HUD distinguishes planned-but-not-injected requests, queued requests, and requests that already created runtime vehicles.

P8 garage request batches and dispatch queue
Demo Capture 2 | During the third injection batch, 9 of 18 requests have entered the runtime and 9 remain pending. The HUD reports queue depth, dispatched vehicles, and the last request ID separately.

Enqueue Validates Identity and Dependencies First

FCyberVehicleGarageRequestQueueRuntime::Enqueue validates garage ID, request ID, prototype, target lane, and maximum queue depth before changing state. A garage already bound to another ID rejects the request. The outer runtime also rejects a target lane that is inconsistent with the garage's known lane data.

Request IDs are checked against both the dispatched set and the pending queue. The code field is still named CompletedRequestIds, but “completed” here only means that a runtime vehicle was created. It does not mean that the vehicle cleared the entrance or finished road attachment. Duplicate requests cannot receive another vehicle number. A full queue returns bQueueFull without modifying existing order.

An accepted request receives a monotonically increasing EnqueueOrdinal. This is not vehicle identity; it only makes equal-priority sorting stable. A VehicleId is allocated at dispatch. Keeping the two values separate allows requests to wait or be cancelled without reserving a vehicle identity prematurely.

Priority First, FIFO Within the Same Priority

When dispatch is permitted, the queue performs a stable sort: higher priority first, then lower EnqueueOrdinal. It removes only the bounded number allowed on that step and writes those RequestIds to CompletedRequestIds, which this article consistently calls the dispatched-request set.

Figure 3: Request lifecycle from planning to an observed clear entrance
Figure 3 | Runtime Actor creation corresponds to Dispatched. Entry Cleared is a later observation of vehicle position, not a completion event.

There is no dedicated RoadEntryCompleted event. The scheduler observes that the entrance has become free on a later fixed step. The dispatched set must not be interpreted as “road entry complete.”

Vehicle IDs combine the garage ID with NextVehicleOrdinal:

vehicle.garage.article2_demo.request.000000
vehicle.garage.article2_demo.request.000001
...

The ordinal increments only when dispatch actually succeeds, and the checkpoint saves it. Within the same demo world and in-memory checkpoint scope, a later vehicle cannot reuse an old number. This identity is independent of Actor names, array indices, and visible-proxy order. It is not a globally unique identifier across processes, worlds, or maps; production persistence would need a Session/World namespace or global entity ID.

Four Gates Must All Permit Dispatch

The garage increments its own FrameIndex, then checks queue emptiness, cooldown, aggregate capacity, and MaximumDispatchPerStep. The upper bound is:

min(
    GarageCapacity - ActiveVehicleCount,
    MaximumDispatchPerStep,
    PendingRequestCount
)

Defaults are capacity 18, queue depth 26, one dispatch per step, and an eight-queue-frame cooldown. After dispatch, the next eight frames are suppressed; the ninth interval frame may dispatch again. This prevents a same-position burst but does not by itself guarantee safe entrance spacing.

Before the garage step, the host checks whether any vehicle remains within the first eight meters of the 50-meter entrance segment, equivalent to LaneAlpha < 0.16. While occupied, effective capacity is clamped to the current managed count, causing the capacity gate to return without creating a vehicle. When the entrance clears, configured capacity is restored.

Figure 4: Queue order, aggregate capacity, cooldown, and entrance-space gates
Figure 4 | Eligibility is a sequence of rules with different responsibilities. `GarageCapacity` is not a persistent parking-space set.

Cooldown controls time separation; entrance occupancy controls space separation. Either rule alone is insufficient. A slow or stopped vehicle can outlast a cooldown, while an entrance-only check can amplify repeated attempts at high frame rates.

The scene and garage also own separate frame indices. Both normally advance once per valid fixed step, but both must be saved. Resetting the garage frame while restoring only the scene frame recomputes the cooldown window; restoring LastDispatchFrame without the current queue frame can suppress for too long or too briefly.

The opening sequence shows why the distinction matters. On scene step 0, requests 00, 01, and 02 enter the queue. The garage then advances to queue frame 1, sorts the requests, dispatches priority-100 request 00, and increments the vehicle ordinal to 1. Queue frames 2 through 9 remain inside the cooldown window. At scene step 10, the host injects requests 03, 04, and 05. The cooldown may now permit another dispatch, but the spatial gate can still reject it if vehicle 000000 remains inside the first eight meters. Request 01 receives VehicleId 000001 only when both time and space conditions are true.

The entrance rule is implemented through effective capacity rather than by deleting or reordering requests. A suppressed step leaves queue order intact. When the entrance clears, the next stable sort sees the same candidates and the same EnqueueOrdinal values. A screenshot of progressive spawning alone would not establish this property; queue depth, last request, and frame counters distinguish it from a delayed animation.

Failure results are part of the contract. Invalid IDs, wrong lanes, and mismatched garages are not accepted. Duplicates set bDuplicate; maximum depth sets bQueueFull; cooldown and capacity are exposed through bSuppressedByCooldown and bSuppressedByCapacity. Callers can distinguish invalid input, queue rejection, and a valid request that is still waiting.

Actor Creation Is Still Synchronous

Once all gates pass, the garage spawns ACyberVehicleRuntimeActor at the entrance, constructs its summon request, assigns a session-stable VehicleId, and selects RouteFollow. The Actor's own visible representation is disabled; the demo host creates a separate debug proxy.

The synchronous creation path omits the reference runtime's multi-stage request, stub, population-entity, and attach-ready pipeline. P8 has no spawn token, asset streaming, or attach-ready event. Its stages cover planning, queue acceptance, and dispatch.


Fixed-Step Policy Arbitration and Route Advancement

Logic Time Is Separate from Render Frames

The demo accumulates DeltaSeconds and executes a fixed step whenever the total reaches 0.1 seconds:

FixedStepAccumulator += Max(0, DeltaSeconds);
while (FixedStepAccumulator >= FixedStepSeconds)
{
    AdvanceVehicleSchedulingDemoFixedStep(FixedStepSeconds);
    FixedStepAccumulator -= FixedStepSeconds;
}

The step is stable, but there is no per-frame catch-up limit. A long hitch can run many logical steps in one render frame and worsen the hitch. Production code would normally cap substeps, discard bounded time debt, or switch background agents to a lower frequency.

Figure 5: Execution order of the 0.1-second fixed step
Figure 5 | A shared pre-step snapshot precedes per-vehicle policy and route writeback. The current loop has no maximum catch-up count.

The fixed-step body follows a deliberate order. It injects the next content-plan batch, advances the signal clock, evaluates entrance occupancy and garage dispatch, ensures that newly managed vehicles have the authoritative four-segment route, and applies the current simulation tier. It then captures PreStepStatuses, derives signal and leader inputs from that shared snapshot, evaluates or vetoes movement, advances eligible routes, handles end-of-route competition, and finally updates tiers, debug proxies, and HUD summaries.

The order separates eligibility, decision, and observation. Dispatch remains independent of proxy creation, policy reads one coherent vehicle slice, and HUD values are produced after authoritative writeback. Collapsing these phases into Actor ticks would allow array order, tick-group changes, or visualization code to alter traffic behavior.

Policy evaluation and route advancement are separate. Evaluate returns a policy, whether to advance, a speed multiplier, and a reason. Route code consumes time only when bShouldAdvance is true. Waiting at red does not permanently overwrite stored speed; yielding constrains only the current step.

Policy Priority Is Explicit

FCyberVehicleAutopilotPolicyRuntime::Evaluate processes inputs in this order:

  1. Despawn requested: DespawnPending, no movement.
  2. Manual branch: Manual, currently advances at the normal multiplier.
  3. Parked: Parked, no movement.
  4. Closed signal: WaitingAtSignal, no movement.
  5. Yield signal: Yielding, 0.35 multiplier.
  6. Pedestrian hazard: Yielding, no movement.
  7. Leader hazard: Yielding, record leader, 0.35 multiplier.
  8. Otherwise: RouteFollow when a route exists, else LaneFollow.

This order makes outcomes independent of call-site Boolean ordering. A closed signal wins over an ordinary leader hazard. Manual returns before signal handling. The current map does not exercise pedestrian risk or Manual; those are interface branches covered by function-level automation, not proof of player takeover or physics ownership transfer.

Figure 6: Emergency headway veto and general policy priority
Figure 6 | Emergency headway protection sits outside `Evaluate`; the general policy returns movement constraints and a reason for the current step.

The Signal Applies Only to Its Lane and Stop-Line Region

The cycle is four seconds open, two seconds yield, and four seconds closed. It controls the second lane segment. The stop line is at LaneAlpha = 0.82; the yield approach begins at 0.35.

A global closed state must not turn every vehicle on the 200-meter route red. Before policy evaluation, the host checks the controlled lane and computes the distance the vehicle could move on the next fixed step:

SignalDecisionAlpha
    = StopLineAlpha
    - ProjectedAlphaDelta
    - epsilon

This look-ahead prevents a point vehicle that begins just before the threshold from crossing after a full step. The yield phase uses the earlier approach threshold and a 0.35 speed multiplier.

The model has no vehicle length, braking distance, acceleration, or tire friction. It proves that scheduling can scope a signal to the correct lane and local interval. P11 must handle body envelopes, braking, contact, and the final physical stopping position.

The yellow interval follows the same state boundary. It leaves stored cruise speed and AutopilotStrategy unchanged, contributing a local input only inside the approach region. Yielding scales distance on the current fixed step; the next evaluation returns to RouteFollow when the gate opens.

Route-follow, yield, and waiting policies during the closed signal phase
Demo Capture 3 | The closed signal constrains only vehicles approaching its stop line. Green, orange, and red proxies show route following, yielding, and waiting; the HUD reports Moving 6, Wait 1, and Yield 1.
Figure 7: Signal scope, stop-line look-ahead, and display hysteresis
Figure 7 | Stop decisions use projected movement for the next step. Debug color may lag, but it never writes back into authoritative `ControlPolicy`.

Leader Constraints Use Circular Route Progress

At the beginning of a step, the garage gathers every vehicle's pre-step status. It converts the four lane segments into one 200-meter coordinate: the full lengths of preceding segments plus LaneAlpha × current segment length.

For each vehicle, the scheduler scans the shared snapshot for the nearest positive forward distance. A negative difference receives the total route length because the leader has already passed the turnaround. All vehicles read the same time slice, so an earlier write cannot alter a later vehicle's input.

The minimum headway is 8 meters and the caution headway is 14 meters:

  • At or below 8 m, an outer emergency guard sets Yielding, records the leader, and blocks movement.
  • Between 8 and 14 m, policy evaluation receives a leader hazard and advances at 0.35 speed.
  • Beyond 14 m, the signal or normal route policy applies.

Automation tracks the minimum two-dimensional distance between vehicles on the same lane and accepts no less than 700 cm. That one-meter tolerance accounts for discrete steps and proxy-center measurement; it is not evidence of a strict eight-meter clear distance between vehicle bodies.

Forward distance is evaluated on a circular route. If candidate progress is greater than the current vehicle's progress, the difference is direct. Otherwise, total route length is added, representing a leader that has crossed the turnaround and re-entered near the beginning. This keeps one leader query valid near the route boundary and avoids treating the last and first segments as unrelated spaces.

The shared pre-step snapshot is the determinism boundary. Without it, a following vehicle could read a leader that had already advanced while another still read the previous position. Reordering the managed array would then change yielding outcomes. P8 does not parallelize vehicle updates yet, but its read-only input slice and per-vehicle writeback preserve the boundary needed for future parallel work.

Figure 8: Circular route progress, pre-step snapshots, and proxy-center headway
Figure 8 | The demo validates topology and identity continuity. Eight meters is a proxy-center scheduling threshold, not body clearance.

The emergency guard is outside the general evaluator and does not produce a complete FCyberVehicleAutopilotPolicyDecision. If replay, telemetry, or unified decision reasons are required, this branch should move into the same policy model.

MovingVehicleCount counts vehicles whose route was advanced on this step, not vehicles with a stored speed above zero. A yielding vehicle moving at 0.35 counts as Moving; a Stub does not, even if its last saved speed is nonzero.

Color Hysteresis Does Not Delay Logic

WaitingAtSignal turns red immediately. Leaving the waiting state requires 0.3 seconds of stable evidence; other display changes require 0.5 seconds. This avoids green-orange flicker between fixed steps.

The hysteresis exists only in DisplayedVehiclePolicies. Authoritative ControlPolicy updates immediately, and route advancement consumes the current decision. Visual stabilization cannot contaminate scheduling state.


Route Continuity: Topological Progress and World Position

Four Segments Form a Recoverable Route

The route contains four straight 50-meter segments. Segments one, three, and four specify 12 m/s; segment two specifies 8 m/s. Per-vehicle continuity includes:

VehicleId
RouteLaneSegmentIds
CurrentRouteLaneIndex
CurrentLaneSegmentId
LaneAlpha
SpeedMetersPerSecond
VehicleLocation
FixedStepCount
SimulationTier
AutopilotStrategy
ControlPolicy
FollowingTargetVehicleId

Advancement computes DeltaAlpha = Speed × DeltaSeconds / LaneLength. At the end of a segment, the runtime switches to the next lane, resets LaneAlpha, and places the vehicle at the new start. Unconsumed time beyond the old segment is not carried forward; the vehicle moves on the new segment on the next fixed step. This boundary loss is small at 0.1 seconds but should become a remaining-distance loop for larger steps or shorter segments.

The current runtime also does not reapply the next segment's speed limit on transition. The second segment's 8 m/s is scene data and a future contract, not a validated dynamic speed-limit result.

World position alone is ambiguous around adjacent lane projections and does not encode the next segment. CurrentRouteLaneIndex + CurrentLaneSegmentId + LaneAlpha defines the topological location; world position is presentation data and a consistency check.

These fields make corruption observable. A saved lane ID can be checked against the route array at CurrentRouteLaneIndex; LaneAlpha can be clamped or rejected; and the reconstructed route position can be compared with VehicleLocation within a tolerance. A raw transform provides none of these topological checks. It may place a proxy in the expected part of the map while silently losing which branch should be taken next.

P8 verifies continuity on a fixed four-segment route through transitions, turnaround, tier changes, and checkpoint recovery. It does not support arbitrary route replacement. A new route containing the current lane could remap by lane ID; otherwise recovery needs an explicit rule such as re-anchor, return to entrance, wait, or fail.

Turnaround Competes for the Same Entrance

At the final segment, LaneAlpha >= 1 does not immediately teleport a vehicle. The garage first checks the same eight-meter entrance region used by dispatch. Only a clear entrance permits RestartVehicleRoute and increments RouteTurnaroundCount.

This prevents a newly dispatched vehicle and a returning vehicle from independently claiming the same position. The implementation is still an ordered loop, not a general reservation system; the first vehicle encountered can win when several compete. P9 addresses broader spatial ownership and intersection reservations.

A vehicle completes the four-segment route and one turnaround
Demo Capture 4 | One turnaround has completed. The HUD retains the 200-meter route, four segments, Turnarounds 1, and samples of VehicleId, current segment, and LaneAlpha.

SimulationTier Determines Whether Route Logic Runs

ApplyVehicleSimulationTier assigns Active, Simulated, or Stub. Active and Simulated both keep bSimulationEnabled = true and run the same route fixed step. Stub disables simulation. Inactive, disabled, lane-mismatched, or invalid-step vehicles do not update LaneAlpha or FixedStepCount.

P8 Stubs freeze at their last route progress, and promotion resumes from that point. Reference target-pose providers may advance stub transforms without a full entity; the demo instead uses a frozen lowest tier to isolate identity and recovery. A future system may use low-frequency route updates or ETA reconstruction, but signal phase, congestion, turnaround, and streaming boundaries require more than a lower tick rate.


Identity, Presentation, and Checkpoint Recovery

One VehicleId Can Use Different Presentation Tiers

The tier is selected from two-dimensional observer distance. Defaults are 25 meters for Active and 500 meters for the Simulated upper bound; beyond that is Stub. Thresholds are clamped so the Simulated distance cannot be smaller than the Active distance.

Applying a tier changes only SimulationTier, bSimulationEnabled, PresentationIntent, and VisibilityState. It does not allocate a new VehicleId, change route ownership, or alter the dispatched-request set. Automation compares the complete VehicleId array before and after observer movement.

Simulation tier Debug geometry Normal visibility Route fixed step
Active Rectangle Visible Runs; full-vehicle presentation intent
Simulated Triangle Visible Runs; lightweight-proxy intent
Stub Hidden; dot in debug mode Hidden / optional marker Does not run; retains last route progress
Active, Simulated, and Stub vehicle tiers visible together
Demo Capture 5 | One session-scoped VehicleId set is distributed across 3 Active, 8 Simulated, and 4 Stub vehicles. Rectangles, triangles, and dots are representations, not three populations.

All managed runtime Actors keep their built-in visible components hidden; the host owns the debug proxies. Tests require proxy count to equal Active plus Simulated.

All three tiers still retain ACyberVehicleRuntimeActor, and every logical vehicle has a prebuilt proxy component. Stub hides the proxy; it does not destroy the Actor or remove all object cost. Active and Simulated have the same route-solving cost, while only Stub stops. P8 separates presentation selection from session identity, but it does not prove thousand-vehicle object density. Production work still needs pooling, batching, and Actor-free data carriers.

Nor is this tier identical to P7 population tiers. P7 establishes the general contract of stable identity, logical tiers, and disposable representations. P8 SimulationTier::Stub is a frozen vehicle-demo tier that retains its Actor; it is neither P7 StubTier nor the reference Entity Stub.

Figure 9: VehicleId, runtime Actor, SimulationTier, and debug presentation
Figure 9 | All tiers retain a runtime Actor. Active and Simulated currently execute the same route fixed step.

Presentation Observer and Player Camera Are Independent

By default, the presentation observer follows the first vehicle in the garage status array. This creates a changing tier distribution without requiring the player camera to move. Tests may call SetPresentationObserverLocation and move it far away so every vehicle becomes Stub.

GARAGE, SIGNAL, and ROUTE change only the capture camera. They do not move the presentation observer. A screenshot must distinguish camera position from the algorithm's observer input; apparent screen distance alone is not evidence of tier selection.

The Checkpoint Saves Four Kinds of State

BuildVehicleSchedulingDemoSaveSnapshot serializes state rather than Actor references:

  1. Scene timing: demo frame, accumulated time, observer position, signal durations, phase time, gate state, cycle count, and turnaround count.
  2. Planned injection: total, injected, and dispatched counts; batch count; last request; and requests not yet injected.
  3. Garage scheduling: pending queue, dispatched RequestIds (CompletedRequestIds), queue frame, last dispatch frame, next request and vehicle ordinals, known lanes, capacity, depth, per-step limit, and cooldown.
  4. Per-vehicle state: a generic Gameplay State Record reconstructs vehicles; a Route Continuity Snapshot then restores route array, lane and index, LaneAlpha, speed, location, fixed-step count, tier, long-lived strategy, current policy, and leader.

The two per-vehicle records are not redundant. The generic record says which vehicles and garage ownership to recreate; route continuity says where each vehicle resumes.

Saving the content plan that has not reached the queue is essential. A checkpoint captured at step 35 may contain planned requests that have never been offered to the garage. Saving only the garage queue and managed vehicles would make them disappear. Conversely, saving only the original list of 18 would inject already-dispatched requests again. The snapshot keeps plan progress, pending garage work, and dispatched RequestIds as separate collections.

Signal continuity also needs more than a color. The snapshot carries phase durations, current phase time, gate state, and cycle count. A restored red proxy with a reset phase clock would look correct for one frame and then diverge. The same principle applies to dispatch: LastDispatchFrame has meaning only relative to the restored queue frame.

Snapshot fields also have different semantics. VehicleId, GarageId, route, lane/index/LaneAlpha, speed, long-lived AutopilotStrategy, queue order, ordinals, and signal time are direct continuity facts. ControlPolicy, FollowingTargetVehicleId, and SimulationTier are derived from environment or observer state. VehicleLocation can be reconstructed from topology and progress and is useful for cross-checking. Proxy visibility and leases should always be rebuilt. The implementation writes some derived fields into the snapshot and applies them first, so they are checkpoint continuity caches rather than long-term persistent facts.

Restore Ownership Before Applying Continuity

Restore destroys the old garage Actor, creates a new one from snapshot garage data, restores queue/configuration, and reconstructs vehicle Actors from Gameplay State Records. The reconstructed count must match. Route snapshots are then applied one by one, and that count must also match.

Only after those stages succeed does the host restore route definitions, observer, signal, statistics, and not-yet-injected requests, then recreate debug proxies. The next fixed step continues from the saved queue frame, signal phase, vehicle ordinal, and route progress while reevaluating policy and tier.

The process avoids serializing disposable proxies, but it is not atomic. The old garage is destroyed before complete validation; a mid-restore failure can leave partial new state. Production recovery should preflight garage ID, route references, VehicleId uniqueness, and record counts in a temporary container, build a candidate state, and swap only after all checks pass.

An atomic version would separate parsing, validation, construction, and activation. Parsing would read a versioned schema without touching the world. Validation would resolve every garage and lane reference and verify cross-set uniqueness. Construction would create candidate runtime records and presentation leases in an isolated container. Activation would replace the old state only after every candidate was valid. If any stage failed, the live garage would remain untouched and the error could identify the exact request, vehicle, or route field. The current demo intentionally stops before that transaction layer.

Post-load invariants should include unique VehicleIds; valid lanes and matching route indices; LaneAlpha in [0,1]; location consistent with topology and progress; no RequestId in both pending and dispatched sets; NextVehicleOrdinal not below dispatched count; valid, non-self leader relations; policy recomputed before movement; tier recomputed from the restored observer or an explicitly frozen observer scope; and tier counts summing to managed vehicles. Current code directly validates snapshot markers, route index/lane agreement, and restore counts. Automation verifies totals, tiers, and continued movement. The remaining relations are not yet one unified post-load audit.

Direct and derived state should also fail differently. An invalid VehicleId, missing route lane, or contradictory request set should reject the candidate snapshot before it replaces the live garage. A stale leader or tier can be discarded and recomputed. Treating every serialized field as equally authoritative either accepts corrupt ownership or rejects state that can be repaired safely.

Vehicle scheduling checkpoint saved at fixed step 230
Demo Capture 6 | The checkpoint is saved at step 230 with 14 logical vehicles, 4 queued requests, four-segment route progress, and the current signal state.
Vehicle scheduling checkpoint restored to fixed step 230
Demo Capture 7 | After the runtime is allowed to diverge, RESTORE returns to step 230, 14 vehicles, and 4 queued requests. VehicleId, route segment, and LaneAlpha samples match the saved scene.
Figure 10: Checkpoint application, topology preflight, and derived-state reevaluation
Figure 10 | The checkpoint restores continuity on the original route; it does not support arbitrary dynamic rerouting.

Cross-field consistency also matters. SignalGateState must agree with phase time and durations; LastDispatchFrame must precede the current queue frame; the planned, queued, and dispatched collections must not share a RequestId. Successful snapshots naturally come from one coherent runtime, but corrupt or cross-version data can violate these relations. A production SaveGame needs schema versioning and complete preflight validation.

FixedStepAccumulator is cleared on restore, so the next update begins with a complete 0.1-second step rather than an incomplete render-frame remainder. Logic acceptance tolerates the lost substep phase; exact replay would save the accumulator or restrict checkpoints to fixed-step boundaries.

The checkpoint remains inside the current demo Actor. It does not cover process restart, version migration, disk persistence, or map streaming.


Demo Acceptance: Reproducible Runtime Evidence

Three Observation Points Test Different Responsibilities

  • GARAGE verifies batch dispatch, cooldown, and entrance spacing.
  • SIGNAL verifies that green, orange, and red policies affect only the controlled region.
  • ROUTE verifies four-segment continuity, proxy-center headway, tier geometry, turnaround, and throughput.

The HUD reports planned, pending, injected, dispatched, queue depth, garage frame, managed vehicles, Moving/Waiting/Yielding, Active/Simulated/Stub, and turnaround count. Buttons and keyboard shortcuts 1/2/3 and K/L/R call the same interface; automation clicks the HUD hit boxes to prove the visible controls are wired.

A recommended walkthrough is:

  1. Start at ROUTE and verify that the total grows progressively rather than appearing at once.
  2. Move to GARAGE and verify that the next vehicle appears only after the entrance safety region clears.
  3. Move to SIGNAL and observe a full open/yield/closed cycle; only stop-line vehicles should change policy.
  4. Return to ROUTE and verify lane transitions, turnaround, and increasing throughput.
  5. SAVE before dispatch completes, run for several seconds, then RESTORE.
  6. Verify frame, pending, dispatched, and vehicle counts return and then continue.
  7. Move the presentation observer far away; all vehicles should become Stub, with zero normal proxies and an equal number of dots when Stub Debug is enabled.
  8. Return the observer to the first vehicle; rectangles and triangles should reappear without changing the VehicleId set.
Figure 11: P8 manual acceptance timeline
Figure 11 | The capture camera and presentation observer move independently and must be identified separately in evidence.
Demo Video | A 35-second walkthrough of batch dispatch, signal policy transitions, route continuity, presentation tiers, and checkpoint recovery. Video shows state over time; screenshots retain HUD values for inspection.

Automation Covers Runtime, Map Wiring, and Bounded Pressure

VehicleSchedulingDemo executes 600 fixed steps of 0.1 seconds, covering 60 seconds. All 18 requests must be injected and dispatched, the queue must drain, and 18 vehicles must remain managed. The run must observe batched injection, yielding, signal waiting, and turnaround. The VehicleId set must survive tier changes. With a distant observer, all 18 vehicles must become Stub with zero normal proxies; enabling debug must create 18 dots.

The same test checks that built-in runtime presentation remains hidden, proxy count equals Active plus Simulated, and each geometry matches its tier count. Waiting color must appear immediately; other colors may be delayed by hysteresis. The snapshot must contain four route segments, 18 vehicle records, 18 route-continuity records, and 18 dispatched RequestIds. Restored tiers, signal, turnaround count, and vehicle count must match; one further step must increment the frame exactly once.

This separates state correctness from visual evidence. A vehicle can have the correct RouteFollow policy while its displayed color is still inside the 0.5-second hysteresis window. Automation checks authoritative policy observations independently from proxy materials. It also requires the runtime Actor's own visible components to remain hidden, preventing two overlapping presentation systems from making proxy counts appear correct by accident.

VehicleSchedulingDemoMap validates map wiring rather than runtime functions: one host, one PlayerStart, four road segments, three lane indicators, one garage region, one signal region, two checkpoints, one end region, two pedestrian-space segments, six building blocks, ten labels, and the expected GameMode and HUD. -run=CyberBuildVehicleSchedulingDemoMap rebuilds the map to prevent asset/code drift.

VehicleSchedulingPressure128 creates 128 requests and drains them in eight bounded steps of at most 16 dispatches. All must be accepted without duplicates or capacity rejection and receive 128 session-unique VehicleIds. Dispatched count and NextVehicleOrdinal must both equal 128. Moving every vehicle to Stub must still produce 128 valid route-continuity snapshots.

The bounded-step assertion matters because a final total of 128 says nothing about work concentration. A queue that creates every Actor in one update could eventually reach the same total while producing an unacceptable spike. MaximumDispatchPerStep constrains request count, but synchronous Actor creation still has no measured millisecond budget. The test proves an algorithmic quantity bound, not a frame-time bound.

The pressure test validates queue order, stable session numbering, logical continuity, and the MaximumDispatchPerStep bound. It does not measure CPU/GPU time or prove that 128 production vehicle meshes, Chaos bodies, animated drivers, and audio meet a platform frame budget.

Acceptance target Directly visible in the main scene Function/automation only Data or later contract
VehicleSchedulingDemo Injection, dispatch, signal, following, turnaround, tiers, checkpoint — Production physics and presentation
VehicleSchedulingDemoMap Map objects, HUD, and camera wiring — City road graph and streaming
VehicleSchedulingPressure128 — Ordering, unique numbering, per-step bound, Stub snapshots Target-platform performance
Policy branches Signal and leader hazard Manual and pedestrian hazard Player takeover and pedestrian sensing
Figure 12: Evidence scope of runtime, map contract, and 128-request pressure test
Figure 12 | Pressure128 validates bounded request counts and data correctness, not CPU milliseconds or platform frame rate.

Frozen Baseline and Known Boundaries

The P8 acceptance candidate is 669501bf, frozen as article2-vehicle-scheduling-demo-v2. It compiled successfully; Playability Smoke reported no errors; ValidationAll reported zero errors and four known aggregate warnings; Standalone ran for 90 seconds without fatal, assert, ensure, or loading errors. Those warnings belong to the tested scope and must not be rewritten as “the project has zero warnings.”

The demo verifies:

  • Planned requests, queue admission, and vehicle dispatch are distinct stages.
  • Requests use priority and FIFO order, with explicit duplicate and queue-full results.
  • Aggregate capacity, per-step limits, cooldown, and entrance spacing jointly gate dispatch.
  • A saved monotonic ordinal generates VehicleIds stable within the demo session and checkpoint scope.
  • Signal, leader, and long-lived strategy inputs are arbitrated in deterministic fixed-step order.
  • Route index, lane ID, LaneAlpha, and world position maintain multi-segment continuity.
  • Active, Simulated, and Stub change participation and presentation intent without changing identity; Active and Simulated run the same route step, while Stub freezes but retains its Actor.
  • Mid-dispatch recovery restores queue, signal phase, session numbering, and route progress.
  • The map, HUD, automation, and 128-request pressure test can reproduce these contracts.

It does not yet verify:

  • The reference Entity Stub, asynchronous spawn tokens, or attach lifecycle.
  • Traffic slots, road-graph pathfinding, intersection reservations, lane changes, or city-scale flow.
  • Vehicle length, stop-line body correction, following brakes, suspension, tire contact, collision, or damage.
  • Player takeover, physics-reason arbitration, quest splines, or target following.
  • Arbitrary runtime rerouting or re-anchoring when the old lane is absent from a new route.
  • Actor-free distant advancement or route extrapolation across streaming boundaries.
  • Disk persistence, schema migration, atomic restore, or target-platform performance at scale.
  • Production meshes, lighting, materials, audio, or traffic aesthetics.

Those belong to P9 traffic networking, P11 vehicle motion and physics, and P15/P21 presentation design and UE5 presentation implementation. P8 placeholder proxies make scheduling observable and testable; they are not final-image acceptance.

The boundary is also visible in performance claims. Eighteen vehicles in the main scene demonstrate interactions among queue state, signal phase, route progress, and presentation tiers. The 128-request test demonstrates ordering, identity allocation, snapshot validity, and a per-step request-count ceiling. Neither result supplies milliseconds, memory residency, streaming latency, draw-call cost, Chaos cost, or platform frame rate. Those measurements require production assets, target hardware, representative road density, and a profiler capture rather than a larger integer in the HUD.

The turnaround is not a road-network solver. It reuses the entrance-space rule on a known circular route without branch selection, intersection reservations, lane changes, or closed-route recovery. It verifies that the last and first segments share one continuity model and one contested spatial resource.


Conclusion: Recoverable Vehicle-Scheduling State

P8 does not reduce scheduling to a spline, and it does not treat request admission as road entry. Requests move through planning and queueing; the garage grants dispatch through priority, capacity, cooldown, and entrance space. Each fixed step selects a policy before advancing the route. Presentation tiers may change while VehicleId and route continuity remain stable. A checkpoint restores queue, signal, numbering, and vehicle progress rather than old proxy components.

These contracts give later systems stable integration points. P9 can replace the straight corridor with a road graph and conflict reservations. P11 can add braking, suspension, and contact after policy permits movement. P15 and P21 can replace debug geometry without changing identity ownership or scheduling state.

P9 begins from this boundary: once vehicles can enter a road and preserve route continuity, lane connectivity, intersection space, and cross-system reservations decide who may proceed.


AI Collaboration Review

  • AI-assisted work: locating reference-runtime evidence and UE5 code for garage queues, autopilot policy, route progress, presentation tiers, checkpoints, and automation, then organizing the article around the demo's actual execution order.
  • Primary corrections: mapping P8 to the P3 vehicle-scheduling foundation; separating planning, queue admission, runtime creation, and observed entrance clearance; separating AutopilotStrategy, ControlPolicy, SimulationTier, and debug color; confirming that the current Stub freezes route logic while retaining a runtime Actor.
  • Human judgment boundary: synchronous Actor creation is not presented as the reference asynchronous entity pipeline; session VehicleId is not presented as a global ID; debug boxes are not production vehicles; the 128-request pressure test is not presented as final vehicle performance.
  • Verification basis: CyberVehicleSchedulingDemoActor, CyberVehicleGarageRuntimeActor, CyberVehicleGarageRequestQueueRuntime, CyberVehicleAutopilotPolicyRuntime, route-continuity code, three automated acceptance targets, and the P8 acceptance document.
  • Remaining risks: uncapped fixed-step catch-up, non-atomic restore, no low-frequency Stub route advancement, ordered entrance turnaround, and tiers that do not yet release runtime Actor cost.

1 thought on “Urban Vitality P8 | UE5 Vehicle Scheduling: Garage Dispatch, Policy Arbitration, and Route Continuity”

Leave a Reply

Discover more from AI Native Game Development

Subscribe now to keep reading and get access to the full archive.

Continue reading