Skip to content

Runtime Reliability and Performance

noteMASTER11 edited this page Jul 24, 2026 · 3 revisions

Runtime Reliability and Performance

TaxiDriver 3.4.0 Beta introduces a defensive runtime layer around the authoritative GE extension. Every contained failure is still written through the structured [TaxiDriver] logger, but an optional service, stale vehicle callback, or expensive export job can no longer stop unrelated gameplay work.

Runtime decomposition

taxiDriver.lua remains the public extension and phase-state owner, while reusable rules and infrastructure are delegated to smaller files:

Module Responsibility
rideRules.lua ETA, fare, pickup deadline, rating bonus, and passenger phase rules
offerPlan.lua Regular, rush, multi-stop, and cargo composition for a dispatcher pool
vehicleBridgeGuard.lua Generation-checked asynchronous vehicle reads and guarded writes
faultBoundary.lua Per-subsystem protected calls, circuit breaking, and independent cleanup
optionalLanBridge.lua Lazy and failure-contained Connected Phone loading

The main Lua chunk has 174 top-level locals. Tests enforce local-count and line-count budgets so future features do not silently approach LuaJIT's 200-local compilation limit.

flowchart LR
  UI["UI commands and BeamNG hooks"] --> Main["taxiDriver.lua orchestrator"]
  Main --> Rules["rideRules and offerPlan"]
  Main --> VehicleGuard["vehicleBridgeGuard"]
  Main --> Boundary["faultBoundary"]
  Main --> OptionalLAN["optionalLanBridge"]
  OptionalLAN -.->|loaded only when sharing is enabled| LAN["lanBridge"]
  Boundary --> History["vehicle and shift history"]
  Boundary --> Fleet["Fleet manager"]
  Boundary --> Gameplay["active trip update"]
  Boundary --> HUD["HUD publisher"]
Loading

Tick fault boundaries

Periodic services no longer share one unprotected call chain. faultBoundary executes each named subsystem with pcall. A failed service:

  1. writes a structured error containing the subsystem name and failure count;
  2. opens only that service's circuit for one second;
  3. allows the rest of the current tick to continue;
  4. retries automatically after the cooldown.

Core state remains authoritative. Circuit breaking is limited to periodic and optional work and does not invent replacement gameplay results.

sequenceDiagram
  participant Tick as onUpdate
  participant Guard as faultBoundary
  participant Fleet as Fleet update
  participant LAN as LAN update
  participant Game as Active trip
  participant HUD as HUD patch

  Tick->>Guard: call Fleet
  Guard->>Fleet: protected update
  Fleet--xGuard: Lua error
  Guard-->>Tick: failed, circuit open
  Tick->>Guard: call LAN
  Guard->>LAN: protected update
  LAN-->>Tick: success
  Tick->>Guard: call active trip
  Guard->>Game: protected update
  Game-->>Tick: success
  Tick->>Guard: publish HUD patch
  Guard->>HUD: protected publish
Loading

Mission and extension shutdown use independent cleanup calls. LAN shutdown, Fleet persistence, AI shutdown, energy cleanup, profile writes, and navigation restoration no longer depend on every earlier cleanup succeeding.

Vehicle VM generation guard

BeamNG can destroy and rebuild the selected vehicle VM while a Vehicle Bridge request is pending. A Lua object captured before a parts change, reset, vehicle replacement, or level transition must not be used when the callback arrives.

vehicleBridgeGuard records:

  • the requested vehicle ID;
  • the current vehicleScanGuard generation;
  • whether Vehicle Config or the VM settle window is active.

The callback compares the generation, requires a stable VM, resolves the vehicle again with getObjectByID, and invokes domain code only for the same live object.

sequenceDiagram
  participant Fuel as Fuel or shift service
  participant Guard as vehicleBridgeGuard
  participant Bridge as core_vehicleBridge
  participant VM as Vehicle VM

  Fuel->>Guard: request energyStorage
  Guard->>Guard: capture vehicle ID and generation
  Guard->>Bridge: requestValue
  VM-->>Bridge: asynchronous response
  Bridge->>Guard: callback
  Guard->>Guard: compare generation and resolve live object
  alt same stable vehicle VM
    Guard->>Fuel: data plus current vehicle
  else reset, replacement, or Vehicle Config
    Guard-->>Fuel: reject stale callback
  end
Loading

Dashboard energy, Realistic Mode initialization, the cheat fuel/charge slider, paid refueling, Magic Fuel routing, and shift restoration share this path. Realistic Mode and the cheat control both apply energy through the same setEnergyStorageEnergy implementation.

Vehicle Config suspension remains in vehicleScanGuard:

  • onUiChangedState stops vehicle-side work before parts are applied;
  • spawn/reset lifecycle events increment the generation;
  • a 1.5-second settle window lets controllers and energy storages register;
  • pending energy flags are invalidated before lazy refresh resumes.

HUD publication

A full HUD snapshot is sent after explicit state-changing commands and when a client requests resynchronization. Periodic updates use TaxiDriverHUDPatch.

The fast state contains scalar trip values such as distance, timers, phase, fuel, rating, and active notification. Expensive collections are excluded unless their owner reports a real change:

  • dispatcher offers;
  • shift history;
  • Fleet drivers and markers;
  • garage vehicle previews;
  • settings.
flowchart TD
  Event{"Explicit command or resync?"}
  Event -->|yes| Full["Build complete state"]
  Event -->|no| Fast["Build fast scalar state"]
  Full --> Snapshot["TaxiDriverHUDState"]
  Fast --> Dirty{"Fleet or shift collection dirty?"}
  Dirty -->|yes| Collections["Add changed collections"]
  Dirty -->|no| Patch["Partial revisioned patch"]
  Collections --> Patch
  Patch --> Client["Merge changed keys"]
Loading

Epoch, base revision, and revision validation remain unchanged. A dropped or discontinuous patch causes the client to request a new full snapshot.

Chunked Connected Phone map export

Connected Phone is loaded through optionalLanBridge; failure to load its socket or server dependencies cannot prevent taxi gameplay from starting.

Large road graphs are not serialized in one frame. A coroutine:

  1. captures the current level map;
  2. examines at most 500 links before yielding;
  3. resumes on later updates;
  4. discards its result if the level key changed;
  5. publishes normal road chunks only after the build completes.

Terrain-setting changes cancel an in-progress build. lan.json writes and LAN method calls are protected. The LAN server stops at mission shutdown and restarts on the next mission only when sharing is enabled.

AI safety cadence

The current native-AI traffic guard uses one accumulator per vehicle:

  • the player observer updates every 100 ms and samples twelve positions along a steering arc;
  • each Fleet observer updates every 200 ms and samples six positions;
  • Fleet route progress remains a separate 250 ms staggered monitor.

No traffic-guard scan is tied directly to render FPS. Speed limiting is jerk-controlled, and the observer releases its temporary native speed cap after the path remains clear. The previous 50 ms exact-approach/recovery ray controllers and 330 ms strategic spatial model are not started by the current AI runtime.

Logging and lifecycle filtering

Extended operation logging filters onVehicleResetted events to the player's or active TaxiDriver vehicle. Traffic vehicles no longer flood the BeamNG log.

BeamNG's native AI exposes Route Done only through AIStatusChange. TaxiDriver installs a protected observer only while an AI route is actively watched. The original guihooks.trigger is restored when route watching stops, so no permanent global modification remains after AI shutdown.

Native and external heartbeat intervals stop on early document shutdown, UI destruction, and mission shutdown. Persisted browser back/forward-cache pages are exempt so a restored Connected Phone page can continue its session.

Regression coverage

The 3.4.0 Beta release is checked by:

  • Lua syntax parsing for every changed module;
  • gameplay combinatorics covering stale callbacks, cleanup continuation, AI/Fleet behavior, shifts, fuel, and 500 deferred respawns;
  • 343 responsive UI states across all locales and HiDPI scenarios;
  • a live LAN probe for subnet HTTP, loopback proxying, WebSocket Upgrade, and bidirectional traffic;
  • archive entry and installed-file hash verification.

Clone this wiki locally