diff --git a/NOTICE.md b/NOTICE.md index 2d2b50a..284c08d 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -35,31 +35,30 @@ below meaningful: every note is generated by the synth in `src/audio/`. There are no imported assets of any kind. -## The one place we are standing on someone else's work +## What is and is not ours -Some **on-screen wording** is reproduced from the original from memory, because -it is the part people remember word for word: +**All of it is ours, with two narrow exceptions noted below.** -| Where | Text | -| --- | --- | -| `IntroScreen.tsx` | "HI! WELCOME TO LEMONSVILLE, CALIFORNIA!" and the paragraph after it | -| `ReportScreen.tsx` | "$$ LEMONSVILLE DAILY FINANCIAL REPORT $$" | -| `TradingScreen.tsx` | the thunderstorm message | -| `BriefingScreen.tsx` | the street-crew and heat-wave messages | +Earlier drafts of this project reproduced some of the original's on-screen +wording from memory — the welcome, the report heading, the thunderstorm and +road-works messages. That text was someone else's writing, and a project +released under a copyleft licence has no business licensing words it did not +write. Every one of those passages has since been rewritten in our own voice. +Nothing quoted remains. -Short functional labels (`GLASSES SOLD`, `WEATHER REPORT: SUNNY`) are hard to -express any other way and are not really anyone's creative property. The longer -passages are a different matter: they are someone's writing, quoted here as -homage rather than authored by us. We cannot license what we did not write, so -that wording is **not** covered by this project's licence and is used on a -fair-use/de-minimis footing. +Two things are still not original, and neither is a copyright question: -If that footing is not comfortable for a given use, the fix is small and -self-contained: rewrite those few strings in your own voice. Nothing else in -the project depends on them. +- **The setting.** The town is still Lemonsville, California. Names and short + titles are not subject to copyright, and it is kept deliberately, as the one + visible nod to where the game came from. +- **The ledger's labels.** `GLASSES SOLD`, `COST OF SIGNS`, `PROFIT` and the + rest are the only sensible words for what they label, and the order they + appear in follows from the arithmetic. There is no creative expression in + them to own. -The name *Lemonade Stand* is descriptive and is used descriptively. It is not -claimed as a mark of this project. +Everything else — the simulation, the artwork, the music, the interface and +every word on screen — was written for this project and is covered by the +licence below. ## Licence diff --git a/README.md b/README.md index 5875e36..5dbddf0 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ Affero rather than plain GPL because the leaderboard is a network service: anyone running a modified copy of it for other people has to offer them the source. Running the game on its own imposes nothing extra. -The simulation, the artwork and the music are original work. The game's *rules* -are not anyone's property, and some of the on-screen wording is quoted from the -1979 original as homage rather than authored here. [NOTICE.md](NOTICE.md) sets -out exactly what came from where, and credits the people who wrote it first. +The simulation, the artwork, the music and every word on screen are original +work — the game's *rules* are nobody's property, and nothing here is quoted +from the original. [NOTICE.md](NOTICE.md) sets out exactly what came from +where, and credits the people who wrote it first. diff --git a/src/App.css b/src/App.css index 4995296..ad0bca9 100644 --- a/src/App.css +++ b/src/App.css @@ -267,6 +267,20 @@ html[data-skin='modern'] .vignette { opacity: 0.35; } .center { text-align: center; } +/* Instructions: a named condition, then what it does to your day. */ +.intro-entry { + margin: 0 0 0.6em; + line-height: 1.4; +} + +.intro-term { + color: var(--accent); + font-weight: 700; + margin-right: 0.8ch; +} + +html[data-skin='modern'] .intro-term { font-weight: 900; } + /* Reserved space for a message that comes and goes without a jolt. */ .hint { opacity: 0; diff --git a/src/components/BriefingScreen.tsx b/src/components/BriefingScreen.tsx index 07d2cf8..8971e18 100644 --- a/src/components/BriefingScreen.tsx +++ b/src/components/BriefingScreen.tsx @@ -27,16 +27,15 @@ export function BriefingScreen({ {conditions.heatWave && ( <> - A HEAT WAVE IS PREDICTED FOR TODAY! - EVERYONE IN TOWN IS THIRSTY. + A HEAT WAVE HAS SETTLED OVER THE + TOWN. EVERY THROAT IN IT IS DRY. )} {conditions.streetCrew && ( <> - THE STREET CREWS ARE WORKING TODAY. - THERE WILL BE NO TRAFFIC ON YOUR - STREET. + THE ROAD IS DUG UP OUTSIDE. NOTHING + IS COMING DOWN YOUR STREET TODAY. )} {conditions.festival && ( diff --git a/src/components/IntroScreen.tsx b/src/components/IntroScreen.tsx index c612284..acbdd6c 100644 --- a/src/components/IntroScreen.tsx +++ b/src/components/IntroScreen.tsx @@ -1,53 +1,93 @@ import { useState } from 'react' import { Btn, Line } from './Crt' -const PAGES: string[][] = [ - [ - 'HI! WELCOME TO LEMONSVILLE, CALIFORNIA!', - '', - 'IN THIS SMALL TOWN YOU ARE IN CHARGE OF', - 'RUNNING YOUR OWN LEMONADE STAND. YOU CAN', - 'COMPETE WITH AS MANY OTHER PEOPLE AS YOU', - 'WISH, BUT HOW MUCH PROFIT YOU MAKE IS UP', - 'TO YOU. IF YOU MAKE THE MOST MONEY,', - "YOU'RE THE WINNER!", - '', - 'TO MAKE LEMONADE YOU WILL NEED LEMONS,', - 'SUGAR, ICE AND PAPER CUPS. THE COST OF A', - 'GLASS STARTS AT 2 CENTS AND CLIMBS AS', - 'THE SUMMER WEARS ON.', - ], - [ - 'EACH DAY YOU DECIDE THREE THINGS:', - '', - ' 1. HOW MANY GLASSES TO MAKE', - ' 2. HOW MANY SIGNS TO PUT UP', - ' (15 CENTS EACH)', - ' 3. WHAT TO CHARGE PER GLASS', - '', - 'SIGNS BRING CUSTOMERS, BUT THE FOURTH', - 'SIGN HELPS A LOT LESS THAN THE FIRST.', - '', - 'WATCH THE WEATHER. A HOT DAY IS WORTH', - 'MORE GLASSES AND A HIGHER PRICE. A', - 'CLOUDY DAY MIGHT TURN INTO A STORM AND', - 'RUIN EVERY GLASS YOU MADE.', - '', - 'YOU START WITH $2.00. GOOD LUCK!', - ], +/** A paragraph, optionally led by the name of the thing it describes. */ +interface Entry { + term?: string + text: string +} + +interface Page { + title: string + entries: Entry[] +} + +const PAGES: Page[] = [ + { + title: 'WELCOME TO LEMONSVILLE', + entries: [ + { + text: 'YOU HAVE A CARD TABLE, A PITCHER AND A CORNER OF THE STREET. WHAT YOU MAKE OF THEM IS ENTIRELY YOUR OWN AFFAIR.', + }, + { + text: 'LEMONS, SUGAR, ICE AND CUPS ALL COST MONEY. A GLASS STARTS AT 2 CENTS TO MAKE AND GETS DEARER AS THE SUMMER WEARS ON.', + }, + { text: 'YOU OPEN WITH $2.00 IN THE TIN. WHOEVER ENDS THE SUMMER RICHEST WINS.' }, + ], + }, + { + title: 'WHAT YOU DECIDE', + entries: [ + { text: 'EACH MORNING YOU SET THREE THINGS:' }, + { term: 'GLASSES', text: 'HOW MANY TO MAKE TODAY.' }, + { term: 'SIGNS', text: 'HOW MANY TO PUT UP, AT 15 CENTS EACH. THE FOURTH SIGN HELPS A LOT LESS THAN THE FIRST.' }, + { term: 'PRICE', text: 'WHAT TO CHARGE A GLASS. ASK TOO MUCH AND NOBODY STOPS.' }, + { + text: 'EVERY GLASS IS MADE FRESH. WHAT YOU DO NOT SELL IS POURED AWAY, SO MAKE WHAT THE DAY WILL ACTUALLY TAKE.', + }, + ], + }, + { + title: 'READ THE SKY', + entries: [ + { term: 'SUNNY', text: 'STEADY TRADE AND NO SURPRISES.' }, + { term: 'HOT AND DRY', text: 'A BIGGER CROWD, AND THEY WILL PAY MORE FOR A COLD GLASS. A HEAT WAVE IS BETTER STILL.' }, + { + term: 'CLOUDY', + text: 'FEWER BUYERS ABOUT, AND THE DAY MAY TURN INTO A THUNDERSTORM THAT RUINS EVERY GLASS YOU MADE.', + }, + { text: 'THE FORECAST COMES BEFORE YOU BUY. THE STORM DOES NOT.' }, + ], + }, + { + title: 'READ THE STREET TOO', + entries: [ + { + term: 'STREET CREWS', + text: 'THE ROAD IS DUG UP AND THE TRAFFIC GOES WITH IT. THEY OFTEN STAY A SECOND DAY.', + }, + { + term: 'SUMMER FAIR', + text: 'HALF THE TOWN COMES PAST YOUR STAND, AND THEY ARE OUT TO SPEND.', + }, + { + term: 'RIVAL STAND', + text: 'SOMEBODY SETS UP ON THE NEXT CORNER AND TAKES A SHARE OF THE STREET UNTIL THEY MOVE ON.', + }, + { text: 'ALL OF IT IS ANNOUNCED BEFORE YOU COMMIT. GOOD LUCK!' }, + ], + }, ] export function IntroScreen({ onDone }: { onDone: () => void }) { const [page, setPage] = useState(0) const last = page === PAGES.length - 1 + const { title, entries } = PAGES[page] return (
HOW TO RUN A LEMONADE STAND - {PAGES[page].map((t, i) => ( - {t} + {title} + + + {entries.map((e, i) => ( +

+ {e.term && {e.term}} + {e.text} +

))} +
{page > 0 && setPage(page - 1)}>BACK} @@ -55,7 +95,7 @@ export function IntroScreen({ onDone }: { onDone: () => void }) { {last ? 'START' : 'MORE'} - PAGE {page + 1} OF {PAGES.length} + {page + 1} OF {PAGES.length}
diff --git a/src/components/ReportScreen.tsx b/src/components/ReportScreen.tsx index 2f18869..6fdd078 100644 --- a/src/components/ReportScreen.tsx +++ b/src/components/ReportScreen.tsx @@ -51,7 +51,7 @@ export function ReportScreen({ return (
- $$ LEMONSVILLE DAILY FINANCIAL REPORT $$ + $$ THE DAY'S TAKINGS $$ - {player.name}, YOU DO NOT HAVE ENOUGH - MONEY LEFT TO STAY IN BUSINESS. + {player.name}, THERE IS NOTHING LEFT IN + THE TIN. YOUR STAND IS FINISHED. )} diff --git a/src/components/TradingScreen.tsx b/src/components/TradingScreen.tsx index ebb5343..aa0065d 100644 --- a/src/components/TradingScreen.tsx +++ b/src/components/TradingScreen.tsx @@ -65,9 +65,9 @@ export function TradingScreen({
DAY {conditions.day} IN LEMONSVILLE - A THUNDERSTORM HIT LEMONSVILLE EARLIER - TODAY, JUST AS THE STANDS WERE BEING - SET UP. EVERYTHING WAS RUINED!! + THE SKY OPENED OVER THE TOWN THIS + MORNING, RIGHT AS THE STANDS WENT UP. + NOT ONE GLASS SURVIVED IT.
diff --git a/src/game/constants.ts b/src/game/constants.ts index bd93de7..9904318 100644 --- a/src/game/constants.ts +++ b/src/game/constants.ts @@ -18,20 +18,11 @@ export function costPerGlass(day: number): number { export function costMessage(day: number): string[] | null { if (day === 1) - return [ - 'ON DAY 1 THE COST OF LEMONADE IS', - '2 CENTS PER GLASS.', - ] + return ['LEMONS ARE CHEAP THIS WEEK. A GLASS', 'COSTS YOU 2 CENTS TO MAKE.'] if (day === 3) - return [ - 'YOUR COST OF LEMONADE HAS GONE UP', - 'TO 4 CENTS PER GLASS.', - ] + return ['LEMONS HAVE GONE UP. A GLASS NOW', 'COSTS YOU 4 CENTS TO MAKE.'] if (day === 8) - return [ - 'YOUR COST OF LEMONADE HAS GONE UP', - 'TO 5 CENTS PER GLASS.', - ] + return ['LEMONS ARE DEARER AGAIN. A GLASS NOW', 'COSTS YOU 5 CENTS TO MAKE.'] return null }