Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions docs/products.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ the request of `unity.export` then holds the units of those objects and every un
census `refs` ([units](stages.md#units)), and nothing else of their bundles.

What a task reaches: the units holding its roots, then every unit that an item of a reached unit references (the
item's `refs`), through the `unity.export` results. A sprite whose atlas is in another bundle has its `image` from the
item's `refs`; a SpriteAtlas reached through a reference does not reach the sprites it packs), through the
`unity.export` results. A sprite whose atlas is in another bundle has its `image` from the
`sprite.crop` result of that atlas. A reached unit that the request did not export is an error of the request; an
object that a reached object references and no census holds is listed as `missing`.

Expand All @@ -53,6 +54,7 @@ changes, or what it reaches changes.
```json
{"schema": "nnnotes.objects/1",
"roots": ["CAB-…:-4153…"],
"keys": {"Character/Live2D/…/model/…": ["CAB-…:-4153…"]},
"objects": {
"CAB-…:-4153…": {"status": "exported", "class": "GameObject", "name": "model",
"files": {"json": {"sha256": "…", "size": 5120, "ext": "json"}}},
Expand All @@ -63,8 +65,9 @@ changes, or what it reaches changes.
"missing": []}
```

Each object has the status of its item (the most severe when two stages made items for it), its class and name
where known, its files by role (the artifacts of its items), the object whose file holds it (`in`, a contained
`keys` gives the root objects of each catalog key of the product, so an assembler finds an object by the key the
game loads it by. Each object has the status of its item (the most severe when two stages made items for it), its
class and name where known, its files by role (the artifacts of its items), the object whose file holds it (`in`, a contained
object), or the reason code of a generic, unsupported or failed object.

## Product layout
Expand Down Expand Up @@ -244,3 +247,31 @@ option defaults of preset 1 (`MasterOptionDefault`), `MasterLiveNoteSe`, `Master

The `product` layout makes the `live.music` products of the musics whose BGM key the selection holds, and the
default `live.sounds` when the selection holds every cue sheet of its sounds; both need the master data.

## Note highway

What a live spawns and animates per note is three products of `nnnotes.pipeline.live`, each shared by every live that
loads it. Their roots are the objects of their keys, and each document names objects of its object table:

| Product | Subject | Manifest | Roots | Document |
|---|---|---|---|---|
| `live.notes` | `default` | `notes/default.json` | the note view prefabs (`EmbLive/Prefabs/LiveGame/<view>_note_view`), the slide and guide line views, the pair line, the groove loop, and the lane effect settings `Effect/Live/LaneEffect/effect001/LiveLaneEffectAssetSettings` | `notes.json` |
| `live.noteskin` | a note skin, `MasterLiveNoteSkin._assetName` | `noteskins/<name>.json` | the skin asset `Live/Note/<name>/LiveNoteSkinAsset` and the three flick views | `noteskin.json` |
| `live.noteeffect` | a note effect set, `MasterLiveNoteEffectSkin._assetName` or its `Light` variant (the set the game loads at quality Low where the catalog has it) | `noteeffects/<name>.json` | the effect settings `Effect/Live/NoteEffect/<name>/LiveNoteEffectAssetSettings` | `noteeffect.json` |

Each document has `format` 1 and

| Field | |
|---|---|
| `prefabs` (notes) | `{name: object id}` of the prefab GameObjects: `tap_note_view`, ..., `slide_line_view`, `guide_line_view`, `pair_note_line`, `note_groove_loop` |
| `laneEffect` (notes) | the object id of the lane effect settings |
| `settings` (notes) | the option defaults of preset 1 (`optionDefaults`) and the ranges (`optionRanges`) of the items the note runtime and the player read, the `MasterLiveSettings` values of the note speed and slides (`liveSettings`), the note display time of the default speed (`noteDisplayTimeMs`), the lane geometry, the default skin and effect set (`skin`, `effect`) and the lane effect set (`laneEffect`), and the names of every skin and effect set by option value (`skins`, `effects`) |
| `name`, `skin` (noteskin) | the skin's name and the object id of its `LiveNoteSkinAsset` |
| `name`, `settings` (noteeffect) | the set's name and the object id of its `LiveNoteEffectAssetSettings`, which references the effect prefabs |
| `bindings` | `{prefab GameObject id: {Animator node path: {clip id: [{path, attribute}]}}}`: the clips each Animator of the table's prefabs plays (its controller's clips and the `_loopAnim` of a `LoopAnimationTimeSync` on its `_animator`; for a skin, the arrow loop of each flick unit on its flick view's `LoopAnimationTimeSync`), named from the Animator's node (`nnnotes.unity.bindings`) |
| `shaders` | `{shader name: object id}` of the shaders of the object table |

The object table holds every object the product reaches but the MonoScripts; of a shader it keeps the parsed form
(`json`), the variant index (`index`) and every GLSL ES 3.00 program. The `product` layout makes `live.notes` when the
selection holds all its keys and the master data is there, and the `live.noteskin` and `live.noteeffect` products of
the skin and effect set keys the selection holds.
7 changes: 6 additions & 1 deletion docs/stages.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ codec and channel of a USM) and `catalog.index` (version 2: gzip input and Japan
| `spot.files` | a spot situation key (`Spot/<place>/<situation>/<situation>`) | `objects`; `master`: the spot's master record | `spot.json` and the Spine files |
| `live.music` | a music id (`MasterLiveMusic`) | `objects`; `acb:<key>` and `sheets`: the BGM's cue sheet and its `cri.audio` files ([products](products.md#live-sounds)); `master`: the music's master record; parameter `format` (`aac`) | `music.json` and the BGM in the web format |
| `live.sounds` | the note sound sets offered: `default` or `NoteSePatternId=<ids>` | `objects` (the sound settings of the APK's built-in files); `acb:<key>` and `sheets` of each cue sheet; `apk:assets/Cri/Sound/Sirius.acf`; `master` | `sounds.json` and the decoded sounds |
| `live.notes` | `default` | `objects`: the object table of the note prefabs and the lane effect settings ([products](products.md#note-highway)); `master`: the settings' master record | `notes.json` and the object table |
| `live.noteskin` | a note skin (`skin001`) | `objects`: the object table of the skin and the flick views | `noteskin.json` and the object table |
| `live.noteeffect` | a note effect set (`effect001`, `effect001Light`) | `objects`: the object table of the effect settings | `noteeffect.json` and the object table |
| `link.addresses` | global | catalog index, censuses (the built-in files' too) | key -> objects, Resources.Load path -> objects, built-in selector (class, MonoBehaviour script class) -> objects, serialized file -> bundle or built-in file, bundle -> keys |
| `view.<name>` | a catalog (`main`) | `master:<Table>` per master table it reads, `rules` (the view's rule and the resolvers it uses), `addresses` (the part of the address table it read: the keys looked up and the prefixes listed); no parameters, atoms or context | `view.<name>:<subject>#view` (facts: rows, entries, gaps, unreferenced) |
| `view.voices` | a catalog (`main`) | `master:<Table>` per master table its rules read, `rules`, `addresses`, `sheets` (each cue sheet the `cri.audio` results are known by that a voice names or the rules' prefixes list: its task and ACB content id), `acb:<sha256>` (the ACB of each decoded one), `episodes` (per story episode and part, the `unity.export` artifact holding the object its key names), `adv:<sha256>` (those contents); context `audio` (the keys of those `cri.audio` results); runs after `unity.export` and `cri.audio` | `view.voices:<subject>#view` (facts: rows, entries, gaps, unreferenced streams) |
Expand Down Expand Up @@ -116,7 +119,9 @@ bundle's content changes, so a unit keeps its task across catalog versions.
A run exports the units holding an object of the selected bundles, the units of the objects the fact "roots" names
(catalog keys, Resources.Load paths, built-in selectors and object ids: a product's roots, [products](products.md)) and every unit reachable
from those through what their objects reference (the census `refs`, across the censuses of the run); with `--only-class`
only the units whose root object is of those classes. The selection is not part of any key: a unit's task is the same
only the units whose root object is of those classes. A SpriteAtlas reached through a reference adds its textures
but not the sprites it packs: a sprite needs its atlas' textures, not the atlas' other sprites (an atlas the run
starts from adds them all). The selection is not part of any key: a unit's task is the same
whichever request reaches it.

A task's key includes the atoms `reader` and `sniff`, the converter `generic.json`, the converters (with their
Expand Down
3 changes: 3 additions & 0 deletions src/nnnotes/cli/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ def matches(self, stage: str) -> bool:
StageSource("spot.files", "nnnotes.pipeline.spot:SpotStage", output=True, product=True),
StageSource("live.music", "nnnotes.pipeline.live:MusicStage", output=True, product=True),
StageSource("live.sounds", "nnnotes.pipeline.live:SoundsStage", output=True, product=True),
StageSource("live.notes", "nnnotes.pipeline.live:NotesStage", output=True, product=True),
StageSource("live.noteskin", "nnnotes.pipeline.live:NoteSkinStage", output=True, product=True),
StageSource("live.noteeffect", "nnnotes.pipeline.live:NoteEffectStage", output=True, product=True),
StageSource("view.", "nnnotes.pipeline.views:stages", output=True),
StageSource("view.voices", "nnnotes.pipeline.voices:VoiceStage", output=True),
)
Expand Down
Loading
Loading