A web-based build optimizer for Zenless Zone Zero (ZZZ). Import your agents, discs, and w-engines, then let the optimizer find the best builds — damage, survivability, or your own custom goals.
Fork of hsr-optimizer and genshin-optimizer.
- React 19 + TypeScript (strict) — frontend
- Nx 23 monorepo, Vite 8 build, bun as package manager
- Mantine v9 UI, Tabler icons, ag-grid
- Zustand v5 state, zod validation, i18next localization
- Jest / Vitest tests, Cypress e2e, Playwright WebGPU e2e
Prerequisites: bun (package manager is bun — never use npm/yarn).
# Install dependencies
bun install
# Initialize datamine data submodules (required for dev/build)
bun run reload-dm
# Start the dev server on :4200
bun nx serve zzz-frontend
# Production build
bun nx build zzz-frontend
gen-fileand full builds depend on the datamine submodule (packages/zzz/dm/src/NanokaData). Runbun run reload-dmfirst if it is not initialized.
app/ # Frontend application (Vite + React + Mantine)
src/app/ # Shell: router, layout, navigation
src/page-*/ # Pages: characters, discs, optimize, ...
packages/
common/ # Shared utilities (database, UI, pipeline, localization)
game-opt/ # Optimizer logic (engine, formula, solver, sheet-ui)
pando/engine/ # Pando calculation engine
zzz/*/ # ZZZ domain libs (db, formula, solver, stats,
# consts, schema, assets, dm, pages-*, ui, ...)
src/NanokaData/ # git submodule (in zzz/dm) — datamine data
Path aliases: @zenless-optimizer/<scope>/<name> → packages/<scope>/<name>/src/index.ts (see tsconfig.base.json).
bun run mini-ci # Local CI: format+organize imports → affected eslint:lint → affected typecheck+test
bun run test # Run all tests (nx run-many)
bun nx serve zzz-frontend # Dev server on :4200
bun nx build zzz-frontend # Production build
bun nx graph # Dependency graph
# Single package
npx nx test <project> # e.g. npx nx test zzz-stats
npx nx typecheck <project> # e.g. npx nx typecheck zzz-frontend
npx nx eslint:lint <project> # ESLint with --max-warnings=0
# Formatting (Biome)
bun biome ci # Format check only (read-only)
bun biome format --write # Auto-format
bun biome check --write --formatter-enabled=true --linter-enabled=false --assist-enabled=true # Format + organize imports
# Codegen & data
bun run gen-file # Regenerate generated files (needs submodule data)
bun nx run zzz-dm:get-nanoka # Fetch Nanoka datamine JSON into packages/zzz/dm/src/NanokaData
bun run reload-dm # git submodule update --init
bun run update-dm # git submodule update --remote
# E2E
bun run e2e:webgpu # Playwright WebGPU e2eAGENTS.md— project conventions, CI workflow, and agent routing rulespackages/pando/engine/doc/— Pando engine architecture (tags, nodes, propagation, optimization)packages/pando/doc/— Pando calculation model (name-scoped buffs, damage survey)packages/game-opt/doc/overview.md— game-opt layer (typed authoring API, solver)docs/dev/character-wengine-implementation-guide.md— adding characters/W-Enginesdocs/dev/formula-ui-character-sheet-guide.md— formula UI sheetsgpusolver.md— WebGPU solver design notes
- Formatter: Biome (single quotes,
asNeededsemicolons, trailing commas es5, 2-space indent, 80-char width). Biome's linter is disabled — linting is done by ESLint only. - Linter: ESLint with
@nx/typescriptrules,unused-imports(unused imports are errors), and module boundary enforcement. - TypeScript 5.7+ strict mode:
exactOptionalPropertyTypes,noImplicitReturns,noPropertyAccessFromIndexSignature. - Tests:
bun testeverywhere (--jsdomwhere DOM is needed). Test files are*.spec.ts/*.test.ts.
.github/workflows/ci.yml runs on push/PR to master: install → lint (eslint) → typecheck → test → build → gen-file check → format check (biome ci). Locally, bun run mini-ci runs the same checks scoped to nx affected packages.