Lemonade Stand: browser recreation of the Atari 8-bit BASIC game

Faithful day loop - weather report, cost of lemonade rising over the
summer, glasses/signs/price decisions, thunderstorms, heat waves and
street crews - with the $$ LEMONSVILLE DAILY FINANCIAL REPORT $$ laid
out the way it printed.

The simulation is kept out of React so a season can be run headlessly:
a careful player compounds $2.00 into roughly $22 over twelve days,
while an all-in player goes broke about seven times in ten.

Weather scenes are pixel rectangles in SVG and the music is a small
chiptune engine on the Web Audio API, so there are no binary assets.
The screen is locked to a 4:3 tube and never scrolls.
This commit is contained in:
2026-09-08 15:23:46 -07:00
commit 5f8ad511f0
32 changed files with 3913 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
import { WEATHER, costMessage } from '../game/constants'
import type { DayConditions } from '../game/types'
import { Btn, Line } from './Crt'
import { Scene } from './Scene'
export function BriefingScreen({
conditions,
onContinue,
}: {
conditions: DayConditions
onContinue: () => void
}) {
const cost = costMessage(conditions.day)
return (
<div className="stack">
<Line className="center inv-line">DAY {conditions.day} IN LEMONSVILLE</Line>
<Scene conditions={{ ...conditions, storm: false }} />
<Line className="center accent">
WEATHER REPORT: {WEATHER[conditions.weather].label}
</Line>
<Line />
{cost?.map((t, i) => (
<Line key={i}>{t}</Line>
))}
{conditions.heatWave && (
<>
<Line />
<Line className="warn">A HEAT WAVE IS PREDICTED FOR TODAY!</Line>
<Line className="warn">EVERYONE IN TOWN IS THIRSTY.</Line>
</>
)}
{conditions.streetCrew && (
<>
<Line />
<Line className="warn">THE STREET CREWS ARE WORKING TODAY.</Line>
<Line className="warn">THERE WILL BE NO TRAFFIC ON YOUR</Line>
<Line className="warn">STREET.</Line>
</>
)}
<Line />
<div className="row center">
<Btn kind="primary" onClick={onContinue}>
OPEN THE STAND
</Btn>
</div>
</div>
)
}