Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
d647d3d
refactor!: keep downloads, results and runs in one depot
nichinichisou0609 Oct 14, 2026
00f6e20
refactor(scripts): use the depot in the atom evaluation script
nichinichisou0609 Oct 14, 2026
0b169fa
feat!: keep the depot's downloads as a cache bounded by [depot] downl…
nichinichisou0609 Oct 14, 2026
5b39baf
fix(depot): keep every input identity recorded by concurrent threads
nichinichisou0609 Oct 14, 2026
cd6152b
feat(depot): share results, contents and runs through a remote
nichinichisou0609 Oct 14, 2026
61143bc
refactor: move the atoms to the unity layer
nichinichisou0609 Oct 14, 2026
9bca3e4
refactor!: convert Unity objects with one converter library
nichinichisou0609 Oct 14, 2026
133f731
feat(export)!: give every object a json document and list its references
nichinichisou0609 Oct 14, 2026
7fd3f0e
feat(export)!: census and export the APK's built-in Unity files
nichinichisou0609 Oct 14, 2026
8b97704
feat(census)!: list what every object references and the hierarchy ho…
nichinichisou0609 Oct 14, 2026
edc9ee4
feat(orchestrate): run the tasks of a batch as one job in one worker
nichinichisou0609 Oct 14, 2026
1c3dff8
feat(export)!: run unity.export once per unit instead of once per bundle
nichinichisou0609 Oct 14, 2026
5197557
feat(assemble): add product stages assembled from the exported objects
nichinichisou0609 Oct 14, 2026
e5a0103
feat(link)!: find objects by their Resources.Load path
nichinichisou0609 Oct 15, 2026
786b7c1
feat(assemble): let a product keep some files of an object
nichinichisou0609 Oct 15, 2026
ca09564
feat(unity): name clip bindings in the hierarchy that plays the clip
nichinichisou0609 Oct 15, 2026
3342671
feat(live2d)!: assemble Live2D models from the exported objects
nichinichisou0609 Oct 15, 2026
93cfb75
feat(layout)!: list only the objects with files in a product manifest
nichinichisou0609 Oct 15, 2026
7d6cc58
feat(convert)!: write path ids as decimal strings in object JSON
nichinichisou0609 Oct 15, 2026
68d5d3b
feat(spot)!: assemble spots and rooms from the exported objects
nichinichisou0609 Oct 15, 2026
2e5872e
feat(pipeline)!: name built-in objects by class as product roots
nichinichisou0609 Oct 15, 2026
b39e8e4
fix(cri): remember the first bytes of raw files in the depot
nichinichisou0609 Oct 15, 2026
856ba89
refactor(formats): keep the web audio formats beside the encoders
nichinichisou0609 Oct 15, 2026
eba6c51
feat(live)!: assemble a music's BGM and the live sounds as products
nichinichisou0609 Oct 15, 2026
9d7a22d
feat(pipeline): name the root objects of each key in a product's obje…
nichinichisou0609 Oct 15, 2026
49d95a9
fix(pipeline): reach the sprites an atlas packs only from the atlas i…
nichinichisou0609 Oct 15, 2026
f280f06
feat(live): assemble the note highway, its skins and effect sets as p…
nichinichisou0609 Oct 15, 2026
c4992b2
feat(pipeline): give a scene key the objects of its scene
nichinichisou0609 Oct 15, 2026
17a7d06
fix(content): name in a shader table the shader a lookup by name finds
nichinichisou0609 Oct 15, 2026
23dd532
refactor(content): look up key objects and components across hierarchies
nichinichisou0609 Oct 15, 2026
ba41904
feat(live): assemble the live scene and each band's start timeline as…
nichinichisou0609 Oct 15, 2026
d2af354
feat(live): assemble a live as a product and export it through the pi…
nichinichisou0609 Oct 15, 2026
c352c4c
feat(unity): write a mesh's vertex channels and submeshes as its arra…
nichinichisou0609 Oct 15, 2026
b925d20
feat(pipeline): add the story.sound and story.crilips products
nichinichisou0609 Oct 15, 2026
7f7e187
test(pipeline): stub the ffmpeg lookup of the story sound atoms
nichinichisou0609 Oct 15, 2026
77eda5d
feat(pipeline): add the story.scene and story.asset products
nichinichisou0609 Oct 15, 2026
a4c3c0d
refactor(content): build story episodes from an object table
nichinichisou0609 Oct 15, 2026
f63bf53
refactor(pipeline): share the master record input of product stages
nichinichisou0609 Oct 15, 2026
87e7cbd
feat(pipeline): add the story and story.chat products
nichinichisou0609 Oct 15, 2026
0f95e99
test(pipeline): cover the story and story.chat products and the two-r…
nichinichisou0609 Oct 15, 2026
6299546
refactor(site): drop the model directory source of the story builder
nichinichisou0609 Oct 15, 2026
b8a82bf
docs: describe the story products and export story
nichinichisou0609 Oct 15, 2026
113d221
feat(pipeline): add the story.video product
nichinichisou0609 Oct 15, 2026
0aa8c75
test(pipeline): cover story.video and the movie inputs of product stages
nichinichisou0609 Oct 15, 2026
7bdd095
docs: describe story.video and the movie inputs of product stages
nichinichisou0609 Oct 15, 2026
cdaf74d
refactor(unity): share TMP font lookup, font records and texel packing
nichinichisou0609 Oct 15, 2026
094ce87
feat(content): read TextMesh Pro font assets from object tables
nichinichisou0609 Oct 15, 2026
be86b0d
test(content): cover font assets read from object tables
nichinichisou0609 Oct 15, 2026
0054c43
fix(story): include CRI categories in sound products
nichinichisou0609 Oct 17, 2026
7b88cf3
test(story): isolate AAC category checks from encoder discovery
nichinichisou0609 Oct 17, 2026
6c59292
feat(pipeline): fence font references in product closures
nichinichisou0609 Oct 17, 2026
bb50c82
feat(unity): read localization settings from builtin components
nichinichisou0609 Oct 17, 2026
b3e266d
feat(content): assemble localized story UI products
nichinichisou0609 Oct 17, 2026
291dd07
test(pipeline): cover localized UI and font reference closures
nichinichisou0609 Oct 17, 2026
d762f87
docs: describe font references and story UI products
nichinichisou0609 Oct 17, 2026
265d960
refactor(content): generate font pages from explicit inputs
nichinichisou0609 Oct 17, 2026
c054696
feat(content): export episode font products
nichinichisou0609 Oct 17, 2026
5b30392
docs: describe story font products and export options
nichinichisou0609 Oct 17, 2026
a7a97bc
refactor(content): share font inputs and glyph generation
nichinichisou0609 Oct 17, 2026
bf57318
feat(content): export localized live start UI products
nichinichisou0609 Oct 17, 2026
3f88cfb
docs: describe live UI products and font options
nichinichisou0609 Oct 17, 2026
0c3f3f9
feat(content): identify room nodes and materials
nichinichisou0609 Oct 17, 2026
ad388db
feat(content): export Overlay story host and UI products
nichinichisou0609 Oct 17, 2026
f0a03e0
docs: describe Overlay story products
nichinichisou0609 Oct 17, 2026
8a6f618
feat(ui): assemble libraries from shared object products
nichinichisou0609 Oct 18, 2026
cd90afc
docs(ui): link schema files from the documentation site
nichinichisou0609 Oct 18, 2026
fc67ea1
feat(site): store transformed assets as depot tasks
nichinichisou0609 Oct 18, 2026
dc7d91e
feat(site): assemble immutable product snapshots
nichinichisou0609 Oct 18, 2026
01d760b
feat(site): build named sites through depot product tasks
nichinichisou0609 Oct 18, 2026
061e5f5
refactor(site): centralize construction around depot products
nichinichisou0609 Oct 18, 2026
80458d5
refactor(fonts): open catalog inputs through the source session
nichinichisou0609 Oct 18, 2026
916ff41
fix(site): include story lifecycle commands in listings
nichinichisou0609 Oct 18, 2026
7df32ff
refactor(cache): keep conversion memoization within each process
nichinichisou0609 Oct 18, 2026
89a0a1b
test(cache): cover atomic writes through the shared file helpers
nichinichisou0609 Oct 18, 2026
7e51217
refactor(export): unify object products and font processing
nichinichisou0609 Oct 18, 2026
44d6a4a
feat(depot): release completed bundle downloads during exports
nichinichisou0609 Oct 18, 2026
bec1dc5
fix(release): import the packaged deck data module
nichinichisou0609 Oct 18, 2026
6eb4296
chore(release): prepare nnnotes v0.3.0
nichinichisou0609 Oct 18, 2026
19decb9
feat(depot): share catalog versions through remotes
nichinichisou0609 Oct 18, 2026
d97b076
fix(depot): retain planned and standalone task results
nichinichisou0609 Oct 18, 2026
8e17b91
fix(depot): publish stored inputs with emitted tasks
nichinichisou0609 Oct 18, 2026
e559c73
chore(release): align the dependency lock and depot notes
nichinichisou0609 Oct 18, 2026
472997d
feat(schema): ship shared product document contracts
nichinichisou0609 Oct 18, 2026
b0454bb
docs(schema): list every packaged product contract
nichinichisou0609 Oct 18, 2026
1ae3260
fix: retain depot results and align product exports
nichinichisou0609 Oct 18, 2026
1d32ea5
test: cover output stages with golden records
nichinichisou0609 Oct 18, 2026
64f56ec
fix: include native PNG codecs in task identities
nichinichisou0609 Oct 18, 2026
f9f977e
fix: annotate codec probe search paths
nichinichisou0609 Oct 18, 2026
d904d8e
fix: report S3 object deletion failures
nichinichisou0609 Oct 19, 2026
4d1b1d5
docs: explain depot exports and player site setup
nichinichisou0609 Oct 19, 2026
13751da
docs: keep package page links and data guarantees explicit
nichinichisou0609 Oct 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .github/goldens-constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ Pillow==12.3.0
numpy==2.4.6
texture2ddecoder==1.0.6
astc-encoder-py==0.1.12
fonttools==4.67.0
freetype-py==2.5.1
scipy==1.18.1
3 changes: 2 additions & 1 deletion .github/scripts/smoke_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

import nnnotes
import ournotes_sim
from nnnotes import deckdata, musicdata
from nnnotes import musicdata
from nnnotes.musicdata import deckdata

assert Path(nnnotes.__file__).resolve().is_relative_to(Path(sys.prefix).resolve())
deck = musicdata.Deck(workers=1, aptitude=False)
Expand Down
9 changes: 6 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Install (with the deck model and the fonts extra)
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[test,deck,fonts]"
python -m pip install -e ".[test,deck,fonts,remote]"
- name: Lint
run: |
python -m ruff check .
Expand All @@ -55,7 +55,7 @@ jobs:
- name: Install
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[test,deck,fonts]"
python -m pip install -e ".[test,deck,fonts,remote]"
- name: Type check
run: python -m pyright

Expand All @@ -65,6 +65,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: "24"
- uses: actions/setup-python@v7
with:
python-version: "3.13"
Expand All @@ -75,7 +78,7 @@ jobs:
- name: Install (pinned)
run: |
python -m pip install --upgrade pip
python -m pip install -c .github/goldens-constraints.txt -e ".[test]"
python -m pip install -c .github/goldens-constraints.txt -e ".[test,fonts]"
- name: Golden records
env:
GOLDENS_STRICT: "1"
Expand Down
35 changes: 33 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,39 @@ All notable changes to this project are listed here. Versions follow [Semantic V
over the command line (commands, options, exit statuses and `--json` reports), the configuration keys, the JSON
schemas in `nnnotes.schemas` and the documented Python API. Before 1.0 a minor version can change any of them.

## [0.3.0](https://github.com/MetaSekaiLab/nnnotes/compare/v0.2.5...v0.3.0) - 2026-10-19

### Compatibility

- Configure persistent storage with `[paths] depot` and optional `[depot] remote`. Manage it with `depot plan`, `depot run`, `depot verify` and `depot gc`.
- Exported products use `nnnotes.product/1` manifests and shared object references. Browser playback uses ournotes-player 0.2.x.
- Build named sites with `site build --name NAME -o DIR`. Copy selected source bundles with `bundle pull -o DIR`.
- The `deck` extra uses ournotes-sim 0.0.12.

### Features

- Report per-object S3 deletion failures during depot collection.
- Keep PNG and font task results distinct across native compression library implementations.
- Export episode documents, shader files and cue-sheet audio through depot tasks and retained file layouts.
- Share cached results when adding remote storage, verify remote-only content, and retain recent results with their dependencies during collection.
- Validate player package compatibility and publish chart metadata and requested language references consistently.
- Ship schemas for shared product root documents and prefab objects, with numeric font and transform contracts.
- Share catalog versions and labels through depot remotes, with verified catalog files fetched on demand.
- Retain census planning results, emitted task descriptions and standalone task runs as depot collection roots.
- Store content, task inputs, results and catalog versions in a persistent depot with optional remote storage, verified collection and bounded source downloads.
- Release recoverable bundle downloads after successful conversion batches under the configured budget and command leases.
- Assemble Live2D, room, spot, live, story and UI products from shared object tables and explicit manifest references.
- Generate localized live and story text products with game or supplied fonts, shared glyph atlases and material records.
- Build named sites through depot product, player read-set, asset and index tasks.
- Retain unselected regional topics, publish immutable product dependencies in order, and restore complete sites from their saved depot layouts.
- Offer Live variant products from chart manifests and select story UI/font languages explicitly.

### Architecture

- Site construction uses shared product requests, named depot catalogs and ordered layout publication. Player page collection and catalog model queries have dedicated interfaces.
- Conversion memoization is bounded within each process, with persistent reuse provided by depot task results.
- Product assembly consumes stored class-converter outputs. Font lookup, texel packing and material construction share object-based implementations.

## [0.2.1](https://github.com/MetaSekaiLab/nnnotes/compare/v0.2.0...v0.2.1) - 2026-10-13

### Build
Expand Down Expand Up @@ -195,5 +228,3 @@ schemas in `nnnotes.schemas` and the documented Python API. Before 1.0 a minor v
- List MetaMiku as an author ([cc43e13](https://github.com/MetaSekaiLab/nnnotes/commit/cc43e132875206d02d8665b19c06b27255ab0037))
- Point the project links at MetaSekaiLab/nnnotes ([a2b8304](https://github.com/MetaSekaiLab/nnnotes/commit/a2b83040bcf06771028bbfd5e90c10c225bde3e9))
- English package readme; check commits on pull requests only ([e602dd5](https://github.com/MetaSekaiLab/nnnotes/commit/e602dd5ebf6dda0f18da5ace54a02dbb893a796f))


4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ mkdocs build --strict # the documentation site
- **Golden records.** `tests/golden/` records the output of each stage version. When a change alters a stage's
output, raise that stage's (or converter's) version and rewrite the records with
`GOLDENS_UPDATE=1 pytest tests/pipeline/test_goldens.py`, using the library versions of
`.github/goldens-constraints.txt` (`pip install -c .github/goldens-constraints.txt -e ".[test]"`).
`.github/goldens-constraints.txt` (`pip install -c .github/goldens-constraints.txt -e ".[test,fonts]"`).
Node.js runs the synthetic read-set fixture. CI uses Node.js 24 and Python 3.13 for these records.
PNG-dependent records also use the native `Pillow.zlib` identity listed in their library versions.
- **Command reference.** `docs/cli.md` is generated from the parser. After changing a command or an option, run
`python -m nnnotes.cli.reference docs/cli.md`; a test fails while the file is out of date.

Expand Down
163 changes: 81 additions & 82 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,100 +1,99 @@
# nnnotes?!
# nnnotes

[English](https://github.com/MetaSekaiLab/nnnotes/blob/main/README.md) | [简体中文](https://github.com/MetaSekaiLab/nnnotes/blob/main/README.zh-CN.md)

nnnotes is an offline data toolkit for the game files of BanG Dream! Our Notes. It reads Addressables catalogs,
downloads and decrypts asset bundles, downloads and decodes master data, and exports stories, Live2D models, spots,
shaders, CRI audio and live charts as structured JSON and common file formats. `nnnotes site build` writes the static
site that [ournotes-player](https://github.com/empty-sekai/ournotes-player) plays, and `nnnotes music-data` one JSON
file with every song and chart. The name was inspired by sssekai.
nnnotes turns your BanG Dream! Our Notes game files into structured data, media and static player sites.
It reads Addressables catalogs, bundles, master data and APK resources; exports stories, Live2D models, live
charts, rooms, UI, shaders and audio; and assembles sites for
[ournotes-player](https://github.com/empty-sekai/ournotes-player).

This is an unofficial fan project, not affiliated with the game's developer or operator. The repository contains no
game assets, keys or server addresses: you supply the game files, the keys and the server addresses in your own
configuration, and the exports stay in the local directories you choose.
A persistent **depot** stores converted objects, task results and catalog versions. Exports share these results,
and named sites retain their selected products across builds. A depot can also share work through a directory
or S3-compatible object storage.

**Documentation: <https://metasekailab.github.io/nnnotes/>**
**[Documentation](https://metasekailab.github.io/nnnotes/)** ·
[Quick start](https://metasekailab.github.io/nnnotes/quickstart/) ·
[Commands](https://metasekailab.github.io/nnnotes/cli/)

## Install

Python 3.11 or newer:

```sh
pip install nnnotes # Python 3.11+
pip install 'nnnotes[fonts]' # the game's fonts (--fonts game) and the story text of site build
pip install 'nnnotes[deck]' # the deck model's chart statistics of music-data
pip install nnnotes==0.3.0
pip install 'nnnotes[fonts]==0.3.0' # story and UI fonts
pip install 'nnnotes[remote]==0.3.0' # S3-compatible depot storage
pip install 'nnnotes[deck]==0.3.0' # music-data chart statistics
```

nnnotes also needs the game's `base.apk`, decoded master data for the commands that read it, and the external tools
[vgmstream](https://vgmstream.org/) and [FFmpeg](https://ffmpeg.org/) for audio and video (Node.js 20+ and a built
ournotes-player for `site build`).
Choose the extras your commands need; they can be combined as `nnnotes[fonts,remote,deck]==0.3.0`.
Audio/video conversion uses [vgmstream](https://vgmstream.org/) and [FFmpeg](https://ffmpeg.org/).
Site builds additionally require Node.js 22+ and a built **ournotes-player 0.2.x** package.
The deck extra installs `ournotes-sim==0.0.12`.

## First export

## Quick start
Supply your own client files, keys and server addresses through the configuration wizard:

```sh
nnnotes config init --user # asks for each setting (keys without echo) and writes the per-user config file
nnnotes config check # where each setting comes from and whether it is valid, never its value
nnnotes config init --user
nnnotes config check
nnnotes master download --latest -o work/master-bin
nnnotes master decode work/master-bin -o work/master
nnnotes --master work/master export story 10462 -o out/story_10462
nnnotes site build -o out/site --all --player path/to/ournotes-player
nnnotes config set paths.master work/master
nnnotes export episode 10462 -o out/episode.json
nnnotes export story 10462 --fonts game -o out/story
```

Set `paths.depot` to a persistent directory and `paths.apk` to your game APK. The wizard reads keys without echo;
`config check` reports setting names, origins and validity. Story export requires the `fonts` extra and audio
tools. See the [quick start](https://metasekailab.github.io/nnnotes/quickstart/) for prerequisites and output layout.

## Build a player site

```sh
npm install ournotes-player@0.2.0
nnnotes site build --name stories -o out/site --story 10462 --fonts game --player node_modules/ournotes-player
node node_modules/ournotes-player/scripts/validate-data.mjs out/site
python -m http.server 8000 --directory out/site
```

Every command prints a short summary, or with `--json` its report as JSON. Scripts set the config file without
questions: `nnnotes config init --user --no-input --set SECTION.KEY=VALUE ...`.

## Commands

| Command | What it does |
| --- | --- |
| `config init\|set\|unset\|check\|path` | write, edit and check the config file |
| `servers` | the game API's server list: regions with their CDN and API roots |
| `catalog keys\|browse` | the addressable keys of a region's catalog; a local web page to browse catalogs and bundles |
| `catalog versions\|import\|fetch\|diff` | catalog versions kept in the store, and what changed between two |
| `bundle pull` | fetch and decrypt the bundle closure of keys into the cache |
| `master version\|download\|decode` | the master data version a region serves, its download and its decoding to JSON |
| `export assets` | every object of the selected bundles in common formats, through the content-addressed store |
| `export episode\|story\|live\|live2d\|spot\|room\|shader\|audio\|ui` | one subject: an ADV episode, a story, a live, a Live2D model, a spot, a room, shaders, a cue sheet, the UI library |
| `apk settings\|hca-key` | the player's graphics settings and the CRI HCA keycode of `base.apk` |
| `store plan\|run\|verify` | what `export assets` would run and why, single tasks, the store's check |
| `voices list\|search\|summary\|get` | the character and story voices of the master data |
| `site build` | the static site of ournotes-player: charts, Live2D models and stories, in several regions and languages |
| `music-data` | every song and chart in one JSON file, with the deck model's chart statistics |

The [command reference](https://metasekailab.github.io/nnnotes/cli/) lists every option.

## Documentation

- [Quick start](https://metasekailab.github.io/nnnotes/quickstart/): from an empty config to an exported story.
- How-to guides: [configure nnnotes](https://metasekailab.github.io/nnnotes/configuration/),
[export stories and lives](https://metasekailab.github.io/nnnotes/export/),
[build an ournotes-player site](https://metasekailab.github.io/nnnotes/site/),
[export every asset](https://metasekailab.github.io/nnnotes/assets/),
[the Japanese release](https://metasekailab.github.io/nnnotes/jp/),
[music data](https://metasekailab.github.io/nnnotes/music-data/).
- Reference: [commands](https://metasekailab.github.io/nnnotes/cli/),
[command outputs](https://metasekailab.github.io/nnnotes/commands/),
[JSON schemas](https://metasekailab.github.io/nnnotes/schemas/),
[Python API](https://metasekailab.github.io/nnnotes/api/),
[contracts](https://metasekailab.github.io/nnnotes/contracts/), [stages](https://metasekailab.github.io/nnnotes/stages/),
[views](https://metasekailab.github.io/nnnotes/views/).
- Explanation: [architecture](https://metasekailab.github.io/nnnotes/architecture/),
[determinism](https://metasekailab.github.io/nnnotes/determinism/),
[validation](https://metasekailab.github.io/nnnotes/validation/).

Exports are deterministic for a given installation: the same input with the same versions of nnnotes, its Python
dependencies (UnityPy, Pillow, numpy, ...) and the external tools gives byte-identical files; JSON is UTF-8 with LF
line endings and non-finite numbers written as `1e999`. Other versions can encode the same content into other bytes
(PNG files written by another Pillow version can differ in their bytes while their pixels are equal).

## Changelog and versions

[CHANGELOG.md](https://github.com/MetaSekaiLab/nnnotes/blob/main/CHANGELOG.md) lists the changes of every version.
Versions follow [Semantic Versioning](https://semver.org/) over the command line, the configuration keys, the JSON
schemas and the documented Python API.

## Contributing

Setup, checks and commit conventions are in
[CONTRIBUTING.md](https://github.com/MetaSekaiLab/nnnotes/blob/main/CONTRIBUTING.md).

## License

MIT, see [LICENSE](https://github.com/MetaSekaiLab/nnnotes/blob/main/LICENSE).
Open `http://localhost:8000/story/`. Live2D, MotionSync and Spine features require the corresponding browser
runtimes supplied by the embedding page. See the [site guide](https://metasekailab.github.io/nnnotes/site/).
Use `--pair MUSIC_ID:DIFFICULTY` for a chart, `--live2d KEY` for a model, and `--story-languages ja,en` for selected
story languages. Reusing a site name updates selected topics and retains the others.

## Choose a workflow

| Task | Commands | Guide |
|---|---|---|
| Configure inputs | `config init`, `config check`, `servers` | [Configuration](https://metasekailab.github.io/nnnotes/configuration/) |
| Inspect or retain catalogs | `catalog keys`, `browse`, `versions`, `import`, `fetch`, `diff` | [Commands](https://metasekailab.github.io/nnnotes/cli/) |
| Copy source bundles | `bundle pull` | [Asset export](https://metasekailab.github.io/nnnotes/assets/) |
| Export a subject | `export episode`, `story`, `live`, `live2d`, `spot`, `room`, `shader`, `audio`, `ui` | [Exports](https://metasekailab.github.io/nnnotes/export/) |
| Convert selected assets | `export assets`, `depot plan`, `depot run` | [Asset export](https://metasekailab.github.io/nnnotes/assets/) |
| Check and retain stored work | `depot verify`, `depot gc` | [Depot](https://metasekailab.github.io/nnnotes/depot/) |
| Export song and chart statistics | `music-data` | [Music data](https://metasekailab.github.io/nnnotes/music-data/) |
| Find character voices | `voices list`, `search`, `summary`, `get` | [Commands](https://metasekailab.github.io/nnnotes/cli/) |

Commands print summaries; `--json` selects a structured report. The reference describes exit statuses and options.

## Data and compatibility

Product exports use versioned manifests and shared object records. Read the
[format reference](https://metasekailab.github.io/nnnotes/formats/),
[product reference](https://metasekailab.github.io/nnnotes/products/) and
[schemas](https://metasekailab.github.io/nnnotes/schemas/) to consume them.
Task identities include input contents, options and conversion implementations, including native encoders.
Byte-identical output requires matching inputs and library/tool implementations, including Pillow and its native
compression backend. JSON uses UTF-8 and LF; infinite values use `1e999` or `-1e999`.
[Determinism](https://metasekailab.github.io/nnnotes/determinism/) explains reproducibility across installations.

Versions cover the CLI, configuration, schemas and documented Python API. Before 1.0, a minor version can change
these interfaces. See [CHANGELOG.md](https://github.com/MetaSekaiLab/nnnotes/blob/main/CHANGELOG.md) and the [architecture](https://metasekailab.github.io/nnnotes/architecture/).

## Contributing and license

[CONTRIBUTING.md](https://github.com/MetaSekaiLab/nnnotes/blob/main/CONTRIBUTING.md) describes development and synthetic tests. nnnotes is licensed under
[MIT](https://github.com/MetaSekaiLab/nnnotes/blob/main/LICENSE). This is an unofficial fan project, unaffiliated with the game's developer or operator.
Game resources, keys and server configuration are supplied by each user and are subject to their owners' rights.
Loading
Loading