From ebd9eedc4266b3c294fb30a899ecdd68b5c1b7b4 Mon Sep 17 00:00:00 2001 From: nichinichisou Date: Sat, 17 Oct 2026 23:57:20 +0800 Subject: [PATCH 1/2] feat(story): load and play shared object products --- CHANGELOG.md | 17 +- docs/data-format.md | 6 + docs/fidelity.md | 1 - docs/story-author.md | 13 +- docs/story-data-format.md | 807 +++---------- docs/story-features.md | 15 +- docs/story-simple.md | 30 +- docs/story.md | 13 +- schema/episode.schema.json | 319 +++++- schema/product.schema.json | 125 ++- schema/story-asset.schema.json | 76 ++ schema/story-fonts.schema.json | 1061 ++++++++++++++---- schema/story-host.schema.json | 185 +++ schema/story-language.schema.json | 84 +- schema/story-manifest.schema.json | 212 ++-- schema/story-scene.schema.json | 146 +++ schema/story-simple-ui.schema.json | 239 ++++ schema/story-ui.schema.json | 281 +++++ schema/story.schema.json | 202 +++- scripts/check-contracts.mjs | 2 +- scripts/lib/headless.mjs | 24 +- scripts/lib/story-author/script.js | 38 +- scripts/lib/story-author/site.js | 107 +- scripts/story-author.mjs | 2 +- scripts/validate-data.mjs | 791 +++++-------- src/engine/anim.js | 4 +- src/engine/audio.js | 31 +- src/{live => engine}/objects.js | 49 +- src/engine/postfx.js | 16 +- src/engine/prefab.js | 35 + src/engine/ugui.js | 31 +- src/live/background.js | 2 +- src/live/fx-effects.js | 10 +- src/live/fx-ui.js | 6 +- src/live/fx.js | 2 +- src/live/intro.js | 2 +- src/live/lane.js | 4 +- src/live/legacy.js | 2 +- src/live/noteview.js | 8 +- src/live/renderer.js | 17 +- src/live/session.js | 4 +- src/story/assets.js | 87 +- src/story/commands/talk.js | 5 +- src/story/controls.js | 1 + src/story/data.js | 92 ++ src/story/features/canvas.js | 101 +- src/story/features/chat.js | 71 +- src/story/features/clips.js | 96 -- src/story/features/effect.js | 83 +- src/story/features/frame.js | 35 +- src/story/features/posteffect.js | 15 +- src/story/features/screen.js | 87 +- src/story/features/still.js | 47 +- src/story/features/uiparticle.js | 27 +- src/story/features/video.js | 33 +- src/story/field.js | 40 +- src/story/interfaces.js | 8 +- src/story/models.js | 13 +- src/story/player-core.js | 2 +- src/story/player.js | 5 +- src/story/renderer.js | 19 +- src/story/scene.js | 32 + src/story/session.js | 79 +- src/story/silent-audio.js | 2 +- src/story/simple/home/host.js | 180 ++- src/story/simple/home/objects.js | 71 ++ src/story/simple/home/post.js | 56 +- src/story/simple/home/room.js | 38 +- src/story/simple/objects.js | 23 + src/story/simple/render.js | 12 +- src/story/simple/session.js | 129 +-- src/story/simple/ui.js | 246 ++-- src/story/simple/view.js | 14 +- src/story/stage.js | 37 +- src/story/store.js | 111 ++ src/story/ui-chat.js | 59 +- src/story/ui-fonts.js | 14 +- src/story/ui-layout.js | 5 +- src/story/ui-objects.js | 38 + src/story/ui-talk.js | 6 +- src/story/ui-transition.js | 20 +- src/story/ui.js | 217 ++-- tests/data/story-data.test.mjs | 53 +- tests/data/story-feature.test.mjs | 25 +- tests/data/story-play.test.mjs | 4 +- tests/data/story-ui-layout.test.mjs | 20 +- tests/unit/crilips-frontend.test.mjs | 7 +- tests/unit/engine-audio.test.mjs | 46 +- tests/unit/engine-postfx.test.mjs | 21 +- tests/unit/live2d-model.test.mjs | 26 +- tests/unit/read-set.test.mjs | 2 +- tests/unit/story-assets.test.mjs | 189 +--- tests/unit/story-author.test.mjs | 111 +- tests/unit/story-chat-resources.mjs | 39 + tests/unit/story-core.test.mjs | 25 +- tests/unit/story-feature-canvas.test.mjs | 7 +- tests/unit/story-feature-chat.test.mjs | 4 +- tests/unit/story-feature-clips.test.mjs | 54 - tests/unit/story-feature-effect.test.mjs | 34 +- tests/unit/story-feature-frame.test.mjs | 26 +- tests/unit/story-feature-scene.test.mjs | 4 +- tests/unit/story-feature-still.test.mjs | 2 + tests/unit/story-feature-uiparticle.test.mjs | 6 +- tests/unit/story-feature-video.test.mjs | 4 +- tests/unit/story-home-resources.mjs | 100 ++ tests/unit/story-object-resources.test.mjs | 94 ++ tests/unit/story-player.test.mjs | 3 +- tests/unit/story-product-fixture.mjs | 46 + tests/unit/story-products.test.mjs | 57 + tests/unit/story-renderer.test.mjs | 4 +- tests/unit/story-schema.test.mjs | 840 ++++---------- tests/unit/story-screen-resources.mjs | 92 ++ tests/unit/story-simple-home.test.mjs | 94 +- tests/unit/story-simple.test.mjs | 59 +- tests/unit/story-ui-canvas.test.mjs | 8 +- tests/unit/story-ui-chat.test.mjs | 12 +- tests/unit/story-ui-resources.mjs | 90 ++ tests/unit/story-validation-fixture.mjs | 172 +++ types/story.d.ts | 40 +- 119 files changed, 5702 insertions(+), 3993 deletions(-) create mode 100644 schema/story-asset.schema.json create mode 100644 schema/story-host.schema.json create mode 100644 schema/story-scene.schema.json create mode 100644 schema/story-simple-ui.schema.json create mode 100644 schema/story-ui.schema.json rename src/{live => engine}/objects.js (75%) create mode 100644 src/story/data.js delete mode 100644 src/story/features/clips.js create mode 100644 src/story/scene.js create mode 100644 src/story/simple/home/objects.js create mode 100644 src/story/simple/objects.js create mode 100644 src/story/store.js create mode 100644 src/story/ui-objects.js create mode 100644 tests/unit/story-chat-resources.mjs delete mode 100644 tests/unit/story-feature-clips.test.mjs create mode 100644 tests/unit/story-home-resources.mjs create mode 100644 tests/unit/story-object-resources.test.mjs create mode 100644 tests/unit/story-product-fixture.mjs create mode 100644 tests/unit/story-products.test.mjs create mode 100644 tests/unit/story-screen-resources.mjs create mode 100644 tests/unit/story-ui-resources.mjs create mode 100644 tests/unit/story-validation-fixture.mjs diff --git a/CHANGELOG.md b/CHANGELOG.md index c660e5b..b2c32ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ All notable changes to this package. Versions follow [Semantic Versioning](https://semver.org/). +## Unreleased + +### Story products + +- Story loading, playback and authoring use `nnnotes.product/1` manifests with shared object resources and language-specific UI and fonts. +- Home and live-result stories resolve their host prefabs, room geometry, Spine materials and animation bindings by object identity. +- Data validation checks the story product graph, font bindings, shader variants, audio files and model dependencies. `--lang` selects an explicit language scope. +- Node story loading accepts a manifest or a product layout containing exactly one story. + +### Bug fixes + +- Keep Spine index uploads from changing another renderer's vertex array. +- Keep model and shared-object validation caches independent. +- Clear loading text after language changes and display configured audio volumes in the controls. + ## [0.1.7](https://github.com/empty-sekai/ournotes-player/compare/v0.1.6..v0.1.7) — 2026-10-14 ### Features @@ -159,5 +174,3 @@ All notable changes to this package. Versions follow [Semantic Versioning](https - add performance.md: the CPU cost of a frame - a file holds each controller and clip once; the validator checks every reference _(story)_ - - diff --git a/docs/data-format.md b/docs/data-format.md index b24b525..55861fd 100644 --- a/docs/data-format.md +++ b/docs/data-format.md @@ -965,3 +965,9 @@ exactly the files the viewer and the story player read. It needs Node.js 22 or later and no dependencies. The opt-in data tests (`OURNOTES_DATA= npm run test:data`) go further and run lives and charts through the player in Node (see [CONTRIBUTING.md](../CONTRIBUTING.md)). + +## Song and replay data + +The song catalog example reads `music-data.json` with format `nnnotes.music-data/1`. Replay presets read +`nnnotes.deck-data/1` for the caller-provided deck capabilities, and the replay worker accepts +`nnnotes.replay-manifest/1` references. These are separate inputs from the live, model and story product manifests. diff --git a/docs/fidelity.md b/docs/fidelity.md index e68e9cb..f442652 100644 --- a/docs/fidelity.md +++ b/docs/fidelity.md @@ -528,7 +528,6 @@ Every `ENGINE:` note in `src/`, by file. `npm test` checks that this list matche - the ambient probe of a Flat ambient is built natively from the ambient colour; a white Flat ambient is taken as - the default reflection of a Skybox-mode scene without a skybox material (and without a custom cube) is taken - unity_LightData (native per-object light data): x the offset of the per-object light indices (0), y their -- atlas page texture import settings are not in the data; bilinear, clamped, no mipmaps here. - a Skybox clear without a skybox material clears to the background colour. **`src/story/simple/home/room.js`** diff --git a/docs/story-author.md b/docs/story-author.md index 2d91e83..9515e21 100644 --- a/docs/story-author.md +++ b/docs/story-author.md @@ -11,7 +11,7 @@ The tool is experimental: the script format and the commands may change between ## Requirements - Node.js 22 or later. -- A story site with stories in the model manifest format (`ournotes.story-manifest/2`) and its `models.json` +- A story site with stories in the story product format (`nnnotes.product/1`) and its `models.json` ([story-data-format.md](story-data-format.md)). Pass it with `--site ` or set `OURNOTES_SITE`. - For pictures (`render`, `base --out`, `model --out`): Chrome, Chromium or Edge. The tool starts a headless browser of its own with a temporary profile and ends it when the command ends. It draws with SwiftShader (WebGL2 on the @@ -181,10 +181,11 @@ long auto mode then keeps the line before the next one (`_waitTalkTextUnitTime` ### build -`build