# 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//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.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*