← Back to Daily Builds

Daily build note · October 16, 2026

Bus Bunch

Put buses on a loop route, add riders and one small delay, and watch them clump into bunches on an animated ring and stringline chart — then flip on headway holding to fix it.

Civic / Data Toys Interactive demo live Static HTML/CSS/JS

What shipped

Bus Bunch is a pocket simulator for the most familiar transit complaint: nothing for 25 minutes, then three buses at once. Set the number of buses, the loop drive time, the number of stops, riders per stop per hour, boarding seconds per rider, and an opening delay on Bus 1. A deterministic 1-second simulation runs three hours of service: a bus that falls behind finds more riders waiting, its dwell grows (15 s + boarding × riders), it falls further behind, and the bus behind it — finding empty stops — catches up. An animated SVG ring shows buses and swelling stop crowds live (60× / 180× / 600×, pause, and a Poke Bus 1 +60 s button), a Marey-style stringline chart shows every bus's trip over time, and bars show which bus carried the riders. Flip headway holding on to make buses wait at four timepoints until a full scheduled headway has passed since the previous bus. Verdict chips by headway CV: EMPTY, EVEN, WOBBLY, BUNCHING, CONVOY, plus GRIDLOCK when boarding demand outruns the fleet. Copy a markdown run report with an America/Chicago timestamp. State saves under bus-bunch-v1.

How to try

  • The demo opens on Downtown loop: 6 buses, 48-minute loop, 16 stops, 45 riders/stop/hr, 4 s boarding, a 60 s opening delay → scheduled headway 10.0 min, but headway CV 0.77 (BUNCHING), a ~30-minute worst gap, and riders waiting ~57% longer than the held twin.
  • Load Hold the line (same route, holding on) and watch the stringline straighten out: CV drops to ~0.07, EVEN.
  • Sunday crosstown stays calm with light ridership; Stadium let-out and Cash fares show how heavy boarding turns a route into a CONVOY — holding helps, but can't fully fix a stadium crowd.
  • Drag Stops, Riders per stop, and Boarding time all the way up with only two buses to hit GRIDLOCK. Hit Copy report for a markdown summary you can paste into a thread.

Why this (vs neighbors)

The last stretch of builds was mostly ops calculators and scorers (Payback Clock, Cut Line, Cost of Delay, Kill Criteria). Bus Bunch is a deliberately visual, animated civic toy. Margin Math plays with election arithmetic and Walk-in Wait Board shows a queue snapshot; neither simulates a feedback loop over time. This one makes an unstable system visible — a small delay compounds on its own unless something (holding) pushes back.

Scope trim

No bus capacity, no alighting, no traffic signals or passing rules, no random arrivals, no GTFS or real route data. Every stop is identical and riders arrive as a steady trickle — enough to show the mechanism without pretending to be a planning model.

Limitations

  • Toy model, not a transit planning tool. Real routes have uneven demand, crowding limits, traffic, and operator behavior that change the numbers a lot.
  • Average wait uses Little's law on the simulated waiting crowd (after a 30-minute warmup); riders who arrive while a bus is boarding count as zero wait.
  • Holding uses the formula-based scheduled headway (drive + stops × 15 s) ÷ (buses − stops × boarding × riders/s); when that denominator is ≤ 0 the verdict is GRIDLOCK and holding is meaningless. The live-view poke doesn't change the stats — those use the opening-delay slider.

Suggested next steps

  1. Add bus capacity and a crowding chart so the leader of a bunch visibly fills up and passes riders by.
  2. Add alternative fixes — stop skipping, all-door boarding, and an extra "gap train" bus — and compare them side by side.
  3. Encode the route in a shareable URL and optionally load stop counts / drive time from a GTFS route.