template/.planning/codebase/STRUCTURE.md

218 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Codebase Structure
**Analysis Date:** 2026-09-07
## Directory Layout
```
mota-ts/
├── src/ # Game entry code (@user/main): entry points + content data
│ ├── main.ts # Render/client entry
│ ├── data.ts # Data entry (replay verification, runs in Node)
│ ├── App.vue # Vue UI root (legacy UI stack)
│ ├── data.ts # (data-end entry)
│ ├── styles.less # Global styles
│ ├── content/ # New JSONC game content (core/enemy/item/tile/maps)
│ ├── types/ # Generated + declared typings (source/, declaration/)
│ └── package.json # name: @user/main
├── packages/ # Core engine monorepo (@motajs/*)
│ ├── common/ # utils, logger, hook, dirtyTracker
│ ├── legacy-common/ # Patch system, legacy EventEmitter, utils
│ ├── types/ # shared types (enemy, utils)
│ ├── client/ # re-export of client-base
│ ├── client-base/ # glUtils, keyCodes, types (KeyCode)
│ ├── system/ # action (hotkey/keyboard) + ui (UIController/GameUI)
│ ├── render/ # WebGL/Canvas MotaRenderer + assets + style
│ ├── render-vue/ # custom Vue renderer over IRenderItem
│ ├── animate/ # excitation/animation
│ ├── audio/ # audio context, decoders, bgm/effect/sound
│ ├── loader/ # LoadTask, progress, stream
│ ├── legacy-client/ # re-export of legacy-system + legacy-ui
│ ├── legacy-system/ # keyboard.vue, storage
│ └── legacy-ui/ # Vue components/panels/presets/tools/ui
├── packages-user/ # User game code monorepo (@user/*)
│ ├── entry-client/ # composition root (render): createGame()
│ ├── entry-data/ # composition root (data): Mota registry, createData()
│ ├── client-base/ # render system layer: load/ + material/
│ ├── client-modules/ # render impl layer: render/ + action/ + fallback/
│ ├── data-common/ # data L0: common/ event/ replay/ save/ store/
│ ├── data-base/ # data L1: game/ map/ hero/ enemy/ flag/ load/
│ ├── data-system/ # data L2: combat/ + trigger/
│ ├── data-state/ # data L3: CoreState singleton + enemy/hero/legacy
│ ├── data-fallback/ # patch legacy globals onto new state
│ ├── legacy-plugin-client/ # dev hot reload
│ └── legacy-plugin-data/ # legacy plugins: shop/replay/fiveLayer/hook
├── public/ # Legacy mota-js sample content + editor assets
│ ├── main.js # legacy mota-js runtime (core/main globals)
│ ├── editor.html # legacy editor
│ ├── project/ # data.js/enemys.js/events.js/items.js/maps.js + assets
│ ├── libs/ # thirdparty libs (lz-string, lodash, localforage…)
│ ├── extensions/ # legacy extensions
│ ├── _server/ # editor server config
│ └── _docs/ # editor-embedded docs
├── script/ # Build/dev tooling (tsx scripts)
│ ├── dev.ts # Vite + Express + WS dev servers
│ ├── build-game.ts # full game build → dist.zip
│ ├── build-lib.ts # library build for packages + packages-user
│ ├── build-packages.ts # library build for packages only
│ ├── build-resource.ts # resource splitting/compression
│ ├── declare.ts # regenerate src/types/source/*.d.ts from public/project/*.js
│ ├── pack-template.ts # pack the template/ directory
│ ├── lines.ts # line-count utility
│ ├── special.ts / types.ts / utils.ts
│ └── template/ # legacy template runtime (main.js, data.js, 启动服务.exe)
├── template/ # Copy of a fresh template project (for pack:template)
├── docs/ # Vitepress documentation site
├── .planning/ # GSD planning state (config.json, graphs/, codebase/)
├── graphify-out/ # Knowledge-graph output (manifest, graph.json/html)
├── _bundle/ # Dev rollup output (ignored)
├── index.html # HTML entry (canvas + Vue root + legacy scripts)
├── vite.config.ts # Vite config + @motajs/@user path aliases
├── tsconfig.json # TS project config + path aliases
├── tsconfig.node.json # Node-side TS config
├── eslint.config.js # ESLint flat config
├── pnpm-workspace.yaml # workspace: packages/*, packages-user/*, src/
├── package.json # root scripts + shared deps
└── dev.md # Project dev conventions/architecture doc (read first)
```
## Directory Purposes
**`src/`:**
- Purpose: The game entry point and game content. Package name `@user/main`.
- Contains: `main.ts` (client entry), `data.ts` (data entry), `App.vue`, `styles.less`, `content/` (JSONC data), `types/` (typings).
- Key files: `src/main.ts`, `src/data.ts`, `src/App.vue`, `src/package.json`.
**`packages/` (core engine, `@motajs/*`):**
- Purpose: The reusable engine core — utilities, render system, audio, animation, input/UI systems, loader, and the legacy bridge.
- Contains: one directory per package, each with `src/` and its own `package.json`.
- Key files: `packages/render/src/core/render.ts`, `packages/system/src/action/hotkey.ts`, `packages/legacy-common/src/patch.ts`.
**`packages-user/` (user code, `@user/*`):**
- Purpose: The game-specific implementation layered over the engine — data end (L0L3) and render end (system + impl), plus composition roots.
- Contains: one directory per package; each `src/` mirrors its layer's responsibility.
- Key files: `packages-user/entry-data/src/mota.ts`, `packages-user/data-state/src/core.ts`, `packages-user/client-modules/src/index.ts`.
**`public/`:**
- Purpose: The legacy mota-js sample game content and runtime, plus editor assets. Not TypeScript — these are the uncompiled game files the engine loads.
- Contains: `main.js` (legacy runtime), `project/` (data, enemys, events, items, maps, floors, images, sounds, bgms, autotiles, tilesets, materials, animates), `libs/thirdparty/`, `extensions/`, `_server/`, `_docs/`, `editor.html`, `styles.css`, `logo.png`.
- Key files: `public/main.js`, `public/project/data.js`, `public/project/maps.js`.
**`script/`:**
- Purpose: Build/dev tooling run via `tsx` (`pnpm dev`, `pnpm build:game`, `pnpm declare`, …).
- Contains: `dev.ts` (dev servers + hot reload), `build-game.ts` (game packaging), `build-resource.ts` (asset splitting), `declare.ts` (type generation), `pack-template.ts`, and helpers.
- Key files: `script/dev.ts`, `script/build-game.ts`, `script/declare.ts`.
**`docs/`:**
- Purpose: Vitepress documentation site (`docs:dev` / `docs:build`), including API docs per package, dev guides, and logger error-code reference.
- Contains: `.vitepress/`, `api/`, `dev/`, `guide/`, `logger/`.
**`template/`:**
- Purpose: A standalone copy of a fresh template project, packaged by `script/pack-template.ts` (`pnpm pack:template`).
- Contains: its own `src/`, `script/`, `vite.config.ts`, `package.json`, etc.
**`.planning/`:**
- Purpose: GSD workflow state — `config.json` (workflow toggles), `graphs/` (project knowledge graph), `codebase/` (these analysis docs). Do not hand-edit during normal development.
## Key File Locations
**Entry Points:**
- `src/main.ts`: Render/client entry — `createGame()` + Vue mount.
- `src/data.ts`: Data entry — replay verification, Node-only.
- `index.html`: HTML shell — canvas `#render-main`, Vue `#root`, legacy scripts.
- `packages-user/entry-client/src/create.ts`: Client composition (`createGame`).
- `packages-user/entry-data/src/mota.ts`: Module registry (`Mota`, `r`, `rf`).
**Configuration:**
- `vite.config.ts`: Vite + auto-generated `@motajs/*`/`@user/*` aliases (from `packages/*/src` and `packages-user/*/src`).
- `tsconfig.json`: path aliases `@motajs/*``./packages/*/src`, `@user/*``./packages-user/*/src`.
- `pnpm-workspace.yaml`: workspace globs.
- `package.json`: root scripts (`dev`, `build:game`, `build:lib`, `build:packages`, `declare`, `check:circular`, `lint:*`).
- `eslint.config.js`, `.prettierrc`, `.madgerc`.
**Core Logic:**
- `packages-user/data-state/src/core.ts`: `CoreState` (data-end composition).
- `packages-user/data-base/src/game.ts`: `loading`, `hook`, `gameListener`.
- `packages-user/data-common/src/save/system.ts`: `SaveSystem` (Dexie persistence).
- `packages-user/data-common/src/replay/system.ts`: `ReplaySystem`.
- `packages/render/src/core/render.ts`: `MotaRenderer`.
- `packages/system/src/action/hotkey.ts`: `Hotkey` (input).
**Testing:**
- Root `package.json` defines `pnpm test``vitest`. (See `TESTING.md` for details; not the focus of this doc.)
## Naming Conventions
Conventions are defined in `dev.md` (authoritative) and escalated in `.agents/code.md`.
**Files:**
- Code files: **camelCase** (e.g. `mapStore.ts`, `hotkey.ts`, `build-game.ts`).
- Markdown folders/files: **kebab-case** (e.g. `docs/dev/`, `my-notes.md`).
- One class per file; multiple trivial implementations of the same interface in one file only after confirmation (`.agents/code.md` #6).
**Directories:**
- Package directories: lowercase single word (e.g. `client-modules`, `legacy-ui`), kebab-case for multi-word.
- Source subfolders group by feature/domain (e.g. `render/map/`, `data-state/enemy/`), not by modifier type.
**Identifiers (from `dev.md`):**
- Variables, members, general constants, methods, functions: **camelCase**.
- Classes, interfaces, type aliases, namespaces, generics, enums, comments: **PascalCase**.
- Immutable constants: **UPPER_SNAKE_CASE** (e.g. `MAX_COUNT`); acronyms all-caps (`HTTP`, `URI`).
- Interfaces meant to be `implements`-ed: **prefixed with `I`** (e.g. `IGameMap`, `IEnemyManager`, `ICoreState`).
- HTML/CSS `id`/`class`: **kebab-case**.
- No underscore naming; private members/methods do **not** start with underscore.
## Where to Add New Code
**New engine feature (core, reusable):**
- Implementation: `packages/<package>/src/` under the appropriate package (e.g. render primitives in `packages/render/src/core/`).
- Export it from the package `index.ts` (e.g. `packages/render/src/index.ts`).
- Update `packages/<package>/package.json` dependencies if it now depends on another `@motajs/*` package.
**New user/game feature:**
- Data logic → `packages-user/data-system/src/` (Layer 2) or extend `packages-user/data-state/src/` (Layer 3).
- Saveable data structures → `packages-user/data-base/src/` (Layer 1).
- Shared/utility interfaces → `packages-user/data-common/src/` (Layer 0).
- Rendering/UI → `packages-user/client-modules/src/render/` (impl layer) or `packages-user/client-base/src/` (system layer).
- Register new modules in `packages-user/entry-data/src/create.ts` and/or `packages-user/entry-client/src/create.ts` so they are available via `Mota`.
**New content (game data):**
- New JSONC content: `src/content/` (e.g. `src/content/item.jsonc`, `src/content/maps/`).
- Legacy content editing: `public/project/` (regenerate types with `pnpm declare`).
**Utilities:**
- Generic shared helpers → `packages/common/src/utils/` (or `packages/common/src/` for `logger`/`hook`).
- Legacy compatibility helpers → `packages/legacy-common/src/`.
**Tests:**
- Co-located or under a `test`/`__tests__` folder as the existing `vitest` config expects; run with `pnpm test`.
**Documentation:**
- API docs → `docs/api/` (one folder per package is generated); dev guides → `docs/dev/`; error codes → `docs/logger/`.
## Special Directories
**`node_modules/` (workspace + per-package):**
- Purpose: pnpm-installed dependencies; per-package `node_modules/@motajs/*` and `@user/*` are symlinks to sibling workspace packages.
- Generated: Yes. Committed: No.
**`_bundle/`:**
- Purpose: Dev rollup output produced by `script/dev.ts` (`getEsmFile`).
- Generated: Yes. Committed: No.
**`_temp/` / `dist/` / `dist.zip`:**
- Purpose: Build intermediates (`_temp/`) and game output (`dist/`, `dist.zip`) from `script/build-game.ts`.
- Generated: Yes. Committed: No.
**`.planning/`:**
- Purpose: GSD workflow state (config, graphs, codebase docs).
- Generated: Partly (by GSD commands). Committed: Yes (config and docs are committed by GSD).
**`graphify-out/`:**
- Purpose: Knowledge-graph build output (`graph.json`, `graph.html`, `manifest.json`).
- Generated: Yes. Committed: Varies (check `.gitignore`).
---
*Structure analysis: 2026-09-07*