Fuel
Each race the race server judges costs 1 fuel. The tank holds 10 and one point comes back every 6 minutes. Fuel replaced interstitial ads: the rewarded fuel ad is now the game’s main ad. The design is in docs/2026-11-08-progression-design.md; the numbers are estimates to tune after playtesting.
What costs fuel
Section titled “What costs fuel”| Race | Cost |
|---|---|
| Career event (any mode, wagers included) | 1 |
| Boss fight, best of 3 | 1 for the fight, paid on round 1 |
| Tournament | 1 for the whole bracket, paid on round 1 |
| Quick race | 1 |
| Results’ Retry | 1, it is a new race |
| Flashback (story tutorial) | free, the server does not judge it |
| Online heat | free for now |
A series costs once so a 3-round boss fight is not three times the price of an event. “Keep rounds won” after a lost boss fight re-races the decider as a later round, so it costs no fuel either.
The rules
Section titled “The rules”player/fuel/fuel.ts holds them, with no Phaser, so the server and the game run the same code. The tank is GarageState.fuel: an amount at a time since (milliseconds, the server’s clock). Nothing ticks: readFuel(tank, now) adds one point per FUEL_REGEN_MS passed since since, up to FUEL_MAX, and says how long the next point takes. A save without a tank reads as full.
spendFuelfolds the regen into the amount, keeps the part-earned point insinceand takes 1. At 0 it refuses withNO_FUEL.applyFuelAdaddsFUEL_PER_AD(2), never past the top, at mostFUEL_ADS_PER_DAY(3) per UTC day. The count and date live in the tank. A full tank refuses the ad.fillFuelfills the tank.addXp(player/level/xp.ts) calls it when the XP crosses a level, and thegoldFuelgarage action calls it for 30 gold (see Gold).
tests/fuel.test.ts covers regen, the cap, spending at 0, the ad cap and the level-up fill.
On the race server
Section titled “On the race server”startinparty/src/api/raceApi.tsspends the fuel when it hands out a ticket (party/src/race/raceFuel.ts), before it enters a series, so a refusal leaves a running boss fight alone. The answer carries the garage, so the game shows the new amount at once.- The fuel ad is the
fuelAdgarage action. Like the daily bonus it is an ad reward (AD_REWARDSinparty/src/api/garageApi.ts): it spends one ad credit that AdMob’s server-side verification gave the account, so a client cannot claim an ad it did not watch. - The game cannot set its own fuel:
fuelis not one of the fields its sync sends (player/garageSync.ts). Moving the phone’s clock changes what the top bar shows, never what the server spends.
In the game
Section titled “In the game”- Top bar (
menu/topBar/fuelGauge.ts): a can,7/10and the wait for the next point, refreshed each second from the local garage copy and the phone’s clock. - Fuel guard (
ui/fuelGuard.ts):whenFuelledruns before every way into a race that costs fuel (career event, boss, quick race, Results’ Retry), after the blown-engine guard. With an empty tank it opens a dialog with the wait, plus “Watch an ad” for +2 while a rewarded ad is loaded and the day’s 3 are not used up. With at least 30 gold it also offers “Fill the tank” for gold. A paid ad or a bought tank starts the race at once. - Gold: tapping the fuel or the gold in the top bar opens the gold dialog, which also fills the tank (see Gold). Its gold ad counts apart from the 3 fuel ads.
Not built yet
Section titled “Not built yet”- When the phone’s clock is ahead of the server, the top bar can show fuel the server does not have; the server refuses the ticket and the race runs unjudged, like any race without a ticket.