-
Notifications
You must be signed in to change notification settings - Fork 3
Architecture
flowchart TB
subgraph Views[UI views]
HUD[In-game TaxiDriverHUD<br/>AngularJS / CEF]
Phone[Connected Phone browser<br/>same Angular app + Canvas map]
end
subgraph GE[Game Engine Lua — authoritative]
Orchestrator[taxiDriver.lua<br/>phase and public API]
Boundaries[faultBoundary.lua<br/>isolated periodic services]
VehicleGuard[vehicleBridgeGuard.lua<br/>stable vehicle VM callbacks]
Publisher[hudPublisher.lua<br/>epochs, snapshots, patches]
Domains[Routing, persistence, shifts,<br/>economy, profile, events]
Supervisor[autopilot.lua<br/>native AI route adapter]
Navigation[navigationUi.lua<br/>minimap ownership + restoration]
Events[tripEvents / physicalPickup / policeCheck]
Fleet[fleetManager.lua<br/>economy + worker lifecycle]
Workers[fleetWorker.lua<br/>lightweight native-route workers]
AIJournal[aiLogger.lua<br/>streaming JSONL diagnostics]
OptionalBridge[optionalLanBridge.lua<br/>lazy failure containment]
Bridge[lanBridge.lua<br/>native External UI + chunked map export]
Network[networkAddress.lua<br/>LAN candidate ranking]
end
subgraph VL[Lazy Vehicle Lua]
Telemetry[taxiDriverTelemetry]
Cargo[taxiDriverCargo]
Observer[taxiDriverStockAiObserver<br/>smooth traffic guard]
end
BeamNG[BeamNG Free Roam systems<br/>road graph, traffic, triggers,<br/>stations, minimap, vehicles]
HUD <-->|engineLua / guihooks| Orchestrator
Phone <-->|HTTP + WebSocket| Bridge
Network --> Bridge
Bridge <--> Publisher
OptionalBridge --> Bridge
Publisher <--> Orchestrator
Orchestrator --> Boundaries
Orchestrator --> VehicleGuard
Orchestrator --> OptionalBridge
Orchestrator <--> Domains
Orchestrator <--> Supervisor
Orchestrator <--> Navigation
Orchestrator <--> Events
Orchestrator <--> Fleet
Fleet <--> Workers
Workers --> BeamNG
Supervisor --> AIJournal
Orchestrator <-->|Vehicle Bridge| Telemetry
Orchestrator <-->|lazy commands| Cargo
Supervisor <-->|native path and completion| Observer
GE <--> BeamNG
VL <--> BeamNG
The GE extension is authoritative for gameplay state, routes, money, rating, penalties, persistence, realistic fuel, delivery state, and external-phone connectivity. The in-game and external UIs are views over the same Lua state. UI-only state includes open pages, local countdown animation, chat scheduling, audio players, and compact/full layout selection. Vehicle Lua supplies damage and g-force telemetry, can enforce an emergency stop, and applies physical cargo mass.
| File | Responsibility |
|---|---|
lua/ge/extensions/taxiDriver/taxiDriver.lua |
Runtime orchestrator, authoritative state machine, domain coordination, and public UI API |
lua/ge/extensions/taxiDriver/rideRules.lua |
Fare, ETA, pickup window, rating bonus, and effective passenger-phase rules |
lua/ge/extensions/taxiDriver/offerPlan.lua |
Dispatcher-pool composition and order-type shuffling |
lua/ge/extensions/taxiDriver/faultBoundary.lua |
Per-subsystem protected calls, circuit breaking, and independent cleanup |
lua/ge/extensions/taxiDriver/vehicleBridgeGuard.lua |
Vehicle ID/generation validation and protected asynchronous Vehicle Bridge callbacks |
lua/ge/extensions/taxiDriver/optionalLanBridge.lua |
Lazy, failure-contained adapter around Connected Phone support |
lua/ge/extensions/taxiDriver/persistence.lua |
Settings, difficulty, profile, progress schemas, validation, and JSON I/O |
lua/ge/extensions/taxiDriver/routePlanner.lua |
Road-graph routing, semantic stop discovery, speed limits, and level caches |
lua/ge/extensions/taxiDriver/routeCache.lua |
Per-map JSON history of UI-published dispatcher offers and restoration after live-generation failures |
lua/ge/extensions/taxiDriver/vehicleControl.lua |
Telemetry, forced-stop/freeze control, and passenger/cargo access triggers |
lua/ge/extensions/taxiDriver/vehicleHistory.lua |
Vehicle identity, previews, per-configuration odometer, and work history |
lua/ge/extensions/taxiDriver/shiftTracker.lua |
Current and previous shift totals and net-income calculation |
lua/ge/extensions/taxiDriver/shiftHistory.lua |
Sanitized 60-second shift snapshots, installed-vehicle validation, and vehicle/energy restoration |
lua/ge/extensions/taxiDriver/tripEvents.lua |
Per-event enable/probability rules, lifecycle state and history projection |
lua/ge/extensions/taxiDriver/tripHistory.lua |
Expandable review records containing penalties and Random Event history |
lua/ge/extensions/taxiDriver/physicalPickup.lua |
Passenger/cargo props, horn sequence, walking/boarding and collision handling |
lua/ge/extensions/taxiDriver/policeCheckEvent.lua |
Optional police preload, native pursuit lifecycle and administrative fine |
lua/ge/extensions/taxiDriver/autopilot.lua |
Player validation, legal or strict-GPS route selection, native-AI lifecycle and physical arrival verification |
lua/ge/extensions/taxiDriver/navigationUi.lua |
Native minimap ownership, dynamic zoom, overlay occlusions and navigation-setting restoration |
lua/ge/extensions/taxiDriver/aiLogger.lua |
Opt-in streaming JSONL journal for AI route, target, traffic, controller, gearbox, recovery, and damage events |
lua/ge/extensions/taxiDriver/fleetManager.lua |
Fleet hiring, economy, persistence, native/world markers, and employee lifecycle |
lua/ge/extensions/taxiDriver/fleetWorker.lua |
Native Fleet assignment, reduced-rate traffic guard, current-segment replanning, and bounded failure hand-off |
lua/ge/extensions/taxiDriver/config.lua |
Static runtime, offer, balance, difficulty, fuel, and phase configuration |
lua/ge/extensions/taxiDriver/identity.lua |
Passenger-name pools and driver-avatar whitelist |
lua/ge/extensions/taxiDriver/passengerMood.lua |
Pure mood calculations and event severity functions |
lua/ge/extensions/taxiDriver/offerGenerator.lua |
Incremental coroutine job scheduler |
lua/ge/extensions/taxiDriver/nextOfferGuard.lua |
Real-time, phase-independent expiry validation for proposed next orders |
lua/ge/extensions/taxiDriver/routeDiversity.lua |
Spatial route-pair history and endpoint diversity validation |
lua/ge/extensions/taxiDriver/delivery.lua |
Cargo weight, fare premium, impact damage, and delivery-rating calculations |
lua/ge/extensions/taxiDriver/lanBridge.lua |
Native External UI lifecycle, stable pairing identity, Windows LAN discovery, coroutine-chunked road export, and external vehicle snapshots |
lua/ge/extensions/taxiDriver/networkAddress.lua |
Private IPv4 validation, adapter classification, bind verification, candidate scoring, and deterministic selection |
lua/ge/extensions/taxiDriver/hudPublisher.lua |
Full snapshots, partial collection-aware patches, epochs, revisions, and resynchronization checks |
lua/ge/extensions/taxiDriver/vehicleScanGuard.lua |
Vehicle Config suspension, VM lifecycle generations, and stable-VM settle timing |
lua/ge/extensions/taxiDriver/logger.lua |
Structured [TaxiDriver] operations, runtime, LAN, vehicle, warning, and error records |
lua/vehicle/extensions/taxiDriverTelemetry.lua |
Lazy-loaded damage/g-force telemetry and forced-stop inputs |
lua/vehicle/extensions/taxiDriverCargo.lua |
Lazy-loaded physical cargo mass attached to the active vehicle |
lua/vehicle/extensions/taxiDriverStockAiObserver.lua |
Lazy speed-only traffic guard, curved-path prediction and protected native Route Done hook |
ui/modules/apps/TaxiDriverHUD/app.js |
Angular controller, Lua bridge, UI-only state, sounds, chat, minimap geometry |
ui/modules/apps/TaxiDriverHUD/app.html |
Phone screens and Angular bindings |
ui/modules/apps/TaxiDriverHUD/app.css |
Complete phone styling and animation |
ui/modules/apps/TaxiDriverHUD/locales.json |
Nine complete localization dictionaries |
ui/modules/apps/TaxiDriverHUD/app.json |
BeamNG UI App registration and default dimensions |
ui/modules/apps/TaxiDriverHUD/external/ |
Lightweight browser entry point, detailed loader, synchronized phone runtime, sounds, and canvas map renderer |
mod_info/TaxiDriver/info.json |
Mod Manager metadata |
taxiDriver.lua declares:
-
core_groundMarkers— route path and remaining length; -
core_vehicleTriggers— passenger-door trigger support; -
core_vehicle_manager— vehicle integration; -
freeroam_gasStations— station interaction and refueling wrappers; -
gameplay_sites_sitesManager— semantic parking/site candidates.
It additionally uses gameplay/route/route, gameplay/traffic/trafficUtils, map graph APIs, facility APIs, raw POIs, marker interaction, vehicle bridge, settings, and native minimap extension APIs.
userSettingsdriverProfileuserProgress- mirrored summary fields in
state: balance, rating, rating totals, and completed rides
-
state.active,state.phase, active vehicle ID, difficulty, realistic-mode flag - current
offerspool - active
trip - floating
nextOfferand acceptance state - telemetry snapshot
- station, refueling session, and fuel detour
- minimap/navigation ownership
-
shiftTrackercurrent totals,shiftHistoryactive snapshot identity, AI-use flag, and the active order's optional random event -
fleetManagersession workers, worker routes, wage clocks, assignment state, and cached nearby traffic candidates
sequenceDiagram
participant GE as taxiDriver.lua
participant Pub as hudPublisher.lua
participant UI as In-game UI
participant LAN as lanBridge.lua
participant Phone as Connected Phone
GE->>Pub: authoritative state changed
Pub->>UI: TaxiDriverHUDState or Patch
Pub->>LAN: revisioned snapshot/patch
LAN->>Phone: GUI hook over WebSocket
Phone->>Phone: validate epoch + baseRevision
alt continuous revision
Phone->>Phone: merge changed fields
else missing or stale revision
Phone->>GE: request full state on heartbeat
GE->>Pub: force snapshot
Pub->>Phone: new authoritative state
end
- semantic stop candidates keyed by level identifier;
- 24 recently accepted taxi stop positions;
- dynamic minimap wrapper and original settings.
M.onUpdate(dtReal, dtSim) services vehicle identity, energy, optional LAN state, and taxi gameplay while the mode is active. Vehicle Config temporarily suspends this work before BeamNG rebuilds the current vehicle VM.
-
updateActiveMode(dtSim)advances gameplay and refuses to advance timers whendtSim <= 0. -
nextOfferGuardadvances proposed-order lifetime fromdtRealbefore Vehicle Config or gameplay-phase early returns, so a modal cannot survive a paused or corrupted simulation timer. - HUD emission is throttled with
dtRealto approximately every 0.2 seconds. - With Connected Phone active, periodic updates use revisioned field-level patches; full snapshots remain available for load and recovery.
- Refueling progress uses the same configured HUD interval instead of a separate 0.1-second stream.
- Vehicle lifecycle callbacks start a 1.5-second quiet period before telemetry, cargo, energy, and identity work resume.
- BeamNG's native External UI transport owns HTTP and WebSocket traffic when its LAN listener is reachable. Otherwise the update loop pumps a bounded non-blocking byte proxy from the selected private IPv4 to the game's loopback listener.
- Fleet workers monitor independently every 250 ms with four staggered update phases; aggregate HUD data is refreshed once per second, nearby hiring candidates are cached for two seconds, and dirty fleet statistics are flushed after a five-second debounce.
The split means pause-safe gameplay with a responsive CEF interface.
The player's optional AI Driver and hired Fleet drivers share BeamNG's road graph but no longer share a supervisor instance or perception workload.
flowchart LR
Route[TaxiDriver road route] --> Choice{Vehicle role}
Choice -->|Player vehicle| Player[autopilot.lua]
Player --> NativePlayer[BeamNG ai.driveUsingPath]
NativePlayer --> PlayerGuard[100 ms traffic guard<br/>12 curved samples]
Choice -->|Hired Fleet vehicle| Worker[fleetWorker.lua]
Worker --> Native[BeamNG ai.driveUsingPath]
Worker --> FleetGuard[200 ms traffic guard<br/>6 curved samples]
Worker --> Monitor[Staggered progress monitor<br/>bounded current-segment replans]
This boundary is intentional. Both roles use native BeamNG steering, but target and traffic state remain isolated per vehicle. Fleet employees use half the player observer frequency and half the curved-path samples to keep aggregate CPU cost bounded.
The UI never mutates the Lua state directly. It calls public extension methods using bngApi.engineLua. Lua emits authoritative data through:
-
TaxiDriverHUDStatefor full snapshots; -
TaxiDriverHUDPatchfor revisioned field-level changes; -
TaxiDriverProfileData.
Every HUD stream has an epoch and revision. Clients reject stale or out-of-order patches and request a full snapshot when baseRevision does not match. The controller also normalizes Lua empty tables because they can arrive as JavaScript objects instead of arrays.
lanBridge.lua starts BeamNG's native bng-ext-app-v1 server with listen address any on TCP port 8085 and probes the selected private IPv4. If that endpoint is reachable, the native server directly serves static HTTP assets and WebSocket traffic. If BeamNG exposes only 127.0.0.1, TaxiDriver binds the selected LAN address and proxies raw bytes to loopback. Both paths retain one authoritative gameplay state and require no companion process.
autopilot.lua selects either a legal directed-edge route or the exact displayed GPS node sequence and delegates driving to BeamNG's ai.driveUsingPath. A Vehicle Lua observer adds a temporary speed limit for following and curved traffic conflicts but never writes steering input. Native Route Done is verified against the physical gameplay target and can trigger a bounded current-position replan. See AI Driver and Recovery.
BeamNG 0.38.6 can still report only 127.0.0.1 on some Windows installations. Address publication is therefore independent from the server's returned label. networkAddress.lua combines BeamNG adapter entries, the native result, a UDP route probe, Winsock hostname resolution, and the last confirmed address. It rejects loopback/APIPA/non-private values, verifies that BeamNG can bind each candidate, penalizes known virtual/VPN descriptions, and ranks the remaining interfaces.
flowchart LR
Toggle[Share enabled] --> Native[Create native server on any:8085]
Native --> Sources{Collect IPv4 candidates}
Sources --> Beam[BeamNG adapters]
Sources --> Route[Windows route socket]
Sources --> DNS[Winsock hostname resolution]
Sources --> Saved[Last confirmed address]
Beam --> Rank[Validate + bind-test + rank]
Route --> Rank
DNS --> Rank
Saved --> Rank
Rank -->|winner| Persist[Write lan.json and publish QR]
Rank -->|none| Error[Localized unavailable state + diagnostics]
The server is started only after the player enables Connected phone. Sharing is session-only and returns to off whenever the UI App or mod starts. See External Web UI.
The map is not a screenshot or duplicated HTML renderer. TaxiDriver loads ui_apps_minimap_minimap, changes it to rectangular mode while owned, and reports the phone map rectangle in normalized screen coordinates.
Five occlusion rectangles protect:
- route/arrival information;
- speed-limit sign;
- phone notifications;
- the AI control overlay;
- the fleet Active drivers overlay.
All transforms and prior minimap settings are reset when the route screen disappears.
Realistic Mode uses reversible function wrapping rather than permanently modifying BeamNG source. Restoration checks that the installed wrapper is still active before replacing it with the saved original function. This reduces interference with other extensions, although two mods wrapping the same function can still be load-order sensitive.
BeamNG's LuaJIT has a practical limit of 200 local variables in a function/chunk. Version 2.25.0 moved persistence, routing, vehicle control/history, shift accounting, and random events into focused modules. New independent configuration, pure calculations, or data pools should continue to live outside the main orchestrator.
TaxiDriver Reloaded documentation · Version 4.0.3 · BeamNG.drive 0.39
- Installation and Quick Start
- Gameplay and Ride Lifecycle
- Order Generation and Routing
- Passengers, Fares and Ratings
- Cargo Deliveries
- Realistic Refueling
- Driver Profile and Persistence
- Settings, Localization and Audio
- Navigation and Map Controls
- External Web UI
- Driver UI Design
- AI Driver Engine 0.39
- AI Driver and Recovery
- Fleet Operations
- Troubleshooting and Compatibility