Luck or Leak · Claims and Evidence← Back to the dashboard

Claims and Evidence appendix

Each claim on the dashboard, with the table and query behind it, the result, the alternative explanation we tested or considered, and its limitation. All numbers come from analysis/build_dashboard_data.py run on data release 0.9.0-draft (gaming dates Jan 1 to Jun 30, 2025). The Gilded Ace is fictional and its data is synthetic.

Shared rules for every query: only machine-days with active = true; all ratios are ratios of sums; money in dollars (cents ÷ 100); location taken from the placement at the start of each gaming day; theo = Σ bet × (1 − configured RTP).

Machines (Question 1)

C1The floor as a whole earned what the game math predicts.

Table / query
machine_day: SUM(house_win_cents) vs. SUM(theo_cents) where active.
Result
House win $23.64M vs. theo $23.55M (luck +$92.8k, +0.4%). Hold 9.50% vs. designed 9.46%.
Alternative explanation
Floor-level luck could hide machine-level problems that cancel out. We therefore tested every machine separately (C3, C4).
Limitation
One six-month period; supplied costs are partial (no rent, tax or depreciation).
See it on the dashboard →

C29 of management's 10 lowest earners sit in Back Forty, where the same games earn 30–45% less per working hour.

Table / query
machine_day + game_math + floor_locations (slot → bank → zone): SUM(theo) / SUM(available_seconds/3600) by zone × theme. Bottom 10 = lowest SUM(house_win_cents), Jan to Jun.
Result
Desert Gold: $11.10/hr in Back Forty vs. $16.06–$20.35 elsewhere. Royal Draw: $6.92 vs. $9.22–$12.20. Comet Cash: $7.86 vs. $11.98–$14.24.
Alternative explanation
Game mix: Back Forty might simply hold weaker games. Ruled out by comparing the same game across zones. Low availability: ruled out (C6).
Limitation
Machines are not randomly placed, so location is strongly associated with lower demand but not proven to cause it.
See it on the dashboard →

C3Luck explains the spread of machine results; only one machine falls outside chance.

Table / query
machine_day + game_math: luck z = (Σ house win − Σ theo) ÷ √Σ(sum_bet_squared × payout_multiplier_variance).
Result
Across 310 machines the z-scores follow a standard normal shape. 1 machine has |z| ≥ 3 (≈0.8 expected by chance). Luck simulator agrees with z for ordinary machines (e.g. M-1181: simulated p 0.012 vs. normal 0.008; M-1288 jackpot game: 0.013 vs. 0.012).
Alternative explanation
The z formula assumes a bell curve, which may fail for high-volatility games. Checked with a Monte Carlo simulator that matches each game's RTP, variance and hit rate; results agree.
Limitation
Independent spins assumed; the simulator uses a 3-point payout model, not the full paytable.
See it on the dashboard →

C4M-1158 behaves differently from its game design and should be inspected.

Table / query
machine_day for M-1158: SUM(payout_positive_spins)/SUM(paid_spins), hold by month; spec from game_math.hit_probability.
Result
Hit rate 38.57% vs. spec 31.54% over 674,454 spins (hit-rate z ≈ 124), every month. Hold 3.04% vs. designed 10%: $36.2k below theo, luck z −4.57. 0 of 1,000 simulated fair replays were as low; simulated hit rate stayed within 31.4–31.7%. Availability 99.9%.
Alternative explanation
A legitimate paytable/configuration change not reflected in game_math, a meter or data-recording error, or a very rare run of luck. Luck is effectively ruled out; the others are exactly what an inspection checks. This is not an accusation of wrongdoing.
Limitation
The data cannot show the cause; only a physical inspection can.
See it on the dashboard →

C5Two of the 10 (M-5076, M-1118) are too new to judge.

Table / query
machine_day: count of active days; theo per available hour.
Result
M-5076: 49 days; M-1118: 55 days of 181. M-1118 earns $19.28 expected per working hour, above the floor average.
Alternative explanation
New machines may have a novelty bump or a slow start; neither changes the fact that their totals reflect fewer days.
Limitation
Short history gives wider uncertainty for these two.
See it on the dashboard →

C6Downtime did not cause the bottom 10's low earnings.

Table / query
machine_day: SUM(available_seconds)/SUM(scheduled_seconds) per machine.
Result
All 10 were available more than 99.5% of scheduled time.
Alternative explanation
Short outages at peak hours could matter more than their share of time; peak-hour pricing in C8 shows the total effect is small.
Limitation
Availability is as recorded by the meters.
See it on the dashboard →

Demand (Question 2)

C7The walkway closure (Mar 3 to Apr 7) cut Back Forty foot traffic about 30%, and only about 90% returned.

Table / query
zone_traffic_hourly mapped to gaming dates via calendar_day; entries ÷ coverage minutes × 1,440 (offline hours excluded, not zero). Closure dates from floor_walkways (W-ENT-B40).
Result
Back Forty: 604 → 423 → 546 entries per working sensor-day (before / during / after). Other zones were flat or up during the closure (e.g. Center Pit 4,167 → 4,404).
Alternative explanation
Seasonality or a floor-wide slump. Ruled out for the closure window because other zones did not fall. The incomplete recovery may partly reflect the citywide June dip (other zones also dipped about 3–5%).
Limitation
Counters measure crossings, not unique people; seated players are not counted.
See it on the dashboard →

C8Sports weekends, a festival and our own tournament lifted demand 15–23%; conventions barely did.

Table / query
machine_day daily coin-in vs. the mean of the same weekday on non-event days; events for dates.
Result
Super Bowl weekend +23%, college basketball +19%, Winter Slot Tournament +18% (+$842k bet, ≈$79.6k theo), EDC +16%; NAB +6%, Locals Week +5%, CinemaCon +3%, CES +2%.
Alternative explanation
Events overlapping weekends or holidays; handled by comparing with the same weekday.
Limitation
One occurrence per event; small samples; promotion prize costs are not in the data.
See it on the dashboard →

Downtime (Question 3)

C9Downtime cost about $99k of expected earnings (0.42%); Ridgeline machines cause most of it.

Table / query
machine_hour: unavailable seconds × the machine's coin-in per available second at that local hour × its theo hold. operations (fault_repair) for fault counts.
Result
5,021 machine-hours down; $98.9k lost theo. Ridgeline $54.2k, Northwind $24.8k, Halcyon $19.9k. Ridgeline faults about 3.6× as often per machine-day as Halcyon.
Alternative explanation
Ridgeline machines could sit in busier zones (raising lost value) rather than being less reliable; the fault-rate comparison per machine-day addresses reliability directly.
Limitation
Lost play is an estimate using average hourly demand; repair parts and labour are separate costs.
See it on the dashboard →

C10Repairs wait longest when no technician is on shift.

Table / query
operations (work_started − opened) joined to shift_roster actual slot-tech headcount by gaming date and shift.
Result
Average wait 4.9 h with 0 techs, 1.8 h with 1, 0.55 h with 2. Day shift had 12 days without a tech in April and May.
Alternative explanation
Zero-tech days might coincide with other disruptions.
Limitation
Only 22 faults occurred with zero techs on shift.
See it on the dashboard →

Players and comps (Questions 4 and 5)

C11Tracked guests lost about what game math predicts, and losses are concentrated.

Table / query
player_period, summed per player over the period (players with carded coin-in > 0).
Result
96,559 players bet $163.8M, got back $148.2M; net −$15.59M vs. theo −$15.49M. 16.1% finished ahead. Top 1% carry 17.8% of losses; top 10% carry 56%. Locals: 8% of players, 57% of losses.
Alternative explanation
Uncarded guests may behave differently; carded share of coin-in is about 66%.
Limitation
Tracked (loyalty-card) play only; uncarded play is invisible at the person level.
See it on the dashboard →

C12On May 1 the points needed per comp dollar were cut about 53% in every tier.

Table / query
loyalty_ledger redeem events: SUM(−points_delta) / SUM(face_value_cents/100) by week and tier; economic cost per point before vs. after.
Result
Base 15 → 7, Gold 12 → 5.6, Platinum 9 → 4.2 points per $1. Cost per redeemed point 2.13¢ → 4.84¢ (×2.27). 156M unredeemed points: cost if all redeemed $3.34M → $7.57M. Monthly comp cost moved little ($31k → $33–34k); visits did not rise.
Alternative explanation
An intentional promotion whose visit effect may lag beyond June; this is why we propose a controlled pilot rather than reversing it outright.
Limitation
The full-redemption figure is an upper bound (only 4.4% of earned points were redeemed); balances reset each year.
See it on the dashboard →

Model

C13A weekday-plus-events forecast beats a flat-average baseline on a time-based holdout.

Table / query
property_day daily coin-in; events with announced_date ≤ forecast date. Train Jan 1 to Apr 30, test May 1 to Jun 30 (61 days). Rolling-origin backtest for Mar, Apr, May, Jun.
Result
MAE per day: flat average $218k, weekday mean $68.7k, weekday + events $46.7k, regression (weekday + events + trend) $65.6k. Chosen on Mar/Apr folds before seeing May/Jun; beats the baseline in 4 of 4 months.
Alternative explanation
May–June might be unusually regular. The four-month backtest shows the gain is consistent; in April, weekday-only edged out the event model.
Limitation
Only four months of training history; no lagged actuals (a frozen 61-day forecast cannot see them); Locals Week excluded as an input because it was announced after Apr 30.
See it on the dashboard →

Recommendation (Question 6)

C14Spend $17,500 on three targeted actions and keep $82,500.

Table / query
action_catalog: cost = qty × (unit + per-day × max(0, 30 − lead days)). Effects from C4, C7 and C12.
Result
Inspect 5 machines $6,000 (up to $5.8k recovered in July if M-1158 is fixed); Back Forty wayfinding $7,500 (≈$10.6k upside, high uncertainty); comp pilot with control group $4,000 (information). Rejected: replacing the bottom 10 ($220k purchase / $33.8k lease), extra technician, Ridgeline maintenance, promotion weekend, moves, floor-wide comp change.
Alternative explanation
A promotion weekend has the largest single upside (≈$80k theo in February) but rests on one example, has unknown prize costs and could only start July 15.
Limitation
Action costs are given; effects are estimates. Measurement plans: hit rate and luck score for M-1158; difference-in-differences on Back Forty traffic and theo per hour; treatment vs. control visits and theo per guest.
See it on the dashboard →

AI-use disclosure

Our ideas: the approach (test luck vs. location vs. leak before spending), the decision to keep most of the budget, and the user experience of explaining results to many audiences at once: the animated story intro and the Simple / Analyst views.

Where AI helped: Claude (Anthropic) helped with execution: writing the SQL and Python analysis, fitting and back-testing the forecast models, building the luck simulator and coding the dashboard.

How we verified it:

Reproduce

From the repository root: python -m pip install duckdb pandas numpy then python analysis/build_dashboard_data.py. This rewrites dashboard/data.js; open dashboard/index.html. Code: github.com/nisargsonar/dashboard-royale.