Thoosie · park twin

Build the coaster twice. Once here first.

A regional park signs off on a thirty-million-dollar coaster and finds out what it did to the rest of the park after it opens. The draw is the easy part. The part nobody models is the fifteen thousand extra walking trips a day that now have to cross a midway that was already tight at four o’clock.

So model it. Below is a working twin of Kings Dominion on its real footpath network, playing a peak Saturday from opening to close. Pick a coaster a manufacturer actually sells, drop it on a plot, and watch the queues build and the walkways load.

The simulator

One park, 43 attractions, 22 food outlets, 4,290 routed walking paths

Every path on the map is a real routed walkway with a measured length and walking time, not a line between two dots. Every coaster in the picker is a model a manufacturer publishes a capacity figure for, linked to the page it came from.

Guests ride, and they also eat. Every food outlet the park lists is on the map, drawing its own trips on its own lunch curve, because a midway carries the people walking to the Firehouse BBQ as surely as the ones walking to the coaster.

Crowd Flow is the operator’s view: an arrow from every backed-up ride to the nearest one that is meaningfully emptier, drawn on the real walking path between them, colored by how bad the queue it leaves is. It is a recommendation, not a measurement. Heatmap is where the crowd physically is. The two pathway views are the capital question: which midways carry the load, and what the new coaster does to them.

Scrub the day and it all re-reads, frame by frame. Change anything on the left and the whole park re-solves.

Thoosie Thoosie Park Twin · Kings Dominion loading park network…
The new coaster

Where it goes
Attendance uplift +1.0%

Measured: +1.0%, spread +1.0 to +1.9. That is the median year-on-year gate lift at parks that opened a headliner, minus the median at parks that opened nothing that year, across 13 park-years. Parks that opened only a mid-card ride showed −0.3%: no detectable lift at all.

Season Opening · ×1.12

Measured decay, not a guess. Indexed to a ride’s own first full season across 31 headliners with an opening date and a multi-year wait history.

Click any ride or food outlet for its numbers Queuing: 0 Eating: 0 Walking: 0 Avg wait: – Hot spot: –
Simulated peak Saturday--:--
New coaster
Less
MoreFood
0
Open
0m
Avg wait
0
Hot (≥30 min)
0
Cool (≤5 min)
Riders per day—
Peak posted wait—
Share of park boardings—
Busiest walkway—

Pathways that take the load

The six walkway corridors whose peak-hour pedestrian flow rises most, in people per minute per meter of width. Color is Fruin’s walkway level of service at the width you set: free restricted at capacity.

6.0 m
CorridorBeforeAfterChange

Congestion is a width problem and centerline mapping carries no widths, so this one is a dial rather than a measurement. In a real engagement we take it off aerial imagery per segment.

Where the riders come from

A new headliner does not only add demand, it moves it, and a long queue takes the day as well as the share. Measured at today’s attendance so the gate uplift does not mask the substitution.

Attractions per guest — → — Food stops — → —
AttractionBeforeAfterChange

Kings Dominion is the park shown because it is the one with both a Google-routed walking set and an extracted footpath graph, so the graph could be scored against measured distances before anything was built on it. The walking layer itself is not unique to it: 92 parks have an extracted OSM footpath network on the same schema. A real engagement calibrates every parameter below against your gate history, your ride telemetry and your own path widths, and pre-registers the prediction so it can be scored against what actually happens.

Source discipline

What is measured, what is assumed, and what only you have

A counterfactual simulation is worth nothing if you cannot see which parts of it are load-bearing. So here is the whole ledger, including the parts that are weak.

Measured — ours or published
  • 1,892 routed walking paths between attractions, each with its own polyline, distance and walking time
  • A walkway graph built from those polylines, 392 nodes and 664 edges, which reproduces Google’s own measured distances to a median of 0.0% across 1,800 pairs. The remaining 2,398 routes, everything touching a food outlet, are solved over it
  • Walking speed of 1.249 m/s, taken as the median of distance over duration across 1,886 measured routes rather than assumed
  • 43 attraction positions to five decimal places
  • 22 food outlets with their own coordinates and the park’s own Meals or Snacks tagging, from its published dining feed. A 23rd sits 155 m off the dry-side network, on the water park boundary, and is dropped rather than dragged onto a path it does not touch
  • Manufacturer-published capacity, height, speed, length and train count for all 19 models in the picker, every one linked to the spec sheet it was read from
  • 10 attractions carry hourly capacity reconciled against the manufacturer’s own published figure or computed from train configuration, with the maker named: Intamin, B&M, RMC, Mack, PTC. Another 8 carry capacity and pull from the crowd model’s calibrated roster
  • A measured decay curve for what a new attraction is worth over time: 31 headliners with both an opening date and a multi-year posted-wait history, indexed to their own first full season
  • A measured gate effect: 921 park-years of annual attendance across 61 parks, differenced against parks that opened nothing in the same year
  • 196 rides’ measured hourly wait curves, used to calibrate the shape of the simulated day rather than to decorate it
  • This park’s own recorded annual average wait for 22 of its rides, across five to nine seasons each, shown on every marker that has one
  • The posted minimum height for 41 of the 43 attractions and which 17 of them sell a paid queue, from the park’s published ride catalog
  • Ten years of posted-wait history behind that roster, with a live tier refreshed across 139 parks
Assumed — stated, not hidden
  • The other 26 attractions get capacity, duration and pull by ride class, because the calibrated roster does not cover them. Kiddie flats sit at 320/hr, which is where two-minute cycles with loading families land
  • Each guest has 315 minutes of the day to spend queueing, riding, eating and walking between all of it. How much that buys is an output, not a setting, and it falls when queues rise. It lands near 7.2 attractions and 2.6 food stops, and the attraction figure works out at about two thirds of the park’s theoretical daily capacity, where real parks run
  • The ride arrival curve is derived from the measured wait curve rather than chosen: a queue is an integral, so the hourly arrivals that hold a given wait profile follow from it algebraically. The result is an 11% opening hour and a nearly flat 8% after, because real parks build a queue at rope drop and then hold it rather than peaking and collapsing. Food runs on its own curve, peaking hard just after noon with a dinner shoulder around six
  • How hard demand concentrates on headliners is calibrated against those 196 curves, not chosen by taste. The residual between the model’s hourly wait shape and the measured one is 0.073, against 0.50 for the hand-tuned version it replaces
  • Service rate and dwell for food are class defaults off the park’s own tagging: a meal counter clears 240 guests an hour and holds them 25 minutes, a snack stand 400 and 8. Nothing measures these. The table that would, food_queue_estimates, is empty
  • Food pull is calibrated so guests buy about two and a half times a day, roughly a meal and a snack. The resulting count is on the page so it can be argued with
  • Posted wait is the proxy for draw throughout, in the decay curve as much as in the model. A ride whose demand fell but whose park grew can hold its wait, and every park pads the number it posts
  • The day runs in 15-minute frames with each station’s queue carried between them, so waits build and drain rather than sitting at one number, and riders per day is the integral of what each station actually cleared
  • Guests pick the next attraction by pull against walking time, and tolerate a longer walk for a bigger ride: about 12 minutes for a mid-card, 18 for a headliner
  • They balk at queues, which is what holds the park in balance. The park is solved to that fixed point, with the day budget solved around it by bisection
  • Everyone enters at the gate and leaves by it, so the entry spine carries arrival and departure as well as through traffic
  • Rides run at 85% of published theoretical capacity all day. Trains dropped for staffing, which moves real capacity by a third, are invisible from outside
  • The wait a ride posts with no queue at all is a property of the ride, not a constant: roughly one dispatch cycle plus the walk through an empty switchback, so a 320/hr kiddie flat shows nine minutes where a 2,000/hr tower shows four
  • The graph is snapped to a 10-meter grid so two routes down one midway do not read as two midways. Costs 2.9% on path length; walking times come from the unsnapped originals
  • The new plot ties into the network by a straight spur to the nearest existing attraction
  • Walkway width is uniform at whatever you set it to
Yours — we cannot scrape it
  • Attendance uplift. Your gate history is the only honest source for it, which is why it is a control here and not an output
  • Measured path widths, or the aerial imagery to take them off
  • Trains in operation by day, which moves real capacity by a third and is invisible from outside
  • Fast Lane share of station throughput
  • Food, retail and per-cap yield by location
Out of scope

What this model does not contain

Shorter than the list of what it does, and more useful. Anything here is a known reason a number could be wrong, not an oversight we would rather you did not notice.

Spread across ridesPartly solved, and worth saying how. Three quarters of the model’s attractions used to sit at exactly five minutes, against 5% of 4,265 real rides. The cause was a flat five-minute floor pinning every quiet ride to the same number; making the floor a property of the ride took that to 14%, and the quartile below the median from 1.00 of it to 0.73, against a measured 0.50. The top of the distribution is still compressed: the model’s busiest rides reach 1.6 times its median where real ones reach 2.9.

Driving pull from this park’s recorded waits was tried first and reverted. It took the hourly residual from 0.073 to 0.49 and made the pinning worse, for two structural reasons: the recorded figure averages every hour of every day while the model runs one peak Saturday, and half those rides average under ten minutes where the target carries no signal. Those recorded numbers are on the markers as provenance instead.
Retail and restroomsFood is modeled; shops, restrooms and shows are not. They are real trips on real midways and their absence understates walkway load, which is why the day budget still carries an allowance for time spent off both rides and food.
Food throughputService rates are class defaults, not measurements. They are the weakest numbers in the model, and a park’s own POS data would replace them on day one of an engagement.
Height and partyEvery guest can ride everything. In a real family park a large share cannot ride the headliner at all, which flatters a new coaster’s draw and starves the kiddie rides.
DowntimeNothing breaks. We hold 1.36 million closure observations and they calibrate the engagement model, but this demo runs every ride all day.
Fast LaneNo paid queue. It takes a real share of station throughput away from standby and changes who waits.
Queue spillQueues never overflow into the walkway. When they do, they rewire the network, which is exactly where a bottleneck becomes a safety question.
Weather and seasonOne warm, dry, peak Saturday. No rain, no shoulder-season day, no event night.
Water parkSoak City is on a separate ticket and a separate path loop, so it is excluded rather than half-modeled.
The walkersThe dots moving on the map are drawn in proportion to the flow on each walkway. They are a picture of the flow field, not individual agents with itineraries, and nothing is inferred from them.
The arrowsCrowd Flow points each backed-up ride at the destination with the best ratio of walking time to queue time saved: at least eight minutes saved, at least 140 m away, never walking longer than half the wait avoided. It is a recommendation, and it assumes the recommendation is taken. Our own measurement says plain information does not move people — the substitution effect of simply publishing a shorter wait nearby is about zero, −0.006 within the hour. Treat an arrow as what it is worth paying a guest to do, not as what they do when told.

Posted waits are padded by every park that publishes them, so any throughput figure derived from them inherits that bias. We say so in the deliverable rather than in a footnote.

Why it holds up

The twin is backtestable, which is unusual

Simulation projects normally die because the customer has no ground truth to check them against. Every new coaster that opens anywhere is a natural experiment, and we hold before-and-after telemetry on both sides of a lot of them.

What we hold
  • Per-ride posted-wait history going back ten years
  • A live tier refreshed across 139 parks
  • Ride opening dates joined to manufacturer throughput
  • 1.36 million closure observations in the core sample alone
  • Closures outnumber our own collection gaps eight to one
How it gets scored
  • The predicted park-wide effect is registered before the opening
  • Then scored against what the telemetry actually did
  • Hits and misses both published
  • Same discipline as the forecast scoreboard
  • No retro-fitting a model to an opening it already saw
Where it is honestly weak
  • Counterfactuals are materially harder than forecasting
  • Within-park reliability has a measured ceiling around 0.53
  • The crowd index is not valid at Disney or Universal
  • Absolute queue minutes need calibration against your own data
  • Without measured widths, bottlenecks are ranked, not certified
The benchmark

What happens when you score it

A twin that has never been scored is an opinion with geometry. This one now has a number, and the number is not flattering, so here it is.

Twenty-two of this park’s rides have five to nine recorded seasons of annual average wait. The model is asked to reproduce them. It cannot be scored in minutes, because it runs one peak Saturday while the record averages every hour of every operating day, so it is scored on the two things that are comparable: the order it puts the rides in, and the spread it gives them relative to the park median. Any model has to beat the trivial explanations or its machinery is decoration.

PredictorRank correlationMagnitude error
Everything gets the park median0.000.51
Hourly capacity alone−0.340.81
Demand over capacity−0.130.64
The roster’s popularity weight, no simulation+0.360.51
This twin, one peak Saturday+0.220.88
This twin, over a season, before the capacity term+0.180.53
This twin, over a season, with it+0.290.56
What it says

It found one real error, and closed most of the gap

Tuning did nothing. Concentration from 1.0 to 4.8, balking from 60 to 400 minutes, a capacity derate falling with ride size, a per-ride weight fitted straight to the record: none of it moved the score.

What moved it was a structural error the benchmark exposed, described below. Fixing that took the rank correlation from 0.18 to 0.29 in sample, and from 0.17 to 0.48 on rides the fit never saw.

Held outCross-validated over four folds, fitting on three quarters of the rides and scoring only the quarter held out, the twin orders them at +0.48 against the baseline’s +0.17. It is still worse on magnitude, 0.55 against 0.43. Four folds of five or six rides is thin, and one fold is negative for both, so treat the size of the gap as unsettled and the sign as the finding.
What broke firstScoring a single deterministic peak day against an annual average over hundreds of days was never a valid comparison. Running the park across a distribution of days instead took the magnitude error from 0.81 to 0.53. The machinery that fixes it is the same machinery an error bar needs.
The error it foundCapacity is not exogenous. A park builds 1,600 an hour where demand already is, so capacity is partly a measurement of popularity, and this park’s record shows it: hourly capacity correlates positively with recorded wait. Queueing physics still has to divide demand by capacity, so with nothing to offset it the model penalised big rides twice, which is why Dominator at 1,600/hr and Pantherian at 1,350 came out near the bottom when the record puts them mid-table. Demand now carries a capacity term of its own. The first attempt failed only because it was applied before the concentration exponent and so was raised to the power of 3.2 along with everything else.
What this does not invalidateThe twin’s job is a difference: what changes when you add a ride, which corridors take the load. Shared bias cancels in a difference in a way it does not in a level. But a model that cannot reproduce the park it already has should not be believed about the park it might have, and until this number improves, the absolute wait figures on this page are a simulation output and not a forecast.
A second thing that failedScaling demand by the share of guests tall enough to ride looked obviously right, and 41 of the 43 attractions carry a posted minimum. It made the benchmark worse, 0.29 down to 0.21, and worse again at higher weights. Height is not the problem: the pull weight already embeds it, because a giga’s popularity is what it is precisely because only teens and adults ride it. Scaling by eligibility counts the same restriction twice. Left switched off, with the limits still on every marker, because the moment pull comes from something eligibility-free it becomes the right term to switch back on.
What to distrustThe capacity term’s strength is one number fitted to 22 observations at one park. Its sign and rough size are supported by the mechanism and by the held-out folds; its precise value is not. It is the first thing a second park would either confirm or kill.
A costThe hourly-shape residual rose from 0.073 to 0.16 when the capacity term went in, measured now on six rides rather than thirteen because fewer clear the ten-minute bar. Twenty-two real observations outrank six, so the cross-section won, but the trade is recorded rather than buried.
What would fix itNot another parameter. Either far more history per park, so a per-ride weight can be estimated rather than fitted to 22 points, or many parks at once, so the parameters are fitted across parks and validated out-of-park. We hold footpath networks for 92.
The engagement

What a real one looks like

Four to six weeks, one park, one capital decision. The output is a document your board can argue with, not a dashboard nobody opens.

Week 1Build your park’s network: footpath extract, widths off imagery, attraction snapping, validated against walk times you already know.
Week 2Calibrate against your telemetry and ours. Ride-level throughput, closure behavior, the demand shape of your actual season.
Weeks 3–4Run the candidate models and plots. Draw, queue, flow, bottlenecks, and the operating consequences of each.
Week 5Backtest against openings at comparable parks so the numbers arrive with an error bar rather than a flourish.
DeliverableA written decision document, the twin itself, and a pre-registered prediction you can score us on next season.
What we needGate history, ride-level ops data if you have it, and a site plan. Everything else we already hold or can extract.
Park twin

Run yours before the steel is ordered

Tell us the park and the decision on the table. You will get an honest read on what we can model from public data alone and what we would need from you.

Start a conversation
hello@luciapps.com