Refactor coaster to ride any time series, not just stocks - #4
Open
Jonezzyboy wants to merge 1 commit into
Open
Conversation
Adds src/series.js, a normalization layer every ride JSON passes through at load: points get a generic .value (from value or legacy close), stats are computed, altitude comes from a norm(v) scale function (log or linear, auto-detected when unspecified), and values format through a per-ride fmtValue (currency for stocks, unit prefix/suffix otherwise). Headlines/milestones attach to the nearest point by date in the engine, so raw series need no pipeline preprocessing. Engine changes: track altitude uses ride.norm/spanScore instead of hardcoded Math.log(close); HUD, minimap, menu previews and the ride-end summary use fmtValue/norm, tolerate series without dates (labels instead of year markers), and switch wording for non-currency rides; terrain seeding and signage key off ride.id. Zero/negative values are guarded throughout. Legacy stock JSON works unchanged. Feeding in a series: - ?data=<url> loads any series JSON and boards it directly - data-pipeline/series/*.json publishes via npm run data:series; the pipeline now regenerates index.json from the output files (stock entries unchanged byte-for-byte) Includes a demo ride, TOKENS: a startup's daily Claude token usage over a year, with an agent-mode liftoff, a 95% region outage (lava trench), and a prompt-caching dip. Smoke test grows a ?data= leg riding it. Closes stablyai#1 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1
The coaster engine is now data-agnostic: a ride is any time series, not just a stock chart. Existing stock rides are untouched (regenerated
index.jsoncame out byte-identical for all 14).How it works
New
src/series.jsnormalization layer. Every ride JSON — legacy stock format or the new generic format — passes throughnormalizeRide()at load, producing the one shape the engine consumes:points[].value(fromvalue, or legacyclose)norm(v) → 0..1altitude scale:logorlinear, explicit via"scale"or auto-detected (log when all values are positive and the range spans ≥4x)fmtValue()display formatting: currency for stocks,unit: { prefix, suffix }otherwise (with K/M/B abbreviation)Engine decoupling. Track altitude uses
ride.norm/spanScoreinstead of hardcodedMath.log(close); HUD, minimap, menu previews, and the ride-end summary usefmtValue/norm, tolerate series without dates (point labels instead of year markers), and switch wording for non-currency rides (TOTAL CHANGE/WORST DIPvsTOTAL RETURN/$1,000 INVESTED); terrain seeding and signage key offride.id. Drawdown embers, ATH confetti, and the lava trench all still fire — they were already value-relative.Feeding in a series
?data=<url>fetches any series JSON and boards it directly (e.g.?data=data/TOKENS.json&go=1)data-pipeline/series/and runnpm run data:series— published topublic/data/and added to the menu; the pipeline now regeneratesindex.jsonfrom output filesFormat documented in the README ("Ride any time series").
Demo ride: TOKENS
A startup's daily Claude token usage over a year (373 points, ~1.5M → ~128M tok/day): agent-mode liftoff, an HN spike, a 95% region outage that carves the lava trench and fires a "REGION OUTAGE" billboard, and a prompt-caching dip. Rides as a NIGHTMARE-rated coaster with the HUD reading "118.4M tok, +8149% since start".
Testing
test/smoke.mjsgrows a leg riding TOKENS via?data=(checks the unit renders and the cart advances); full suite passes with 15 menu cards and zero console errors🤖 Generated with Claude Code