Alexandre Bordereau
The nine-junction grid seen from above at golden hour, streets and queues of cars between the buildings: half render, half diagnostics, cars coloured by speed and junction labels

Lab · Simulation · In progress

Trafic

A real-time microscopic traffic simulator in JavaScript, rendered with three.js. Every vehicle has its own driving model, route and junction bookings. The engine is independent of rendering and validated under Node by a twenty-scenario bench; networks are described in JSON; one vehicle can be driven.

Engine
JavaScript
Rendering
three.js r128
Bench
20 scenarios
Roadmap
28 / 50
Reading
16 min

Trafic computes every vehicle individually, at a fixed 1/30 s step, and three.js displays it in the browser. The demo network is a 3 × 3 grid of junctions; the engine also reads other networks, described in JSON.

The roadmap’s goal: approach the realism of the reference simulators (SUMO, PTV Vissim, Aimsun) while staying real-time. Development follows fifty features ordered by size and dependencies, one per commit; each is measured by a headless test bench and documented by a figure generated by the engine. This page describes the state at #28.

Log 01 / 10

Engine core

#1, 2, 3, 7 · Tier 1

Car-following model, fixed step, seeded randomness, headless test bench, spatial index.

Demo network: a 3 × 3 grid of junctions 60 m apart, one lane each way, twelve entry-exits. Every vehicle follows the IDM: its acceleration depends on the gap and relative speed to the first obstacle on its path, a vehicle, a stop line or a vehicle already in the junction. It books the junction before entering it. The simulation step is fixed and decoupled from display; at start-up, 25 s of traffic are pre-simulated.

Straight-down view of the central junction, cars coloured from red (stopped) to green (fast)
Fig. 01Top view of B2, colour = speed: red when stopped, green above 47 km/h.

Determinism: all randomness in the traffic goes through a seeded generator (mulberry32) instead of Math.random: spawns, destinations, driver parameters, colours. Same seed, same trajectories. The seed is passed in the URL (?seed=42).

Three top views of B2 at the same moment, coloured by speed: seed 1, seed 1 run again, seed 2
Fig. 02B2 after 75 s: seed 1, seed 1 run again (identical state), seed 2.

Test bench: npm run bench runs the simulation headless under Node on twenty reference scenarios, six seeds each, and compares the indicators’ means against a reference; a difference is only flagged beyond three standard errors, since the variance between seeds is 5 to 15%. An exact fingerprint of the final state validates refactors that should change nothing, bit for bit. Seed 1 runs as three simultaneous copies: fingerprints compared for determinism, best time kept for the step cost.

1/30 s
Fixed simulation step; rendering interpolates between the last two steps.
20 × 6
Reference scenarios × seeds per scenario.
0.20 ms
Cost of one step at saturation, about 170 vehicles.

Spatial index: a grid of 50 m cells rebuilt at every step (only the 3 × 3 neighbouring cells are read), then a bounding-box test on the 22 points sampled ahead of the vehicle. Both filters are exact: fingerprints unchanged. At saturation, a step goes from 0.25-0.29 ms to 0.20 ms; the gain is mainly for large networks, beyond the current 400-vehicle limit.

Log 02 / 10

Driver model

#4, 5, 15

Randomly drawn profiles, amber decision, reaction time and anticipation (HDM).

Three profiles: cautious (25%), normal (55%), hurried (20%). Each driver draws their parameters around their profile’s values, with an 8% relative standard deviation capped at ±2σ. Effect at saturation compared with identical drivers: exits −4%, average speed −6%.

ParameterCautiousNormalHurried
Max acceleration1.7 m/s²2.3 m/s²2.9 m/s²
Comfortable braking2.0 m/s²2.6 m/s²3.2 m/s²
Time headway1.1 s0.8 s0.6 s
Minimum gap2 m1.8 m1.5 m
Desired speed86% of the limit95%108%
Reaction time0.75 s0.6 s0.5 s
Lateness accepted on red0 s0.4 s1 s
Central values of each profile (config.js).
Junction A1 from above, cars coloured by driver profile
Fig. 03Colouring by profile around A1: blue cautious, grey normal, red hurried.

Dilemma zone: when the amber comes on, each driver draws their decision once, from their time to the line, on a logistic curve fitted to Zegeer and Deen (1978): 10% stop at 2.5 s and 90% at 5.5 s for a normal driver, shifted by ±0.5 s depending on the profile. They go if stopping requires more than 4.5 m/s², and give up if they cannot cross the line before their accepted lateness on red runs out. Measured: 0.5 to 0.6% of crossings during the all-red.

Probability of stopping on amber against the time to the line, three S-curves for the three profiles
Fig. 04Probability of stopping against the time to the line, by profile.

Human Driver Model, on by default: each driver applies the decision taken one reaction time earlier (0.5 to 0.75 s), anticipating their position when it takes effect; they estimate distances to ±10% and the closing speed with an error correlated over 20 s; they react to the most constraining of the vehicles visible ahead. Anticipation starts from the accelerations already decided, not from a constant speed: 1 to 2‰ of harsh braking. Parameters were refitted to keep a saturation flow of 1,803 ± 34 veh/h. A box in the panel switches back to the plain IDM.

Two space-time diagrams of street 2, IDM alone at the top and HDM at the bottom
Fig. 05Space-time diagrams of street 2, same signals, same seed: IDM alone at the top, HDM at the bottom. With reaction time, queues restart more slowly and the entry queue before A2 no longer clears.
At ground level on avenue B, a queue of cars waits at the red light of junction B2
Fig. 06Avenue B, queue at the B2 red light; brake lights on when braking.

Log 03 / 10

Junctions and signals

#10, 11, 19, 20 · Tier 2

Five junction regimes, gap acceptance, three signal controls.

RegimeRule
Traffic signalsGreen, 3 s amber, 1.5 s all-red, alternating between the east-west and north-south axes.
All-way stopFull stop required, then first come, first served.
Stop on the minor roadStop, then wait for a big enough gap in the major road’s traffic.
YieldApproach at 16 km/h, pull in if the gap is enough.
Priority to the rightEveryone gives way to the vehicle coming from their right.
Available regimes, chosen per junction. Signs and markings follow the regime.

Gap acceptance: a driver who has to give way estimates the arrival of the next priority vehicle whose path crosses or merges with theirs, up to two segments upstream and assuming firm acceleration. They only pull in if the gap exceeds the HCM critical gap: from the minor road, 6.2 s right, 6.5 s straight, 7.1 s left; from the major road, 4.1 s left; all × √(T / 1.1) according to their time headway T. Conflicts are computed on the turning curves.

Junction A2 as a yield junction seen from avenue A: triangular signs, dashed lines, a queue on the minor road
Fig. 07A2 as a yield junction: avenue A, the minor road, waits for a gap in the traffic on street 2.

Actuated signals: detection over the 35 m upstream of the stop lines, phase call by a vehicle on red, 6 s minimum green, extended while vehicles keep arriving, ended after 2 s without an arrival or 30 s after the opposing call. At equal demand against the fixed-time green wave: waiting −7%, exits +4%.

The city with actuated signals, junction labels shown
Fig. 08Actuated signals, 70 veh/min. Labels: signal state, queue, delay, red-light crossings.

Webster coordination: every 5 min, a common cycle C₀ = (1.5 L + 5) / (1 − Y) computed from the loop flows, with a lost time L of 6 s per phase and a cycle bounded between 30 and 120 s; greens shared by load; offsets of the form a·column + b·row, chosen to maximise the total width of the green bands at 40 km/h in both directions. On this grid (60 m blocks, cycle of about 40 s), the optimum is a wave in one direction per axis. At 70 veh/min: control delay of 27.0 s against 28.4 s for the fixed-cycle green wave, CO₂ −4.5%.

Space-time diagram of street 2 with the Webster plan: signals at A2, B2 and C2, green band eastbound, trajectories both ways
Fig. 09Webster plan on street 2: a 15 s green band per cycle eastbound, none westbound.

Max-pressure: a phase’s pressure is the sum, over its requested movements, of the waiting vehicles minus the queue on their exit. A decision every 2 s, after a 12 s minimum green; the opposing phase takes green if its pressure exceeds the current phase’s by at least 3 vehicles. A lower threshold (6 s minimum green, switching at the slightest difference) costs more in phase changes than it gains: 39.5 s delay.

Control delay and exits per minute for four signal controls, with error bars
Fig. 10Four controls at equal demand (70 veh/min, six seeds, ± 2 standard errors).

Log 04 / 10

Instrumentation

#13, 14

Vehicle inspector, heat map, sensors, levels of service, calibration.

Inspector: clicking a vehicle opens its sheet, with driver profile and parameters, trip, planned route (drawn on the ground), intention and booking at the next junction or the reason it is waiting, the IDM acceleration terms and their cause, emissions. Heat map: each lane’s mean speed relative to its limit, over a sliding 20 s. The ?debug URL exposes the full state in the console.

The inspector open on a vehicle, with the heat map: lanes tinted from red to green by speed
Fig. 11Inspector and heat map.

Sensors: a virtual counting loop in the middle of each lane (flow, occupancy, speed, aggregated per minute); control delay per vehicle and per junction, converted into a level of service A to F at HCM thresholds; saturation flow measured at signals from the 5th vehicle in a queue; flow-density diagram.

Calibration: the first measurement gave 1,250 veh/h per lane, against 1,800 to 1,900 observed in cities. Fixes: gap to the vehicle ahead underestimated by 0.7 m, junction anti-blocking rule too strict, IDM parameters brought back into the ranges published for urban driving. Side effect: waiting per trip −30 to −38%.

1,250
Veh/h per lane, saturation flow before calibration.
1,824
Veh/h per lane after calibration (± 49), cars only.
1,640
Veh/h per lane with 7% trucks and buses, consistent with the HCM correction.
The measurements panel: saturation flow, control delay and level of service for the nine junctions, flow-density diagram
Fig. 12Measurements panel at 110 veh/min on a green wave: saturation flow, levels of service D to F, flow-density diagram.

Log 05 / 10

Demand and fleet

#8, 9, 12, 18

Origin-destination matrix, shortest path, five vehicle types, emissions.

Routes: each vehicle gets a destination on entry, drawn from an origin-destination matrix, and takes the fastest path, in time at the speed limit plus 3 s per right turn and 8 s per left turn; random choice between paths within 1 s of the best. Resulting split: 58% straight, 22% right, 20% left. Accelerated-day mode (1 min = 1 h): peaks at 8 am and 5 pm, destinations leaning east in the morning and west in the evening.

A vehicle’s planned route drawn on the ground, with its sheet
Fig. 13Planned route of vehicle no. 62, drawn on the ground: right at A3, right at B3, exit south.

Fleet: cars 80%, vans 8%, trucks 4% (10 m), buses 3% (12 m), two-wheelers 5%. Each type has its own size, acceleration, braking, critical gap (+1 s for heavy vehicles) and emission class; the single length constant is gone from the engine. A heavy vehicle keeps its junction booking until its rear has left it. Validation: no gridlock over six seeds at 70, 110 and 140 veh/min; saturation flow of 1,643 veh/h on the green wave.

At the B2 signal: a bus, a truck, vans, cars and a two-wheeler
Fig. 14Fleet at the B2 signal (share of heavy vehicles forced for the picture).

Emissions: CO₂, NOx and fuel computed at every step from speed and acceleration, with SUMO’s HBEFA3 coefficients and fuel cut-off when decelerating. Check at a steady 50 km/h: 168 g/km of CO₂ and 7.2 L/100 km (Euro 4 petrol). On the grid, averages (500 to 1,400 g/km) are dominated by idling; they are used to compare settings. For example, 30 zones on the outer axes: average speed −3%, trips +3%, CO₂ per kilometre −7%.

Avenue A as a 30 zone around A2, “30” painted on the road
Fig. 1530 zone on avenue A, marked at the start of each segment; street 2, central, stays at 50.

Log 06 / 10

Drivable vehicle

#16, 17, 22, 23

Bicycle dynamics, collisions, traffic rules, GPS and missions.

Dynamics: bicycle model with tyre grip; 1,300 kg, 2.6 m wheelbase, 75 kW, front-wheel drive; 0 to 100 km/h in 8.4 s, 50 to 0 km/h in 11 m; loss of grip when braking or accelerating in a bend. Keyboard or gamepad; chase, cockpit and free cameras.

Collisions: vehicles approximated by three circles along their axis, buildings by their boxes. Penetration resolved, then a rigid-body impulse: bounce, rotation depending on the point of impact, sliding along walls (friction 0.2). An AI vehicle that is hit absorbs the shock along its path and stops.

Driving the orange car, chase camera, behind a truck on street 2 at golden hour
Fig. 16Chase camera, street 2.

Traffic rules: 12-point licence, ANTAI scale. The player’s free position is attached at every step to the segment whose carriageway contains it and whose direction matches its heading (map matching); that segment gives the limit, the next junction and its regime. Line crossings are detected between two steps on the position of the vehicle’s front; speed is checked continuously, in whole km/h, with a 5 km/h margin deducted.

OffenceDetectionPoints
Red lightThe front crosses the line on red.4
Avoidable amberWhen it came on, required braking v² / 2d below 4.5 m/s².4
Rolled stopNo full stop (< 1 km/h) within the last 15 metres.4
Failure to give wayPriority vehicle less than 3 s from the line, or already in the junction.4
SpeedingRecorded speed = measured − 5 km/h, at the peak of the excess.0 to 6
Offences detected. Fine: €135, €1,500 beyond 50 km/h over the limit.
Two offences seen from the chase camera: a red light run at B2, a failure to give way at A2
Fig. 17Red light at B2 (red for 3.2 s, 54 km/h); failure to give way at A2 (priority vehicle 0.9 s from the line).
Record of the test drive: speed along street 1 with the limit and the speed camera margin, offences marked, and licence points falling from 12 to 2
Fig. 18Scripted drive along street 1 with no traffic: speed, offences detected and points balance.

GPS: a graph whose nodes are the segments and whose edges are the allowed movements (no U-turns), with the same costs as the AI routes. The time remaining to the destination is computed for every segment, backwards (Bellman-Ford, a few passes over 48 segments); at each junction, guidance takes the branch that minimises turn + time remaining. A deviation from the route therefore needs no recomputation. The displayed ribbon is updated on segment changes and four times per second.

Missions: trip, delivery, time trial. Stops are drawn from a separate random stream, with no effect on traffic; a stop is validated within 6 m, below 1 m/s for 1 s; time trials are judged at 1, 1.2 and 1.5 times the estimated time, with a 10 s penalty per offence.

Map of the times remaining to the parcel: each arrow coloured by the time that would remain from it, the chosen route in orange
Fig. 19Time remaining per segment to the parcel; decision at C2: right, 3 + 11 = 14 s, against 21 s straight on.
Driving with the GPS: the blue ribbon of the route turns right at C2, then the orange column of the parcel to pick up
Fig. 20Guidance: route ribbon on the ground, column for the next stop, next turn announced.

Log 07 / 10

Disruptions

#21, 24, 25

Distraction and fender benders, weather and visibility, scheduled events.

Distraction (optional): inattention episodes while driving (one every 40 s on average, × 0.6 for a cautious driver, × 1.5 for a hurried one; lognormal duration, median 1.1 s, at most 4 s) and while stopped (after 2 s of waiting, one every 12 s, median 2.5 s, foot on the brake). During an episode, perception is frozen. The return to the road is triggered by a time-to-collision below a threshold with a 1.8 s median or by the vehicle ahead pulling away (4 m), then the reaction time applies.

Fender bender: contact at 1 m/s or more on the same segment. Both vehicles stop with hazard lights on for the duration of the accident report (median 2 min 30 s, 1 to 6 min) and block the lane; the queue upstream triggers route changes at the previous junctions.

A fender bender on street 1: two cars stopped, hazard lights on, the queue behind, and the inspector open on the car at fault
Fig. 21Fender bender on street 1 (no. 272 into no. 254, 7 km/h), inspector open on the vehicle at fault.
1.49 → 1.92 s
Queue-head start-up, without then with distraction.
16.8 → 19.9 s
Mean control delay.
≈ 3 / h
Fender benders, deliberately above reality. Option off: bench identical bit for bit.
Overhead view with the heat map: the lanes turn red around the fender benders
Fig. 22Heat map during two fender benders: blocked lanes and feeding lanes in red.

Weather: rain, fog and night act on every driver’s parameters, on top of their profile. Rain: grip × 0.7, speeds × 0.92, gaps × 1.15, acceleration × 0.9, comfortable braking × 0.85. Fog: 30 m visibility. Night: 80 m visibility. Grip bounds every braking (emergency, dilemma zone, player vehicle), and the desired speed is capped so the driver can stop within the visibility: Tr·v + v² / 2b ≤ visibility, i.e. 40 km/h at most in fog. In fair weather by day, every factor is 1 and the bench is unchanged bit for bit.

Stopping distance against speed, dry and wet, comfortable and emergency braking, with the fog and night visibilities
Fig. 23Stopping distance against speed, dry and wet, with night and fog visibilities.
The same avenue in the rain, drops and low sky, then in fog
Fig. 24Avenue B, rain and fog; fog is rendered at the drivers’ visibility distance. On the bench, only rain clearly degrades: delay +14%, harsh braking +20%.

Events: roadworks (20 km/h over 32 m), closure and accident, scheduled per segment with a start time and duration. Each event changes the segment’s cost in the route computation shared with the GPS: infinite for a closure, the time lost for roadworks, a 90 s penalty for an accident. At every event start and end, the remaining times are recomputed; drivers who have not yet booked their next junction choose their branch again, and those whose exit becomes unreachable change it. Traffic diversions follow from these costs alone.

Three views of the same moment: roadwork cones on street 2, the barrier on avenue B after B1, crashed vehicles on street 3
Fig. 25The scenario’s three events: roadworks on street 2, closure on avenue B, accident on street 3.
Two flow maps, before and during the events: avenue B emptied, avenue C reinforced
Fig. 26Flows per segment before and during the events: avenue B southbound 2.8 → 0 entries/min, avenue C 3.2 → 5.8.
Vehicles in the city minute by minute, with and without events, at 40 and 50 vehicles per minute
Fig. 27Network load during the scenario: at 40 veh/min, back to the initial level; at 50 veh/min, close to capacity, 138 vehicles at the end against 108 without events.

Log 08 / 10

Architecture and data

#26, 27, 28

Engine without global state, versioned JSON formats, curved segments.

The engine (src/sim/) is pure JavaScript, with no three.js and no DOM: it runs under Node for the bench and the figures, and in the browser for the app. Its state lives in a world object created by createWorld(): settings, network, traffic, sensors, signal coordination, events, weather. Modules are factories that receive a world and read its parts under their usual names; the functions’ code did not change. Rendering and UI read the app’s world through src/world.js. The refactor keeps the fingerprints of the 18 scenarios and the figures byte for byte.

Before/after diagram: six modules with their own state on one side, a world object and its parts on the other
Fig. 28Before: one state per module, created on import. After: one world per instance.
Vehicles in the city for three worlds stepping together: signalised axes, all signals, all stops
Fig. 29Three worlds with different settings in one loop; a fourth, twin of the first, stays identical at every one of the 18,000 steps.

Network format: a JSON file of nodes (position in metres; regime and priority axis for a junction, nothing for an end point) and streets (name, speed limit, sequence of nodes). The engine derives the segments (one per direction, shortened by 6 m for the stop line), turning curves, entries, exits and remaining-time tables. The scenario format adds settings, signal plans, entry and exit weights, and events. The loader reproduces the creation order of the old hard-coded grid: same numbering, same draws, identical fingerprints.

JSONdatas/scenarios/boulevard-onde.json, excerpt
{
  "format": "trafic-scenario",
  "version": 1,
  "network": "boulevard",
  "settings": { "preset": "mixed", "control": "fixed", "coord": "plan", "rate": 24 },
  "plans": {
    "J1": { "green": [35, 16], "offset": 0 },
    "J2": { "green": [35, 16], "offset": 5 },
    "J3": { "green": [35, 16], "offset": 10 },
    "J4": { "green": [35, 16], "offset": 15 }
  },
  "demand": { "entries": { "O": 4, "E": 4 }, "exits": { "O": 8, "E": 8 } }
}

Test network: a 252 m east-west boulevard with four signals, plan offset in 5 s steps (wave at 43 km/h). Eastbound, a 36 s green band per cycle and 42% of trips without a stop; westbound, 6 s and 5%.

Space-time diagram of the boulevard both ways: eastbound, a wide green band; westbound, a narrow band and stops at almost every signal
Fig. 30The file’s signal plan applied as is, trajectories computed by the engine.

Validation: both formats are versioned; npm run datas checks a file before anything is built and lists all its errors, one per mistake, including what the engine version cannot drive yet.

Outputnpm run datas on an invalid network (excerpt; the checker reports in French)
✗ casse.json
  Réseau « Réseau cassé » : 9 erreurs
    - rue « rue haute » : nœud inconnu « X9 »
    - rue « rue basse » : vitesse limite 200 hors de 10 à 130 km/h
    - rue « rue basse », de J1 à J2 : ce tronçon existe déjà
    - rue « impasse », de J1 à J3 : 8 m entre lignes d’arrêt, il en faut au moins 20
    - il faut au moins deux extrémités, pour entrer et sortir (1 trouvée)

Curved segments (format v2): shape points, joined by circular arcs tangent to both stretches, with the given radius. Vehicles are still located by their arc length s: distances, queues, loops and roadwork zones are unchanged, only the s → position conversion changes (inverse accurate to 3 × 10⁻¹⁴ m, used for the player’s vehicle). The twenty or so reads of “segment direction” now distinguish arrival and departure direction. Comfort speed √(2.5 R), targeted 1 s before the bend to make up for the IDM’s lag in reaching its desired speed; time lost in bends goes into route costs and out of control delay.

The park road between J1 and J2: file segments dashed, eastbound lane in blue straights and orange arcs, marked every 25 m
Fig. 31Park road (parc.json): file segments, straights and tangent arcs, arc length.
Speed along the park road eastbound, by driver profile: each curve dips before every bend and climbs back after
Fig. 32Simulated speeds by profile. 18 m bend: 21, 23 and 26 km/h for a theoretical 20.9, 23.1 and 26.3 km/h.

Log 09 / 10

Rendering

#3, 6 · Asphalt

three.js r128: interpolation, vehicle lights, procedural asphalt.

Rendering reads the simulation state without modifying it. Vehicles as InstancedMesh; position and heading interpolated between the last two steps, with one step (33 ms) of latency, for smooth motion at 60 Hz and above. Brake lights when braking, indicators 40 m before the turn (intention carried by the simulation), hazard lights; at night, headlights with a beam on the ground, side lights and halos at metric scale. Building shadows fall on the vehicles.

Left, B2 by day with a car indicating before it turns; right, the same street at night, headlights on
Fig. 33Indicator before a turn at B2; the same street at night, headlights on.
At night, avenue B through a telephoto lens: traffic lights and brake lights in the dark
Fig. 34Avenue B at night, dark theme.

Asphalt: the ground is a 2,048 px canvas texture for 256 m (8 px/m, 28 px per lane), not enough at eye level; the grain of asphalt would need 256 px/m. A 4 m tile (1,024 px) repeated 64 times in each direction provides that grain. It comes from a procedural MaterialCraft graph (binder, 1 to 2 cm chippings, larger stones, undulation and wear), periodic by construction: every generator has a whole-number scale over the tile. It contains no identifiable pattern, so the repetition does not show.

The asphalt tile, colour: dark grey speckled with lighter chippingsFig. 35 · basecolor
The same tile, normal map: the relief of the chippings in blue, pink and greenFig. 36 · normal

4 m tile, colour and normals, exported from the graph (asphalte.mcraft, 2 kB).

Ground shader: asphalt is only applied to bare road surface, detected by the distance to its colour in the canvas (blended between 0.03 and 0.08), so markings stay intact. The tile modulates the colour instead of replacing it: colour × tile / tile average, the average being read from the last mipmap level; from a distance, the original tint is preserved. The normal map is read in tile coordinates by replacing three.js’s normal_fragment_maps block, with a console warning if the targeted block changes. The ground moves from Lambert (per-vertex lighting) to Phong without specular (per-pixel lighting). Cost: three extra texture reads per ground pixel.

The same view, at eye level on avenue A facing junction A2: left without asphalt, a flat road; right with it, the grain and relief of the chippings
Fig. 37Avenue A at eye level, without then with asphalt. Markings are still those of the canvas.
Telephoto view down street 2, low sun in the haze, queues of cars and signals in a row
Fig. 38Street 2 through a telephoto lens, golden hour.

Log 10 / 10

Roadmap

In progress · 28 of 50

28 of 50 features done; tier 1 complete, tier 2 up to #28.

Fifty features in four tiers, ranked by size (S to XL) then by value, with dependencies respected. The app reads ROADMAP.md and shows progress on its #roadmap page: done, in progress, ready to start.

The prototype’s Roadmap page: progress counters, progress bar and the list of upcoming features
Fig. 39Tracking page: 28 of 50 done, 8 ready to start.

Rest of tier 2: recording and replay from the seed and inputs (#29), state in typed arrays read without copying by the renderer (#30), simulation in a Web Worker (#31). Main tier 3 projects:

  1. 01

    #32 Conflict zones

    Conflict points per pair of paths; booking only the points crossed instead of the whole junction.

  2. 02

    #33 Player in traffic

    The AI drivers perceive the player’s vehicle, its indicators and merges; the player books junctions like they do.

  3. 03

    #34–37 Multiple lanes

    Several lanes each way with allowed movements, MOBIL lane changes, positioning ahead of time for the route, merges and zipper merging.

  4. 04

    #38 Calibration

    Fitting to real counts and travel times, comparison with SUMO on the same scenarios.

Then: junctions with any number of arms at any angle, multi-phase signal plans (NEMA), dynamic assignment to Wardrop equilibrium, steering kinematics for the AI, parking, public transport, cyclists, a network editor, roundabouts, emergency vehicles. Tier 4: OpenStreetMap import (an extract of about 1.65 × 1 km near Nagoya is already in the repository) and pedestrians following a social force model (Helbing and Molnár, 1995).

Project
Personal, in progress
Version
Prototype 0.1, #28, 5 November 2026
Models
IDM · HDM · HCM · Webster · Max-pressure · HBEFA3
Emissions
HBEFA3 coefficients from SUMO (© DLR, EPL 2.0)
  • JavaScript
  • three.js r128
  • GLSL
  • Vite
  • Node
  • playwright-core
  • SVG
  • JSON
  • MaterialCraft