-
Notifications
You must be signed in to change notification settings - Fork 3
AI Driver Engine 0.39
TaxiDriver 4.0.0 RC introduces a new experimental player-vehicle AI stack for BeamNG.drive 0.39. It does not replace BeamNG's driving model. BeamNG's stock vehicle AI continues to own steering, throttle, braking, lane following, traffic lights, and ordinary obstacle avoidance; TaxiDriver adds taxi-route planning, bounded traffic supervision, physical arrival verification, and a deterministic parking hand-off.
AI Driver is disabled by default and remains experimental. Keep control of the vehicle available. Community-map graphs, unusual vehicle controllers, and traffic edge cases can still produce incorrect native-AI decisions.
For controls and the broader historical reference, see AI Driver and Recovery.
BeamNG 0.39 exposes a current asynchronous route planner, expanded stock-AI manoeuvre controls, vehicle tracking, and an official MCP server. The 4.0.0 engine is built around those facilities instead of running a second steering controller beside BeamNG.
The design has five goals:
- use the shortest legal road-graph route to the passenger, stop, destination, cargo, or fuel target;
- keep ordinary driving human-like by modifying intent and speed rather than fighting the stock steering loop;
- distinguish real collision threats from normal traffic in neighbouring or opposing lanes;
- allow passing or emergency evasion only after conservative road and traffic checks;
- keep work bounded so one taxi does not require a large per-frame CPU budget.
flowchart LR
Target["TaxiDriver target"] --> Route["0.39 async route adapter"]
Graph["BeamNG road graph"] --> Route
Route --> Native["Stock ai.driveUsingPath"]
Native --> Car["Player vehicle"]
Traffic["Up to 16 nearby vehicles"] --> Guard["Bounded safety supervisor"]
Static["Three static rays"] --> Guard
Car --> Guard
Guard --> Intent["Speed cap / native manoeuvre request"]
Intent --> Native
Native --> Done["Route Done"]
Done --> Verify{"Target physically reached?"}
Verify -->|No| Route
Verify -->|Yes| Park["Stop → P or N → parking brake → AI off"]
| Component | Responsibility |
|---|---|
aiDriverRoute.lua |
Asynchronous BeamNG route job, cancellation generations, legal target approach, bounded fallback, and safe start-path trimming |
autopilot.lua |
Session and player-vehicle ownership, route dispatch, physical completion checks, bounded retry, and parking lifecycle |
taxiDriverStockAiObserver.lua |
Lead following, collision prediction, static clearance, guarded overtaking/evasion, full-stop arrival, and drivetrain-aware parking |
aiLogger.lua |
Optional streaming route, threat, manoeuvre, drivetrain, and timing diagnostics |
The default mode asks BeamNG 0.39's gameplay/route/route service to build the route asynchronously. Starting a newer job invalidates the previous generation, so a late callback cannot replace the current trip route.
The adapter:
- accepts road graph waypoint IDs and removes coordinate-only markers that
ai.driveUsingPathcannot consume; - orients the destination edge using the target travel direction;
- protects the approach and departure suffix so the vehicle crosses the target in the legal direction;
- rejects a reverse approach through a one-way edge;
- trims at most three clearly behind start nodes, within a 30-metre prefix, while always retaining at least two nodes;
- uses a bounded synchronous graph-path fallback only when the asynchronous planner is unavailable and the graph and route distance remain below configured limits.
Strict GPS route remains available when the displayed ground-marker node order must be followed. It changes the requested road path, not BeamNG's steering decisions inside that path.
The observer evaluates vehicle motion in the taxi's forward/lateral frame. A same-direction vehicle becomes a lead only when its body overlaps the current lane corridor. The desired following distance combines:
minimum gap + speed × following time + closing-speed braking distance
Speed reductions are jerk-limited. When a hazard clears, the temporary speed cap is released progressively instead of snapping between full braking and acceleration.
Potential collisions use time to closest approach, predicted separation, vehicle dimensions, and a prediction horizon. A threat normally has to persist across three scans. An oncoming vehicle on its own side of a bend is ignored unless its centre enters the physical collision corridor; this prevents the repeated empty-road braking seen in early 0.39 test builds.
TaxiDriver can request the stock AI's passing behaviour only when every gate succeeds:
- a slower lead has remained stable long enough;
- the lead is 8–35 metres ahead and at least 3 m/s slower;
- the target is not close;
- the current edge is an explicit one-way road with at least two same-direction lanes and no opposing lane;
- the road is sufficiently straight and a nearby junction does not make the pass ambiguous;
- the passing corridor has adequate front and rear gaps and rear time-to-collision;
- static rays confirm that the passing lane is clear and inside the road boundary.
Passing is time-limited and followed by a cooldown. If lane metadata is incomplete, TaxiDriver does not attempt the pass.
Emergency lane-change evasion is considered only for a confirmed oncoming collision. The engine first calculates whether emergency braking can stop before the predicted closure. If braking is sufficient, it brakes and does not change lane.
When braking is insufficient, both candidate sides are checked against:
- road width and the current road-centre offset;
- three static-clearance rays;
- six time samples of the ego path and every tracked vehicle;
- a manoeuvre cooldown.
Only a clear candidate is sent to BeamNG's native laneChange action. If no checked corridor exists, emergency braking remains the fallback.
Route completion is never accepted from the graph callback alone. TaxiDriver verifies the physical distance to the gameplay target and replans premature Route Done events with a bounded retry count.
Arrival targets zero speed. The gameplay state uses only a 0.5 km/h wheel-speed sensor tolerance, so an automatic vehicle cannot creep through the pickup trigger. Passenger pickup is logical inside 10 metres; the walking dummy and horn sequence are no longer used.
Every terminal path uses the same parking handshake:
- retain BeamNG's native
stopsteering while applying service brake; - wait for the wheels to become stationary;
- disable native driving AI;
- select Park for an automatic or Neutral for a manual gearbox;
- apply and confirm the parking brake;
- release the temporary service-brake input only after the parked state is acknowledged.
This handshake also runs after cancellation, passenger no-show, failed pickup, return to dispatcher search, and switching the AI Driver master control off.
| Profile | Intent | Aggression | Following time | Minimum gap | Speed limits |
|---|---|---|---|---|---|
| Modest Novice | Maximum margin | 30% | 3.4 s | 7 m | Yes |
| Cautious Driver | Conservative daily use | 35% | 2.8 s | 5.5 m | Yes |
| Balanced | Average human-like target | 40% | 2.3 s | 4 m | Yes |
| Assertive | Faster response with legal speed | 50% | 1.9 s | 3.2 m | Yes |
| Mad Racer | Deliberately high-risk mode | 85% | 1.3 s | 2 m | No |
Balanced is the design baseline. Cautious is recommended when avoiding contact is more important than trip time. Mad Racer intentionally removes lane discipline and speed-limit compliance and should not be treated as a safety profile.
The supervisor is deliberately bounded:
- adaptive update interval: 50 ms during an emergency or manoeuvre, 100 ms during ordinary driving, and up to 200 ms while stationary;
- no more than 16 nearby vehicles in the sorted working set;
- static clearance scans at 200 ms rather than every graphics frame;
- three static rays and six dynamic samples for a candidate emergency corridor;
- asynchronous route calculation when BeamNG exposes it;
- no custom free-space planner or competing per-frame steering controller.
AI debug state includes average and 95th-percentile update time so performance regressions can be diagnosed from a live session.
Enable AI trip debug log to write the streaming taxidriver_ailog_*.jsonl journal. It includes route source and revision, traffic candidates, TTC/closest-approach values, selected manoeuvre, speed caps, parking state, drivetrain data, and supervisor timing.
The official BeamNG 0.39 MCP server was used to reset vehicles, start controlled test runs, inspect live UI and vehicle state, and read logs without a manual iteration between every change. TaxiDriver thanks the BeamNG developers for providing this integration; it enabled rapid AI-assisted regression testing while the final behavior remained subject to in-game validation.
- The engine cannot repair missing or incorrect road/lane metadata supplied by a map.
- Stock AI still makes the final steering and traffic-light decisions.
- Parked or unusual objects that are absent from BeamNG's tracked vehicle data may be visible only to native avoidance or the short static rays.
- A safe overtake is intentionally unavailable when lane direction is ambiguous.
- Evasion is conservative; it will brake when a side corridor cannot be proven clear.
- Vehicle-specific gearbox controllers may require additional compatibility work during the RC period.
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