mirror of
https://github.com/motajs/template.git
synced 2026-09-15 11:28:50 +08:00
218 lines
13 KiB
Markdown
218 lines
13 KiB
Markdown
# 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 (L0–L3) 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*
|