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
10 changes: 8 additions & 2 deletions docs/assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ nnnotes depot plan --check && echo "up to date"
## Commands

```
nnnotes export assets -o OUT [--layout original[,cas]] [--select group:G|key:PREFIX|bundle:GLOB ...] [--views all|none|a,b]
nnnotes export assets -o OUT [--layout original[,cas][,product]] [--select group:G|key:PREFIX|bundle:GLOB ...] [--views all|none|a,b]
[--depot DIR] [--workers N] [--memory GiB] [--fetch-workers N] [--stored-catalog L|SHA]
[--png-level N] [--flac-level N] [--only-class C,...] [--link auto|clone|hard|copy] [--strict]
[--dry-run] [--explain]
Expand All @@ -37,7 +37,7 @@ nnnotes depot verify [--quick] [--workers N]
| `-o OUT` | output directory |
| `--select SEL` | what to export (repeatable, the union; default everything): `group:G` the bundles of an Addressables group (the stable bundle name up to `_assets_`, else up to its first `_`), `key:PREFIX` the bundles and raw files the catalog keys under `PREFIX` load, `bundle:GLOB` the bundles and raw files whose stable name matches |
| `--views` | the semantic views to build ([views.md](views.md)): `all`, `none` or names, comma-separated; default `all` when master data is set, else `none` |
| `--layout` | `original`, `cas` or both (below) |
| `--layout` | `original`, `cas`, `product`, comma-separated (below) |
| `--depot DIR` | the depot (`[paths] depot`) |
| `--workers N` | worker processes (default: the CPUs the process may run on, its affinity mask as `taskset` or a container's cpuset sets it; `0`: every task in this process) |
| `--memory GiB` | memory budget (default: 80 % of the physical memory where it can be read, else none) |
Expand Down Expand Up @@ -183,6 +183,12 @@ replaces or removes it where the system needs that (Windows), and the depot obje
from the `original` manifest alone, `original` from `cas` and the results. The views are the exception: `original`
has them with the paths of their objects, `cas` the view documents they are made from.

`product` places the products of the selection ([products](products.md)): every product stage makes its products
of the catalog keys the selected bundles hold (the Live2D stages: each model key), and the layout writes each
product's manifest (`models/<name>.json`, `cubism/<name>.json`) with its files and the files of its objects at
`assets/<sha256>.<ext>`. The product stages run only with this layout. Without `original` or `cas`, the run exports
only the objects the products reach, not every object of the selection.

## Reports

`OUT/_reports/`:
Expand Down
12 changes: 9 additions & 3 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ every object of the selected bundles -> common formats (the depot and its layout
| `--workers` `N` | worker processes (default: the CPUs this process may use; 0: this process) |
| `--memory` `GiB` | memory budget of the running tasks and workers (default: 80 % of the physical memory) |
| `--fetch-workers` `N` | parallel downloads (default 8) |
| `--layout` `LAYOUT` | original, cas or original,cas (default original) |
| `--layout` `LAYOUT` | original, cas, product, comma-separated (default original; product: the products of the selection) |
| `--explain` | print every setting of the run first |
| `--link` `LINK` | how the layout files are made from the depot: auto (default; [export] link): a clone where the file system makes them, else a hard link (read-only), else a copy; or that method only (one of `auto`, `clone`, `hard`, `copy`) |
| `--strict` | exit 1 when a view has gaps |
Expand Down Expand Up @@ -228,12 +228,18 @@ At most one of `--band`, `--leader-card`.

## nnnotes export live2d

a Live2D model -> runtime model directory
a Live2D model -> its Cubism SDK files, or the player's model

| Argument | Description |
| --- | --- |
| `key` | model key Character/Live2D/<group>/<name>/model/<name>, or its model id <name> |
| `-o`, `--out` `OUT` | output directory (required) |
| `--player` | write the player's model (models/<id>.json and assets/) instead of the Cubism SDK files |
| `--stored-catalog` `LABEL\|SHA` | a catalog version of the depot (`catalog versions`; default: the current catalog) |
| `--workers` `N` | worker processes (default: the usable CPUs) |
| `--link` `LINK` | as export assets --link (one of `auto`, `clone`, `hard`, `copy`) |
| `--explain` | print every setting of the run first |
| `--dry-run` | print the plan, run nothing |

## nnnotes export spot

Expand Down Expand Up @@ -321,7 +327,7 @@ what `export assets` would run and why, without running it (--json: nnnotes.plan
| `--workers` `N` | worker processes (default: the CPUs this process may use; 0: this process) |
| `--memory` `GiB` | memory budget of the running tasks and workers (default: 80 % of the physical memory) |
| `--fetch-workers` `N` | parallel downloads (default 8) |
| `--layout` `LAYOUT` | original, cas or original,cas (default original) |
| `--layout` `LAYOUT` | original, cas, product, comma-separated (default original; product: the products of the selection) |
| `--explain` | print every setting of the run first |
| `--since` `RUN` | explain against this run (default: the latest of the selection) |
| `--check` | exit 1 when anything would run or change |
Expand Down
21 changes: 13 additions & 8 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,24 +287,29 @@ way the TMP shader applies them. The document-level `textStyle.roles` gives, per
## export live2d

```
nnnotes export live2d MODEL -o OUT
nnnotes export live2d MODEL -o OUT [--player]
```

A Live2D (Cubism) model prefab as a Cubism runtime directory. `MODEL` is the model's key
A Live2D (Cubism) model as the Cubism SDK files other tools read. `MODEL` is the model's key
`Character/Live2D/<group>/<name>/model/<name>` or its id `<name>` (`nnnotes catalog keys --prefix Character/Live2D/` lists
the keys):

```
OUT/<name>.moc3 the model's moc3
OUT/textures/*.png atlas pages
OUT/<name>.prefab.json the whole prefab: every GameObject and component, motions and expressions inlined
OUT/<exp>.exp3.json expressions
OUT/textures/<page>.png the atlas pages the drawables draw with, by name
OUT/<name>.physics3.json physics (not written for a model without physics)
OUT/motions/<motion>.motion3.json motions (and motions/_fades.json)
OUT/<name>.model3.json file references, EyeBlink / LipSync groups
OUT/<exp>.exp3.json expressions
OUT/motions/<motion>.motion3.json motions
OUT/<name>.model3.json file references, the model's fade times per motion, EyeBlink / LipSync groups
```

Needs `[paths] apk` (component classes are resolved through the APK). Prints a JSON summary.
With `--player`, the model the player reads instead: the product layout of `live2d.model`, `OUT/models/<name>.json`
and the files it names under `OUT/assets/` ([products](products.md#live2d-models)).

The command runs the depot's pipeline for the model alone (the census of the bundles of its key, the objects its
prefab reaches, the product) like `export assets`, and writes the same reports in `OUT/_reports/`; it takes
`--stored-catalog`, `--workers`, `--link`, `--explain` and `--dry-run` as `export assets` does. Needs `[paths] apk`
(the component classes and the mask materials are in the APK).

## export spot

Expand Down
6 changes: 3 additions & 3 deletions docs/export.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ nnnotes catalog keys --prefix Character/Live2D/ --limit 0 # every model key
nnnotes export live2d adv_live2d_rana_003_casual_spring_01 -o out/live2d/rana
```

`MODEL` is the model's key or its id, the last part of the key. The output is a Cubism runtime directory: moc3, atlas
pages, motions, expressions, physics, `model3.json` and the whole prefab as JSON. Details:
[export live2d](commands.md#export-live2d).
`MODEL` is the model's key or its id, the last part of the key. The output is the model's Cubism SDK files: moc3,
atlas pages, motions, expressions, physics and `model3.json`; `--player` writes the model the player reads instead.
Details: [export live2d](commands.md#export-live2d).

## A spot or a room

Expand Down
46 changes: 45 additions & 1 deletion docs/products.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,18 @@ object), or the reason code of a generic, unsupported or failed object.

## Product layout

A product layout places products for a player:
A product layout places products for a player (`export assets --layout product`, `export live2d --player`):

- every file of a product and every file of the objects of its object table at `assets/<sha256>.<ext>` (a file
several products or objects share is written once);
- each product's manifest at `<directory>/<file>.json` (the stage's `manifest(subject)`, by default
`<stage>/<subject>.json` with the subject escaped as one path segment).

A command asks for products in one of two ways: `export assets --layout product` makes, with each product stage, the
products of the catalog keys the selected bundles hold (the stage's `select`); `export live2d` asks for one model.
`export live2d` without `--player` places the files of its one product at their own paths instead (the `files`
placement: the Cubism SDK files as a directory).

## Product manifest: nnnotes.product/1

([product.schema.json](https://github.com/MetaSekaiLab/nnnotes/blob/main/src/nnnotes/schemas/product.schema.json))
Expand All @@ -83,3 +88,42 @@ A product layout places products for a player:
contained in an object that has one. An asset path is relative to the directory above the manifest's directory, as
in the chart manifests of ournotes-player. A reference in an object's JSON (`{"$ref": {"file", "pathId"}}`) names
the object `<file>:<pathId>` of `objects`.

## Live2D models

Two product stages (`nnnotes.pipeline.live2d`) assemble a Live2D model from the objects its prefab reaches. Their
subjects are model keys, `Character/Live2D/<group>/<name>/model/<name>`; a model's id is its `<name>`.

`live2d.model` is the model the player reads. Its roots are the model's GameObject (the object of its key) and the
materials the Cubism mask pass draws with, which the APK's built-in files hold at the `Resources.Load` paths
`Live2D/Cubism/Materials/Mask` and `Live2D/Cubism/Materials/MaskCulling`. Its manifest is `models/<id>.json`, and its
one file `model.json` (format 3) names objects of its object table:

| Field | |
|---|---|
| `name`, `key` | the model's id and key |
| `prefab` | the object id of the model's GameObject; its `json` is the hierarchy (prefab.json) |
| `moc` | the object id of its CubismMoc (the root's `CubismModel._moc`); the moc3 is its file `blob:_bytes` |
| `canvas` | the moc3's canvas: `pixelsPerUnit`, `originX`, `originY`, `width`, `height`, `mocVersion` |
| `textures` | the object ids of the atlas pages the drawables draw with (`CubismRenderer._mainTexture`), by name |
| `shaders` | `{shader name: object id}` of the shaders of the object table |
| `resources` | `{"cubismMask", "cubismMaskCulling"}`: the object ids of the two mask materials |
| `motionSync` | the root has the MotionSync controller and its CRI audio input |
| `bindings` | `{clip object id: [{path, attribute}]}`: the bindings of every AnimationClip of the table named in the model's hierarchy, played from its root (`nnnotes.unity.bindings`; `null` where no name, or several, fit) |

Its object table holds every object the model reaches but the MonoScripts. Of a shader it keeps the parsed form
(`json`), the variant index (`index`) and the GLSL ES 3.00 programs (subshader 0, pass 0) the player draws the
drawables' materials with: for each material's keywords, alone and with `_ADDITIONAL_LIGHTS_VERTEX` (the keyword the
story renderer adds to a character draw), and the mask materials' when a drawable is masked (`CUBISM_MASK_ON`).

`live2d.cubism` is the model as the Cubism SDK files other tools read (`export live2d`); its manifest is
`cubism/<id>.json` and it has no objects:

| File | From |
|---|---|
| `<id>.moc3` | the CubismMoc's bytes |
| `textures/<page>.png` | the atlas pages, by name (a name two pages share is numbered: `<page>-2.png`) |
| `<id>.physics3.json` | the root's `CubismPhysicsController._rig` (when it has sub-rigs) |
| `<expression>.exp3.json` | each CubismExpressionData of the table |
| `motions/<motion>.motion3.json` | each CubismFadeMotionData, with the sample rate of the clip of its name |
| `<id>.model3.json` | the files, the model's fade times of each motion, and the EyeBlink and LipSync groups (the GameObjects holding a CubismEyeBlinkParameter or a CubismMouthParameter) |
4 changes: 2 additions & 2 deletions docs/stages.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The asset export is built from three layers:

Every stage is at version 1, except `unity.census` (version 4: it lists what every object references, the
hierarchy holding it and the Resources.Load paths of a ResourceManager), `link.addresses` (version 2: the
Resources.Load paths), `unity.export` (version 2: one task per unit), `cri.movie` (version 2: every stream kind,
Resources.Load paths), `live2d.model` (version 2: assembled from the exported objects), `unity.export` (version 2: one task per unit), `cri.movie` (version 2: every stream kind,
codec and channel of a USM) and `catalog.index` (version 2: gzip input and Japanese remote asset placeholders).

| Stage | Subject | Inputs | Outputs |
Expand All @@ -26,7 +26,7 @@ codec and channel of a USM) and `catalog.index` (version 2: gzip input and Japan
| `sprite.crop` | a SpriteAtlas | the atlas' JSON, the images of its textures, the metas of the sprites of other bundles it packs | the sprites' images |
| `cri.audio` | ACB content | `acb` (a raw file of the catalog, or the `acb` artifact of a cue sheet held in a bundle), `awb` (an AWB the catalog pairs with it), `boot` (the game's boot data: the key's source) | FLAC per stream, `cues.json`, `streams.json` |
| `cri.movie` | USM content | `usm` (a raw file of the catalog, or the `usm` artifact of a movie held in a bundle), `boot` | every stream as stored (video, alpha, audio, subtitles), `movie.mkv` (or `movie.webm`) |
| `live2d.model` | a Live2D model key (`Character/Live2D/<group>/<name>/model/<name>`) whose bundle is selected | `bundle:<n>`: the bundles of the key's dependency closure in the order the extractor loads them (the order is part of the key); context `internalId` (the key's location); atom `live2d.extract_model` (the extractor of `nnnotes export live2d`, run unchanged) | `live2d.model:<key>#<path>`: every file `nnnotes export live2d` writes for the model, `<path>` relative to the model's directory; placed under `<key>/` |
| `live2d.model`, `live2d.cubism` | a Live2D model key (`Character/Live2D/<group>/<name>/model/<name>`) a command asks for | `objects`: the object table of what the model reaches ([products](products.md#live2d-models)); depends on `link.addresses` and the `unity.export` tasks it reads | `model.json` (the player's model) and the object table; the Cubism SDK files |
| `spine.skeleton` | a SkeletonDataAsset of a selected bundle, by its stable address `<bundle>:<pathId>` (in a bundle of several serialized files the file's tag follows the bundle name, as in `link.addresses`) | `bundle:<stable name>`: the bundles holding the serialized files the asset's file reaches through its externals; context `object` (the asset's object id); atom `spot.write_skeleton` (the Spine writer of `nnnotes export spot`) | `spine.skeleton:<subject>#<file>`: the skeleton (`.json` or `.skel`), its atlases (`.atlas`) and their page images, the bytes `nnnotes export spot` writes into `spine/`; one item for the asset |
| `link.addresses` | global | catalog index, censuses (the built-in files' too) | key -> objects, Resources.Load path -> 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) |
Expand Down
Loading
Loading