Remaster: cel-shaded skin, a crowd that tracks trade, and a funk band
Two skins over one game. 1979 is the machine as it was; the remaster is the same rules in cel-shaded vector art with a modern palette. The simulation is untouched - only the paint differs - and the toggle sits under the set. The street is now driven by the game. Before prices are in, the number of people walking on comes from the forecast; afterwards it comes from the glasses that actually sold, so the report shows the crowd you earned. A heat wave has them fanning themselves; a downpour leaves one figure hurrying past under an umbrella. Selling no longer snaps straight to the books. The stand trades for a few seconds first, tally climbing and till filling, which is where that crowd animation pays off. Skippable. The synth grew a kit (pitched-sine kick, snare with body, hats), a sweeping resonant lowpass for the bass, chords and a shuffle - enough for a funk band. The chiptunes stay for the 1979 skin. Boot is now a cassette load, which doubles as the gesture browsers require before audio will play. Fixes found on the way: the picture scaled about its centre while flex auto-margins collapsed to zero on overflow, which pushed the report's buttons off the bottom; and the validation line moved the button when it appeared, so it is now reserved and faded. Sibling tabs in one browser also keep their score tables in step.
This commit is contained in:
@@ -3,9 +3,14 @@
|
||||
A browser recreation of the Atari 8-bit BASIC classic — the one you typed in,
|
||||
ran on a TV, and lost two dollars to on a cloudy day.
|
||||
|
||||
React + TypeScript + Vite. No art assets and no audio files: the weather is
|
||||
drawn as pixel rectangles in SVG, and the music is generated by a small
|
||||
chiptune engine built on the Web Audio API.
|
||||
It ships in two skins over one game. **1979** is the machine as it was: Atari
|
||||
blue, block letters, scanlines, chiptune. **Remaster** is the same rules with
|
||||
cel-shaded art, a crowd that turns up in proportion to trade, and a funk band.
|
||||
The rules never differ between them — only the paint. Switch any time with the
|
||||
button under the set.
|
||||
|
||||
React + TypeScript + Vite, and not one binary asset: every pixel is SVG drawn
|
||||
in code and every note is generated by a small synth on the Web Audio API.
|
||||
|
||||
## Playing
|
||||
|
||||
@@ -14,6 +19,11 @@ npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
It loads from cassette first, because that is how it arrived. Pressing PLAY on
|
||||
the recorder is also what unlocks the audio — browsers want a gesture before
|
||||
they will make a sound, and that happens to be exactly the gesture the game
|
||||
already wanted.
|
||||
|
||||
One to four players share the keyboard, hot-seat style. Each morning you see
|
||||
the weather, then decide three things: how many glasses to make, how many
|
||||
15-cent signs to put up, and what to charge. Then the town votes with its
|
||||
@@ -31,6 +41,10 @@ pocket money.
|
||||
- Signs work, but with sharp diminishing returns — the fourth one barely
|
||||
earns its 15 cents.
|
||||
|
||||
Once the prices are in, the stand trades for a few seconds before the books
|
||||
open: the crowd arrives at the rate you actually sold, the tally climbs, and
|
||||
the till fills. It can be skipped, but the day is worth watching.
|
||||
|
||||
You are broke when you cannot afford a single glass. Otherwise the summer runs
|
||||
as long as you like; **RETIRE** closes the books and shows the standings.
|
||||
|
||||
@@ -63,9 +77,14 @@ src/
|
||||
rng.ts seeded mulberry32, so a run can be replayed
|
||||
highscores.ts the persisted table, with validation on load
|
||||
audio/
|
||||
synth.ts pulse-wave voices, noise percussion, look-ahead sequencer
|
||||
tunes.ts the title, trading and closing themes
|
||||
components/ the screens, and the CRT they are drawn on
|
||||
synth.ts pulse voices, a drum kit, filters, look-ahead sequencer
|
||||
tunes.ts the 1979 chiptunes
|
||||
funk.ts the remaster's band
|
||||
skin.ts which of the two skins is on, and where it is kept
|
||||
components/
|
||||
PixelScene the 1979 artwork, in chunky rectangles
|
||||
CelScene the remaster's artwork, and the people on the street
|
||||
Scene picks between them, so no screen needs to care
|
||||
```
|
||||
|
||||
The simulation is deliberately kept out of React: `engine.ts` takes a player, a
|
||||
@@ -88,9 +107,37 @@ is locked to 4:3 and everything inside it is sized in container units, so the
|
||||
picture stays in proportion at any size. If a page ever did come out taller
|
||||
than the tube, `Fit` scales it down rather than clipping or scrolling it.
|
||||
|
||||
### The people on the street
|
||||
|
||||
How many figures walk on is driven by trade, not decoration. Before you have
|
||||
priced anything it comes from the forecast — a hot day fills the pavement, road
|
||||
works empty it, a downpour leaves one soul hurrying past under an umbrella.
|
||||
Once the day has traded it comes from the glasses that actually crossed the
|
||||
counter, so the report shows you the crowd you earned. In a heat wave they fan
|
||||
themselves.
|
||||
|
||||
## Sound
|
||||
|
||||
Audio starts on the first click or key press, as browsers require. Two pulse
|
||||
voices, a triangle bass and filtered white noise for percussion, driven by a
|
||||
scheduler that queues notes 200 ms ahead so the music does not stutter when
|
||||
React re-renders. `MUSIC` and `SOUND` toggle independently.
|
||||
Audio starts on the first gesture, as browsers require. The 1979 skin gets the
|
||||
chiptune: two pulse voices, a triangle bass and filtered noise, with real
|
||||
Fourier-built duty cycles rather than a plain square.
|
||||
|
||||
The remaster gets a band. Same engine, more of it — a sine kick with a pitch
|
||||
envelope, a snare with body under the crack, sixteenth hats, and a sawtooth
|
||||
bass through a sweeping resonant lowpass, which is where the funk actually
|
||||
lives. Patterns are written in sixteenths with a light shuffle, and chords are
|
||||
just slash-separated notes in a step (`F4/A4/C5`).
|
||||
|
||||
Both run off one scheduler that queues notes 200 ms ahead, so the groove does
|
||||
not stutter when React re-renders. `MUSIC` and `SOUND` toggle independently.
|
||||
|
||||
## Two people, two browsers
|
||||
|
||||
There is no server and no shared state: the whole game is a static bundle and
|
||||
lives entirely in the page. Two people on two machines, two browsers, or two
|
||||
profiles are completely independent — different seeds, different weather,
|
||||
different books.
|
||||
|
||||
The one thing two tabs in the *same* browser profile share is `localStorage`,
|
||||
which holds the high score table and the skin. They stay in step: each tab
|
||||
listens for the other's writes and refreshes rather than going stale.
|
||||
|
||||
Reference in New Issue
Block a user