aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2026-04-22Load the content manifest and cache every chunk to IndexedDB on initial loadHEADmainBobby5-7/+88
2026-04-22Revise the Mirror Coast sample toward observation over editorial summaryBobby3-7/+7
2026-04-22Scrub Earth references and real-world dates from the Mirror Coast sample contentBobby4-4/+4
2026-04-22Add the content pipeline and the Mirror Coast region as the first authored ↵Bobby14-22/+857
sample
2026-04-22Revert the worldgen stub pending the full pipeline and authored region contentBobby3-130/+1
2026-04-22Generate a fresh year-1111 world on Begin and persist it to the user-data ↵Bobby3-1/+130
database
2026-04-22Wire the begin-state detector through Dexie via world and people repositoriesBobby4-5/+71
2026-04-22Co-locate AudioPlayer and TextSizeChoice with their stores and move version ↵Bobby9-6/+5
and credits to their new homes
2026-04-22Drop cursor: pointer from the button reset so the custom pointer SVG winsBobby3-10/+12
2026-04-22Rebuild Settings with Reading, Sound, Accessibility, and About sections per ↵Bobby7-12/+281
the mockup
2026-04-22Redraw cursors as a warm-white ring and an amber disc with centered hotspotsBobby3-21/+9
2026-04-22Hold the initial-load progress bar to the first session entry and skip it on ↵Bobby2-2/+24
return
2026-04-22Remove the leaf scene and its supporting systems from the Begin screenBobby8-769/+0
2026-04-22Expand Settings with Display and About sections and a reduce-motion override ↵Bobby3-1/+70
for the leaf scene
2026-04-22Redesign leaves with real silhouettes and localized gusts driven by a ↵Bobby6-186/+450
prevailing wind
2026-04-22Redesign cursor: warm-white arrow for default, amber pointing hand for ↵Bobby3-9/+21
interactive
2026-04-22Move title music to layout so it plays continuously across routesBobby2-6/+7
2026-04-22Add Settings screen with mute toggle and ambient volume sliderBobby5-1/+319
2026-04-22Add falling-leaf physics and periodic wind gusts to the Begin screenBobby6-4/+505
2026-04-22Add custom SVG cursor with normal and pointer variantsBobby3-0/+24
2026-04-22Play title track on Begin screen with autoplay-fallback on first interactionBobby3-0/+73
2026-04-22Add Credits screen with initial font and audio attributionsBobby6-1/+257
2026-04-22Revert prop plumbing; components can tap stores and module constants directlyBobby4-20/+6
2026-04-22Make lib components and screens pure; orchestration (store, version) moves ↵Bobby4-6/+20
to routes
2026-04-22Move screens to lib/screens, version to lib/version, inject version via Vite ↵Bobby8-18/+21
define; lib is folders-only
2026-04-22Rename ui-lib to lib, split Begin into smaller components, add Credits, bump ↵Bobby14-155/+240
version to 1.0 from package.json
2026-04-22Implement initial load + Begin screens with stub 3s loading pipelineBobby10-33/+365
2026-04-22Strip comments from CSS, YAML, gitignore, JS configs; JSDoc-on-declarations ↵Bobby4-54/+2
is the only allowed comment
2026-04-22Migrate remaining relative imports to @hollowdark/*; strip //-comments and ↵Bobby49-220/+190
doc references, JSDoc-only
2026-04-22Drop all barrel index.ts files; imports target leaf files directlyBobby40-267/+57
2026-04-22Switch cross-module imports to @hollowdark/* scoped aliasBobby28-47/+32
2026-04-22Set up IndexedDB schema via DexieBobby4-0/+257
2026-04-22Define core entity interfacesBobby38-0/+1254
2026-04-22Add Literata and Inter fonts, title-screen audioBobby12-36/+234
Fonts (SIL Open Font License; licenses preserved alongside the files): static/fonts/Literata-Regular.ttf body — 400 weight static/fonts/Literata-Italic.ttf body — 400 italic static/fonts/Literata-Medium.ttf body — 500 weight static/fonts/Inter-Regular.ttf UI chrome — 400 weight static/fonts/Inter-Medium.ttf UI chrome — 500 weight static/fonts/Literata.OFL.txt static/fonts/Inter.OFL.txt Google Fonts' Inter distribution is optical-size-tiered — the 18pt variants are tuned for the 13–18px range our UI uses, so they're aliased as the base "Inter" family. Crimson Pro (memoir body) is not yet sourced; its @font-face block and preload hint both drop out of app.css / app.html for now and land when the memoir screen is built. app.css swaps the woff2 references for ttf (format: 'truetype'), and the @font-face comment now reflects the reality of what's on disk. app.html preloads the ttf variants. svelte.config.js drops the prerender handleHttpError shim that was tolerating missing /fonts/ 404s — the files exist now, so the build should fail loudly if any preloaded font goes missing. Title-screen audio: static/audio/title/piano-relaxing.mp3 — "Piano Relaxing" by atlasaudio, Pixabay Content License static/audio/title/piano-relaxing.license.txt — Pixabay license certificate Note on design: docs/17-first-hour.md said "no menu music" on the title screen. Running with this addition per the director's current direction (the design docs reflect an earlier stage of thinking).
2026-04-22Use relative imports for same-directory siblings; split utils into foldersBobby28-163/+165
Two related cleanups landed together because they touch the same pattern: 1. Intra-module imports now use relative paths rather than the module's own path alias. rng/seeded.ts imports from './derive', not 'rng/derive'; time/gameTime.ts from './calendar', not 'time/calendar'; the utils barrel from './result' etc. This matches rules/01-code-style.md: "Relative imports only for same-directory siblings." The alias form is reserved for imports *between* modules — how external callers refer to a module's public surface. (The TS language server in the IDE had trouble resolving the self- aliased form even though svelte-check accepted it; this change removes the ambiguity.) 2. utils/ is now folder-per-concept. Each utility owns a directory with its files broken up into small pieces: utils/result/ types, constructors, predicates, map, unwrap utils/assert/ assert, assert-never, assert-defined utils/equal/ deep utils/types/ brand, deep-readonly, element-of, json, non-empty-array utils/log/ log utils/index.ts re-exports from each subfolder via the barrel. External callers import from 'utils' unchanged; internal references are relative. One reason to prefer folders over flat files here is headroom — when a concept grows, new files sit alongside their siblings inside the concept's folder rather than crowding the utils/ root. No API changes. All 128 tests still green.
2026-04-22Add shared utilities: Result, assert, deepEqual, common types, logBobby9-0/+513
Foundational helpers referenced by most subsequent code. Small, pure, no dependencies on anything in the project. utils/result.ts Result<T, E> = Ok<T> | Err<E> for recoverable failures at system boundaries (save/load, manifest fetch, content validation). Internal pure logic still uses throw for programmer errors. ok / err / isOk / isErr / mapResult / mapErr / unwrap / unwrapOr. utils/assert.ts assert (with type-narrowing asserts), assertNever for exhaustive-switch termination, assertDefined for narrowing T | null | undefined → T. utils/equal.ts Structural deepEqual for tests comparing simulation snapshots. Handles plain objects, arrays, Map, Set, Date, primitives. Does not handle cyclic graphs (simulation state is a tree). utils/types.ts Common type aliases: NonEmptyArray, JsonValue, ElementOf, DeepReadonly, Brand<T, B> for nominal / branded types (PersonId vs RelationshipId). utils/log.ts Structured logging wrapping console. Developer- facing only; the game ships with no runtime telemetry. utils/index.ts Public re-exports. 40 unit tests in tests/unit/utils/ cover Result constructors and combinators, assert variants, and deepEqual's primitive / array / object / Map / Set / Date paths plus a realistic simulation-snapshot comparison.
2026-04-22Implement GameTime and the 12-month calendarBobby8-0/+817
The Hollowdark calendar is 12 × 30-day months + a 5-day year-end festival = 365 days, with 7-day weeks (docs/01-world.md and the style bible). Months live in canonical order: spring 1 Thawing 2 Greening 3 Blossomtide summer 4 Highsun 5 Amberhaze 6 Harvestmark autumn 7 Firstfall 8 Stormturn 9 Ashfall winter 10 Rainfall 11 Hollowdark 12 Rimefrost festival 13 Year's End Festival (5 days) time/calendar.ts month names, season mapping, days-per-month, festival helpers time/gameTime.ts GameTime shape + arithmetic: makeGameTime, addDays / addWeeks / addMonths / addYears, daysBetween / weeksBetween, compare / isBefore / isAfter / isSameDay, dayOfWeek, dayOfYear, toAbsoluteDays, formatGameTime time/granularity.ts LifeStage + TickUnit mapping — one tick is a year in infancy, a season in childhood, a month in adolescence and old age, a week in adult life (docs/05-time-system.md, ARCHITECTURE.md §5) time/speed.ts Speed type: 'paused' | 'play' | 'fast' time/index.ts public re-exports Arithmetic is implemented by flattening GameTime to absolute-day integers (year × 365 + dayOfYear - 1) so addDays, daysBetween, and ordering are exact integer math. addMonths uses 13-month modular arithmetic and clamps the day into the festival's 5-day length on overflow. 59 unit tests in tests/unit/time/ cover constants, validation, arithmetic edge cases (Rimefrost 30 → Festival 1, Festival 5 → Thawing 1 of next year, day-clamping when landing in the festival), negative offsets, tickOfDay preservation, day-of-week stability, and life-stage boundaries.
2026-04-22Implement seeded PRNG with deterministic sub-RNG derivationBobby4-0/+387
rng/ is the load-bearing primitive for simulation determinism (ARCHITECTURE.md §26). All gameplay randomness routes through createRNG; Math.random is forbidden in gameplay code by ESLint. rng/derive.ts xmur3 string hash + deriveSeed(parentSeed, label), stable across processes and runs rng/seeded.ts SeededRNG interface, mulberry32 implementation, next / nextInt / nextBool / pick / weightedPick / sub rng/index.ts public re-exports Sub-RNG derivation is the key technical move: seeding a child with hash(parent_seed + label) lets NPCs' trajectories be regenerated deterministically from their identity tuple alone — which is how Tier 3 NPCs stay off-disk until the player needs them. 29 determinism tests in tests/determinism/rng.test.ts cover: same seed → same sequence, sub-RNG independence from parent consumption, sub-order matters, input validation, and a byte-level inline snapshot that locks the PRNG output for seed "hollowdark". The snapshot is load-bearing — if mulberry32 or xmur3 changes, every existing save diverges, so treat a snapshot break as a migration concern, not an update-the-snapshot fix.
2026-04-22Drop configure-pages enablement; Pages must be enabled once by handBobby1-4/+4
configure-pages@v5 with enablement: true fails on a fresh repo with "Resource not accessible by integration" — creating a Pages site is administration-scoped and the workflow's GITHUB_TOKEN only carries pages: write, which is enough to deploy but not to provision. The one-time manual step is: Settings → Pages → Source: GitHub Actions. After that, this workflow is idempotent and deploys on every push.
2026-04-22Enable GitHub Pages from the deploy workflow itselfBobby1-0/+4
configure-pages fails on first run when Pages hasn't been turned on in the repo yet. Passing enablement: true lets the workflow provision the Pages site using its own pages:write token — no manual Settings → Pages trip needed, and subsequent runs are idempotent.
2026-04-22Add GitHub Pages deploy workflowBobby1-0/+58
On push to main: install with frozen lockfile, type-check with svelte-check, lint, then build with BASE_PATH set to /<repo-name> so kit.paths.base produces correct asset URLs under the GH Pages subdomain. Artifact uploaded via actions/upload-pages-artifact@v3 and deployed via actions/deploy-pages@v4. Concurrency group 'pages' prevents overlapping deploys from stepping on each other; cancel-in-progress left off so a queued deploy from a later commit waits for the earlier one to finish rather than aborting it mid-upload.
2026-04-22Forbid Math.random in gameplay code via ESLintBobby1-0/+95
Determinism is load-bearing in Hollowdark (ARCHITECTURE.md §26). Same seed plus same choices must produce bit-identical outcomes — otherwise bug reproduction, lazy NPC backfill, and save integrity all break. Every random call has to route through the seeded PRNG in rng/. Three restricted-syntax rules, scoped to gameplay directories via an explicit files glob: - Math.random() — forbidden - crypto.getRandomValues() — forbidden for gameplay - Date.now() — forbidden; use GameTime from time/ Each rule carries a specific error message pointing at the architectural rationale. The restrictions lift inside tests/, scripts/, and *.{test,spec}.ts where non-deterministic helpers are fine. @typescript-eslint/no-explicit-any set to error across the board.
2026-04-22Add design tokens and global stylesBobby1-0/+238
The single source of truth for colors, fonts, spacing, type scale, line height, and transition timing — applied as CSS custom properties on :root per rules/01-code-style.md. Component styles reference these via var(), never hex literals. body.crisis-mode swaps --color-bg, --color-text, and --color-accent to the tighter palette from docs/22-crisis-mode.md. The transition runs at --transition-ceremonial so the shift is felt rather than flashed. Global reset: no-select everywhere (the reading surface is not a document), .selectable escape hatch for input fields, smooth scroll, minimal scrollbars hidden on coarse pointers, prefers-reduced-motion respected. The oncontextmenu handler in app/app.html suppresses right-click. Font-face declarations point at static/fonts/ with font-display: swap and relative URLs so they resolve correctly under the GitHub Pages base path. Font files land separately.
2026-04-22Configure Prettier and ESLint baseBobby2-0/+36
Prettier: no semicolons, single quotes, no trailing commas, 100-column body width, 80-column prose markdown. Svelte plugin registered for component formatting. ESLint is added in a separate commit since the lint rule forbidding Math.random in gameplay code is its load-bearing purpose; the base flat config appears there.
2026-04-22Initialize project with SvelteKit on flat-root layoutBobby17-0/+2439
SvelteKit 2 with adapter-static, Svelte 5, TypeScript 6 strict mode. Design decisions follow ARCHITECTURE.md §2 and technical/01-file-structure.md: no src/ wrapper, implementation folders sit at the project root alongside the design corpus in .claude/, and each top-level folder is its own import alias (engine/, events/, flow/, scene/, etc.) configured in svelte.config.js. Framework configuration routes SvelteKit away from the default src/ layout: templates live in app/, hooks in hooks/, routes in routes/, assets in static/. The favicon is a quiet amber dot on #13100E; .nojekyll keeps GitHub Pages from stripping the _app/ build folder. Deploy target is GitHub Pages. adapter-static uses fallback: '404.html' (the GH Pages SPA convention) and kit.paths.base reads BASE_PATH from the environment so dev serves at the root while the deploy workflow builds under /<repo>/. Prerender tolerates missing /fonts/ files so the build doesn't block until font files land — see static/css/app.css @font-face block. Licensed MIT.