sapdon 3.2.2 → 3.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +245 -121
- package/doc/dev/architecture.md +415 -0
- package/doc/dev/cli.md +467 -0
- package/doc/dev/core.md +717 -0
- package/doc/dev/oc.md +582 -0
- package/doc/user/api/biome.md +558 -0
- package/doc/user/api/block.md +945 -0
- package/doc/user/api/entity.md +685 -0
- package/doc/user/api/extra.md +231 -0
- package/doc/user/api/item.md +896 -0
- package/doc/user/api/recipe.md +427 -0
- package/doc/user/api/texture.md +181 -0
- package/doc/user/config/build-config.md +84 -0
- package/doc/user/config/mod-info.md +33 -0
- package/doc/user/faq.md +160 -0
- package/doc/user/quick-start.md +108 -0
- package/doc/user/tutorials/block.md +463 -0
- package/doc/user/tutorials/entity.md +356 -0
- package/doc/user/tutorials/item.md +449 -0
- package/doc/user/tutorials/recipe.md +278 -0
- package/package.json +4 -3
- package/prod/cli/index.js +1 -1
- package/prod/cli/start.js +1 -1458
- package/prod/core/index.d.ts +3290 -2150
- package/prod/core/index.js +1 -59015
- package/prod/core/package.json +7 -0
- package/prod/oc/index.d.ts +348 -108
- package/prod/oc/index.js +1 -1
- package/prod/oc/package.json +7 -0
- package/prod/utils/index.d.ts +20 -2
- package/prod/utils/index.js +1 -1
- package/prod/utils/package.json +7 -0
- package/doc/BlockAPI.md +0 -145
- package/doc/api.md +0 -128
- package/doc/oc/index.md +0 -0
- package/doc/sapdon-ts.md +0 -64
- package/src/templates/js_sapdon/build.config +0 -23
- package/src/templates/js_sapdon/main.mjs +0 -4
- package/src/templates/js_sapdon/mod.info +0 -7
- package/src/templates/js_sapdon/pack_icon.png +0 -0
- package/src/templates/js_sapdon/package.json +0 -20
- package/src/templates/js_sapdon/res/animations/animation_item.animation.json +0 -34
- package/src/templates/js_sapdon/res/animations/large_item.animation.json +0 -27
- package/src/templates/js_sapdon/res/models/blocks/crop.geo.json +0 -48
- package/src/templates/js_sapdon/res/models/entity/animation/animation_item.geo.json +0 -26
- package/src/templates/js_sapdon/res/models/entity/animation/large_item.geo.json +0 -28
- package/src/templates/js_sapdon/res/textures/blocks/none.png +0 -0
- package/src/templates/js_sapdon/res/textures/blocks/test_log_oak.png +0 -0
- package/src/templates/js_sapdon/res/textures/blocks/test_log_top.png +0 -0
- package/src/templates/js_sapdon/res/textures/items/masterball.png +0 -0
- package/src/templates/js_sapdon/scripts/custom_components/cropComponent.js +0 -50
- package/src/templates/js_sapdon/scripts/custom_components/items/gui_book.js +0 -37
- package/src/templates/js_sapdon/scripts/custom_components/registry.js +0 -25
- package/src/templates/js_sapdon/scripts/index.js +0 -0
- package/src/templates/ts_sapdon/build.config +0 -23
- package/src/templates/ts_sapdon/main.ts +0 -11
- package/src/templates/ts_sapdon/mod.info +0 -7
- package/src/templates/ts_sapdon/pack_icon.png +0 -0
- package/src/templates/ts_sapdon/package.json +0 -20
- package/src/templates/ts_sapdon/res/models/blocks/crop.geo.json +0 -48
- package/src/templates/ts_sapdon/res/textures/blocks/test_log_oak.png +0 -0
- package/src/templates/ts_sapdon/res/textures/blocks/test_log_top.png +0 -0
- package/src/templates/ts_sapdon/res/textures/items/masterball.png +0 -0
- package/src/templates/ts_sapdon/scripts/components/cropComponent.ts +0 -44
- package/src/templates/ts_sapdon/scripts/components/items/guiBook.ts +0 -36
- package/src/templates/ts_sapdon/scripts/components/registry.ts +0 -24
- package/src/templates/ts_sapdon/scripts/index.ts +0 -7
- package/src/templates/ts_sapdon/tsconfig.json +0 -117
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
# Sapdon 架构概览
|
|
2
|
+
|
|
3
|
+
Sapdon 是一个面向 Minecraft Bedrock 版 Addon 开发的 Node.js 工具链。它将 Minecraft 的 JSON 定义 (entity、item、block、recipe 等) 抽象为 TypeScript 类,提供类型安全、可组合的 API,并自动生成最终的 JSON 包体。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 项目结构
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
sapdon/
|
|
11
|
+
├── src/
|
|
12
|
+
│ ├── cli/ # CLI 应用:命令、构建管道、开发服务器、热更新
|
|
13
|
+
│ ├── core/ # 核心库:DTO 定义、业务逻辑 API、工厂/注册层
|
|
14
|
+
│ ├── oc/ # OC 运行时:ECS 游戏框架(运行时,用于 Script API)
|
|
15
|
+
│ ├── templates/ # 项目模板 (js_sapdon, ts_sapdon)
|
|
16
|
+
│ └── utils/ # 通用工具:序列化系统、类型、缓存
|
|
17
|
+
├── prod/ # 构建产物(发布到 npm)
|
|
18
|
+
│ ├── cli/ # CLI 入口 (start.js, index.js)
|
|
19
|
+
│ ├── core/ # 核心库
|
|
20
|
+
│ ├── oc/ # OC 运行时
|
|
21
|
+
│ └── utils/ # 工具库
|
|
22
|
+
├── scripts/ # 框架自身的构建脚本
|
|
23
|
+
├── examples/ # 示例项目
|
|
24
|
+
└── doc/ # 文档
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**包入口**:
|
|
28
|
+
|
|
29
|
+
| 包名 | 源文件 | 产物 |
|
|
30
|
+
|------|--------|------|
|
|
31
|
+
| `@sapdon/core` | `src/core/index.js` | `prod/core/index.js` |
|
|
32
|
+
| `@sapdon/cli` | `src/cli/index.js` | `prod/cli/index.js` |
|
|
33
|
+
| `@sapdon/runtime` | `src/oc/index.ts` | `prod/oc/index.js` |
|
|
34
|
+
| `@sapdon/utils` | `src/utils/index.ts` | `prod/utils/index.js` |
|
|
35
|
+
|
|
36
|
+
`sapdon` CLI 二进制入口: `prod/cli/start.js`(`package.json` 中 `bin` 字段指定)。
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 2. 三层核心架构 (`src/core/`)
|
|
41
|
+
|
|
42
|
+
核心库采用 **三层架构**,自底向上:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
┌──────────────────────────────────────────────────┐
|
|
46
|
+
│ Layer 3: factory/ (工厂/注册层) │
|
|
47
|
+
│ ItemAPI, EntityAPI, BlockAPI, RecipeAPI... │
|
|
48
|
+
│ 用户直接调用的静态 API,创建实例并注册 │
|
|
49
|
+
├──────────────────────────────────────────────────┤
|
|
50
|
+
│ Layer 2: item/, entity/, block/, biome/... │
|
|
51
|
+
│ (业务逻辑/API 层) │
|
|
52
|
+
│ Item, Food, Entity, Block, Biome 等高级类 │
|
|
53
|
+
│ 封装组件操作方法,内部使用 Layer 1 的 DTO 生成 │
|
|
54
|
+
├──────────────────────────────────────────────────┤
|
|
55
|
+
│ Layer 1: addon/ (DTO 层) │
|
|
56
|
+
│ AddonItem, AddonEntity, AddonBlock... │
|
|
57
|
+
│ 纯数据类,1:1 映射 Minecraft JSON Schema │
|
|
58
|
+
│ 每个类有 @Serializer 装饰的 toObject() 方法 │
|
|
59
|
+
└──────────────────────────────────────────────────┘
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 2.1 DTO 层 (`addon/`)
|
|
63
|
+
|
|
64
|
+
DTO 类位于 `src/core/addon/`,直接对应 Minecraft JSON 格式。每个 DTO 类有一个 `toObject()` 方法,用 `@Serializer` 装饰器标记:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
src/core/addon/
|
|
68
|
+
├── item/
|
|
69
|
+
│ ├── item.ts → AddonItem, AddonItemDefinition, AddonItemDescription
|
|
70
|
+
│ └── attachable.ts → AddonAttachable
|
|
71
|
+
├── entity/
|
|
72
|
+
│ ├── entity.ts → AddonEntity, AddonEntityDefinition, AddonEntityDescription
|
|
73
|
+
│ └── clientEntity.ts → AddonClientEntity, AddonClientEntityDescription
|
|
74
|
+
├── block/block.ts → AddonBlock, AddonBlockDefinition, AddonBlockDescription
|
|
75
|
+
├── biome.ts → AddonBiome
|
|
76
|
+
├── recipe/
|
|
77
|
+
│ ├── shaped.ts → AddonRecipeShaped
|
|
78
|
+
│ ├── shapeless.ts → AddonRecipeShapeless
|
|
79
|
+
│ ├── furnace.ts → AddonRecipeFurnace
|
|
80
|
+
│ └── baseRecipe.ts → AddonRecipe (基类)
|
|
81
|
+
├── controllers/
|
|
82
|
+
│ ├── animationController.ts
|
|
83
|
+
│ └── render_controllers.ts
|
|
84
|
+
├── feature/
|
|
85
|
+
│ └── oreFeature.ts → AddonOreFeature
|
|
86
|
+
├── featureRule.ts → AddonFeatureRule
|
|
87
|
+
├── manifest.ts → AddonManifest, AddonManifestHeader, AddonManifestModule
|
|
88
|
+
└── menuCategory.ts → AddonMenuCategory
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 2.2 业务逻辑层 (`item/`, `entity/`, `block/` 等)
|
|
92
|
+
|
|
93
|
+
这一层是用户直接操作的类,提供高层次的组件操作方法:
|
|
94
|
+
|
|
95
|
+
- **Item** (`src/core/item/item.js`) — `addComponent()`、`removeComponent()`、`toObject()`
|
|
96
|
+
- **Entity** (`src/core/entity/entity.js`) — 组合 `BasicEntity`(行为包)+ `ClientEntity`(资源包)
|
|
97
|
+
- **Block** (`src/core/block/block.js`) — 多变体、几何、旋转等
|
|
98
|
+
- **ItemComponent / EntityComponent / BlockComponent** — 静态工厂方法,返回 `Map` 对象
|
|
99
|
+
|
|
100
|
+
### 2.3 工厂层 (`factory/`)
|
|
101
|
+
|
|
102
|
+
静态 API 入口,用户直接调用:
|
|
103
|
+
|
|
104
|
+
| API | 位置 | 主要方法 |
|
|
105
|
+
|-----|------|---------|
|
|
106
|
+
| `ItemAPI` | `factory/itemFactory.js` | `createItem()`, `createFood()`, `createAttachable()`, armor 系列 |
|
|
107
|
+
| `EntityAPI` | `factory/entityFactory.js` | `createEntity()`, `createDummyEntity()`, `createProjectile()` |
|
|
108
|
+
| `BlockAPI` | `factory/blockFactory.js` | `createBasicBlock()`, `createBlock()`, `createRotatableBlock()`, `createCropBlock()` |
|
|
109
|
+
| `RecipeAPI` | `factory/recipeFactory.js` | `registerSimpleShaped()`, `registerSimpleShapeless()`, `registerSimpleFurnace()` |
|
|
110
|
+
| `BiomeAPI` | `factory/biomeFactory.js` | `createBiome()` |
|
|
111
|
+
| `FeatureAPI` | `factory/featureFactory.js` | `createOreFeature()`, `createFeatureRules()` |
|
|
112
|
+
| `UiAPI` | `factory/uiFactory.js` | `createUISystem()`, `createPanel()`, `createImage()`, `createLabel()` |
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 3. 序列化系统 (`src/utils/serializable.ts`)
|
|
117
|
+
|
|
118
|
+
框架使用装饰器实现自定义序列化:
|
|
119
|
+
|
|
120
|
+
- **`@Serializer`** — 方法装饰器,标记 `toObject()` 为序列化方法。序列化器存储在 `WeakMap<Constructor, ISerializer>` 中
|
|
121
|
+
- **`@Serializable`** — 类装饰器,通过 `Symbol.metadata` 注册序列化器(备选方案)
|
|
122
|
+
- **`serialize(instance)`** — 查找实例的序列化器并调用
|
|
123
|
+
- **`encode(value)` / `decode(value)`** — 用于 HTTP 传输(JSON.stringify + jsonEncoderReplacer)
|
|
124
|
+
- **`jsonEncoderReplacer`** — 保留原始 JSON 类型(number/boolean 以 `JSON.rawJSON` 形式输出)
|
|
125
|
+
|
|
126
|
+
典型用法:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
class AddonItem {
|
|
130
|
+
@Serializer
|
|
131
|
+
toObject() {
|
|
132
|
+
return { format_version: "1.21.40", "minecraft:item": { ... } }
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
class Item {
|
|
137
|
+
@Serializer
|
|
138
|
+
toObject() {
|
|
139
|
+
const dto = new AddonItem(this.identifier, ...)
|
|
140
|
+
return serialize(dto) // 委托给 DTO 的 @Serializer
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 4. 数据流:从用户代码到 JSON 文件
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
用户代码 (main.ts)
|
|
151
|
+
│
|
|
152
|
+
│ ItemAPI.createItem('my:item', 'items', 'tex')
|
|
153
|
+
│ EntityAPI.createEntity('my:entity', 'tex')
|
|
154
|
+
│ registry.submit()
|
|
155
|
+
▼
|
|
156
|
+
┌──────────────────────────────────────────────────────┐
|
|
157
|
+
│ 1. 注册阶段(构建时,在子进程中执行) │
|
|
158
|
+
│ │
|
|
159
|
+
│ ItemAPI.createItem() │
|
|
160
|
+
│ → 创建 Item 实例 │
|
|
161
|
+
│ → GRegistry.register('my_item', 'behavior', │
|
|
162
|
+
│ 'items/', item) │
|
|
163
|
+
│ → 推入 { name, root, path, data } 到 clientRegistry │
|
|
164
|
+
│ │
|
|
165
|
+
│ registry.submit() │
|
|
166
|
+
│ → 遍历 clientRegistry[] │
|
|
167
|
+
│ → 调用每个 data 的 toObject() 获取最终 JSON 数据 │
|
|
168
|
+
│ → transportPost('submit', data) │
|
|
169
|
+
│ (src/core/transport/client.ts, HTTP POST fallback) │
|
|
170
|
+
└───────────────────────┬──────────────────────────────┘
|
|
171
|
+
│ HTTP POST
|
|
172
|
+
▼
|
|
173
|
+
┌──────────────────────────────────────────────────────┐
|
|
174
|
+
│ 2. 处理阶段(CLI 进程中) │
|
|
175
|
+
│ │
|
|
176
|
+
│ server.handle('submit', (data) => { │
|
|
177
|
+
│ GRegistryServer.dataList = data │
|
|
178
|
+
│ generateAddon(modPath, buildPath, projectName) │
|
|
179
|
+
│ }) │
|
|
180
|
+
│ │
|
|
181
|
+
│ generateAddon(): │
|
|
182
|
+
│ for each { name, root, path, data } in dataList: │
|
|
183
|
+
│ if root == "behavior": │
|
|
184
|
+
│ → dev/<name>_BP/<path>/<name>.json │
|
|
185
|
+
│ if root == "resource": │
|
|
186
|
+
│ → dev/<name>_RP/<path>/<name>.json │
|
|
187
|
+
│ 特殊处理: item_texture, terrain_texture, │
|
|
188
|
+
│ flipbook_textures │
|
|
189
|
+
└───────────────────────┬──────────────────────────────┘
|
|
190
|
+
│ writeFileSync
|
|
191
|
+
▼
|
|
192
|
+
┌──────────────────────────────────────────────────────┐
|
|
193
|
+
│ 3. 输出阶段 │
|
|
194
|
+
│ │
|
|
195
|
+
│ dev/<name>_BP/ │
|
|
196
|
+
│ ├── manifest.json │
|
|
197
|
+
│ ├── items/*.json │
|
|
198
|
+
│ ├── entities/*.json │
|
|
199
|
+
│ ├── blocks/*.json │
|
|
200
|
+
│ ├── biomes/*.json │
|
|
201
|
+
│ ├── recipes/*.json │
|
|
202
|
+
│ ├── scripts/index.js ← Script API 打包输出 │
|
|
203
|
+
│ │
|
|
204
|
+
│ dev/<name>_RP/ │
|
|
205
|
+
│ ├── manifest.json │
|
|
206
|
+
│ ├── entity/*.json │
|
|
207
|
+
│ ├── textures/item_texture.json │
|
|
208
|
+
│ ├── textures/terrain_texture.json │
|
|
209
|
+
│ └── ... │
|
|
210
|
+
└───────────────────────┬──────────────────────────────┘
|
|
211
|
+
│ syncDevFilesServer()
|
|
212
|
+
▼
|
|
213
|
+
┌──────────────────────────────────────────────────────┐
|
|
214
|
+
│ 4. 同步到 Minecraft 目录 │
|
|
215
|
+
│ │
|
|
216
|
+
│ development_behavior_packs/<name>_BP/ │
|
|
217
|
+
│ development_resource_packs/<name>_RP/ │
|
|
218
|
+
└──────────────────────────────────────────────────────┘
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 5. 注册系统
|
|
224
|
+
|
|
225
|
+
注册系统采用 **客户端-服务端** 架构,分为两个部分:
|
|
226
|
+
|
|
227
|
+
### 客户端 (`src/core/registry.ts` + `src/core/transport/client.ts`)
|
|
228
|
+
|
|
229
|
+
位于 core 模块,供用户代码在子进程中调用。依赖通用的 HTTP 客户端,不引入 CLI 代码:
|
|
230
|
+
|
|
231
|
+
| 组件 | 位置 | 说明 |
|
|
232
|
+
|------|------|------|
|
|
233
|
+
| `GRegistry` | `src/core/registry.ts` | 累加注册数据的客户端注册表 |
|
|
234
|
+
| `GRegistry.register(name, root, path, data)` | `registry.ts` | 注册一个条目:文件名、根目录(behavior/resource)、子路径、数据实例 |
|
|
235
|
+
| `GRegistry.submit()` | `registry.ts` | 调用所有 data 的 `toObject()`,然后 HTTP POST 到 dev server |
|
|
236
|
+
| `registry.submit()` | `registry.ts` | 命名空间下的便捷入口 |
|
|
237
|
+
| `transportPost()` | `src/core/transport/client.ts` | 通用 HTTP POST 客户端,端口可被 `SAPDON_DEV_SERVER_PORT` 环境变量覆盖 |
|
|
238
|
+
|
|
239
|
+
### 服务端 (`src/cli/registryServer.ts`)
|
|
240
|
+
|
|
241
|
+
位于 CLI 模块,直接引用 `dev-server/server.ts` 和 `remoteLogger`。在 CLI 主进程中运行,不对外暴露:
|
|
242
|
+
|
|
243
|
+
| 组件 | 说明 |
|
|
244
|
+
|------|------|
|
|
245
|
+
| `GRegistryServer` | 服务端注册表,接收并存储数据 |
|
|
246
|
+
| `GRegistryServer.dataList` | 存储 `{ name, root, path, data }` 数组 |
|
|
247
|
+
| `GRegistryServer.startServer()` | 注册 `submitGregistry` 和 `remote-logger` 的 HTTP handler |
|
|
248
|
+
|
|
249
|
+
### 数据提交逻辑
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
import { transportPost } from './transport/client.js'
|
|
253
|
+
|
|
254
|
+
export function submit() {
|
|
255
|
+
const data = clientRegistryData.map(item => {
|
|
256
|
+
if (typeof item.data.toObject === 'function') {
|
|
257
|
+
item.data = item.data.toObject()
|
|
258
|
+
}
|
|
259
|
+
return item
|
|
260
|
+
})
|
|
261
|
+
transportPost('submit', data)
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 6. CLI 构建管道
|
|
268
|
+
|
|
269
|
+
### 6.1 命令
|
|
270
|
+
|
|
271
|
+
| 命令 | 说明 |
|
|
272
|
+
|------|------|
|
|
273
|
+
| `sapdon build <name>` | 完整构建 + 启动热更新 |
|
|
274
|
+
| `sapdon pack` | 构建当前目录项目(不带 HMR) |
|
|
275
|
+
| `sapdon create <name>` | 从模板脚手架新项目 |
|
|
276
|
+
| `sapdon init` | 为已有项目添加 sapdon 配置 |
|
|
277
|
+
| `sapdon lib` | 复制库文件到 `node_modules/@sapdon/` |
|
|
278
|
+
| `sapdon res` | 生成资源提示文件 `res.hint.ts` |
|
|
279
|
+
|
|
280
|
+
### 6.2 构建步骤 (`buildProject()`)
|
|
281
|
+
|
|
282
|
+
```
|
|
283
|
+
1. projectCanBuild() → 验证项目目录和 build.config
|
|
284
|
+
2. initResourceDir() → 扫描 res/ 目录,生成 res.hint.ts
|
|
285
|
+
3. 生成 manifest.json → behavior pack + resource pack 清单
|
|
286
|
+
4. 复制 pack_icon.png
|
|
287
|
+
5. 复制资源文件 res/ → RP
|
|
288
|
+
6. 启动开发服务器 → startDevServer() + GRegistryServer.startServer()
|
|
289
|
+
7. runScript(main.ts) → rollup 编译 → fork 子进程执行
|
|
290
|
+
子进程中用户代码执行并注册数据
|
|
291
|
+
HTTP POST 提交数据到 dev server
|
|
292
|
+
generateAddon() 生成 JSON 文件
|
|
293
|
+
8. bundleScripts() → rollup 打包 scripts/main.ts → scripts/index.js
|
|
294
|
+
9. syncDevFilesServer() → 复制 BP/RP 到 Minecraft 开发包目录
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### 6.3 关键文件职责
|
|
298
|
+
|
|
299
|
+
| 文件 | 作用 |
|
|
300
|
+
|------|------|
|
|
301
|
+
| `src/cli/start.js` | CLI 入口,定义所有 commander 命令 |
|
|
302
|
+
| `src/cli/build.js` | 构建编排器:`scriptBundler`、`buildProject()`、`runScript()` |
|
|
303
|
+
| `src/cli/load.js` | `generateAddon()` — 遍历 dataList 写入 JSON 文件,生成纹理 JSON |
|
|
304
|
+
| `src/cli/init.js` | 项目初始化:脚手架生成、路径辅助 |
|
|
305
|
+
| `src/cli/utils.ts` | `saveFile`、`readFile`、`copyFileSync` 等文件 I/O 工具 |
|
|
306
|
+
| `src/cli/registryServer.ts` | `GRegistryServer` — 服务端注册表,注册 submit/remote-logger handler |
|
|
307
|
+
| `src/cli/dev-server/server.ts` | `DevelopmentServer` — HTTP 服务,用于构建时 IPC |
|
|
308
|
+
| `src/cli/dev-server/client.js` | `cliRequest()` / `post()` — CLI 内部使用的 HTTP 客户端(remoteLogger 等) |
|
|
309
|
+
| `src/cli/dev-server/hmr.js` | `hmr()` — 文件监听器,热更新触发重建 |
|
|
310
|
+
| `src/cli/dev-server/syncFiles.js` | `syncDevFilesServer()` — 同步到 Minecraft 目录;`writeLib()` — 复制库文件 |
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## 7. 开发服务器
|
|
315
|
+
|
|
316
|
+
- **端口**: 49037(可通过环境变量 `SAPDON_DEV_SERVER_PORT` 覆盖)
|
|
317
|
+
- **实现**: 原生 Node.js `http.createServer()`
|
|
318
|
+
- **传输**: HTTP POST + JSON body
|
|
319
|
+
- **通信模式**:
|
|
320
|
+
- 客户端(子进程中用户代码):`transportPost(path, ...params)`(来自 `src/core/transport/client.ts`)
|
|
321
|
+
- 服务端(CLI 进程):`server.handle(url, handler)`(来自 `src/cli/dev-server/server.ts`)
|
|
322
|
+
- 编码/解码:`encode()`/`decode()`(基于 `JSON.stringify` + `jsonEncoderReplacer`)
|
|
323
|
+
- **架构原则**: core 模块只包含通用 HTTP 客户端,不引用 CLI 代码。服务端逻辑全部位于 CLI 内部。
|
|
324
|
+
|
|
325
|
+
### Handler 列表
|
|
326
|
+
|
|
327
|
+
| Handler | 用途 |
|
|
328
|
+
|---------|------|
|
|
329
|
+
| `submit` | 接收注册数据并触发 `generateAddon()` |
|
|
330
|
+
| `remote-logger` | 游戏内 Script API 通过此 handler 发送日志到 CLI |
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## 8. 热更新 (HMR)
|
|
335
|
+
|
|
336
|
+
- **触发**: `sapdon build` 命令自动启动 HMR(`build.config` 中 `useHMR: true`)
|
|
337
|
+
- **机制**: `fs.watch` 递归监听项目目录,1 秒防抖
|
|
338
|
+
- **监听文件**: `.js`、`.ts`、`build.config`、`mod.info`
|
|
339
|
+
- **排除**: 点文件、构建输出目录 (`dev/`)、`.tmp` 文件
|
|
340
|
+
- **处理流程**: 文件变更 → `buildProject()` 重新构建 → `syncDevFilesServer()` 同步到 Minecraft
|
|
341
|
+
- **资源热更新**: 监听 `res/` 目录,3 秒防抖,变更时运行 `sapdon res`
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## 9. OC 运行时 (`src/oc/`)
|
|
346
|
+
|
|
347
|
+
OC (Object-Component) 是一个 ECS 风格的游戏框架,用于 Minecraft Script API 运行时:
|
|
348
|
+
|
|
349
|
+
### 核心架构
|
|
350
|
+
|
|
351
|
+
| 组件 | 说明 |
|
|
352
|
+
|------|------|
|
|
353
|
+
| `Component<Actor>` | 组件接口:`onTick(dt)`、`onAttach()`、`onDetach()` |
|
|
354
|
+
| `BasicComponent<Actor>` | 带有 onAttach/onDetach 生命周期钩子的抽象基类 |
|
|
355
|
+
| `ComponentManager<Actor>` | 管理实体的组件附加和 tick 循环 |
|
|
356
|
+
| `Level<Actor>` | 抽象关卡:`addEntity()`、`removeEntity()`、通过 `Scheduler` 驱动 |
|
|
357
|
+
| `Scheduler<Actor>` | 调度器,使用 `system.runInterval()` 驱动 tick |
|
|
358
|
+
| `MinecraftTickingScheduler` | `Scheduler` 的 Minecraft 实现 |
|
|
359
|
+
| `Optional<T>` | Monadic Option 类型 |
|
|
360
|
+
|
|
361
|
+
### 装饰器
|
|
362
|
+
|
|
363
|
+
- `@MinecraftMain` — 标记主游戏类,自动绑定玩家/实体生成事件
|
|
364
|
+
- `@PlayerSpawned` / `@EntitySpawned` / `@ActorSpawned` — 实体生成时自动附加组件
|
|
365
|
+
- `@SpawnFilter` — 过滤哪些实体附加组件
|
|
366
|
+
- `@RequireComponents` — 声明组件依赖,自动附加
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## 10. 框架自身的构建流程 (`scripts/build.cjs`)
|
|
371
|
+
|
|
372
|
+
Sapdon 框架自身的构建使用三步管道:
|
|
373
|
+
|
|
374
|
+
```
|
|
375
|
+
tsc (TypeScript 编译)
|
|
376
|
+
│ src/ → dist/
|
|
377
|
+
│ 编译 .ts 到 .js,保留路径结构
|
|
378
|
+
▼
|
|
379
|
+
tsc-alias (路径别名解析)
|
|
380
|
+
│ @sapdon/* → 正确的相对路径
|
|
381
|
+
▼
|
|
382
|
+
rollup (打包)
|
|
383
|
+
│ dist/ → prod/
|
|
384
|
+
│ 9 个 bundle:
|
|
385
|
+
│ start, CLI, Core, OC, Utils
|
|
386
|
+
│ + 各自的 .d.ts 声明文件
|
|
387
|
+
│ 插件: node-resolve, commonjs, json, terser
|
|
388
|
+
│ 外部化: rollup, typescript, @sapdon/*, @minecraft/*
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
## 11. 目录输出路径
|
|
394
|
+
|
|
395
|
+
构建产物输出规则:
|
|
396
|
+
|
|
397
|
+
| 数据类型 | root | dataPath | 输出路径 |
|
|
398
|
+
|---------|------|----------|---------|
|
|
399
|
+
| 物品 | `behavior` | `items/` | `dev/<name>_BP/items/<name>.json` |
|
|
400
|
+
| 实体 (行为) | `behavior` | `entities/` | `dev/<name>_BP/entities/<name>.json` |
|
|
401
|
+
| 方块 | `behavior` | `blocks/` | `dev/<name>_BP/blocks/<name>.json` |
|
|
402
|
+
| 配方 | `behavior` | `recipes/` | `dev/<name>_BP/recipes/<name>.json` |
|
|
403
|
+
| 生物群系 | `behavior` | `biomes/` | `dev/<name>_BP/biomes/<name>.json` |
|
|
404
|
+
| 特征 | `behavior` | `features/` | `dev/<name>_BP/features/<name>.json` |
|
|
405
|
+
| 特征规则 | `behavior` | `feature_rules/` | `dev/<name>_BP/feature_rules/<name>.json` |
|
|
406
|
+
| 实体 (资源) | `resource` | `entity/` | `dev/<name>_RP/entity/<name>.json` |
|
|
407
|
+
| 附着物 | `resource` | `attachables/` | `dev/<name>_RP/attachables/<name>.json` |
|
|
408
|
+
| 渲染控制器 | `resource` | `render_controllers/` | `dev/<name>_RP/render_controllers/<name>.json` |
|
|
409
|
+
|
|
410
|
+
最终同步到 Minecraft 目录(`versionType` 决定路径):
|
|
411
|
+
|
|
412
|
+
- **release**: `%USERPROFILE%\AppData\Roaming\Minecraft Bedrock\Users\Shared\games\com.mojang\development_<behavior|resource>_packs\<name>_<BP|RP>\`
|
|
413
|
+
- **beta**: `%USERPROFILE%\AppData\Local\Packages\Microsoft.MinecraftWindowsBeta_8wekyb3d8bbwe\LocalState\games\com.mojang\development_<behavior|resource>_packs\<name>_<BP|RP>\`
|
|
414
|
+
|
|
415
|
+
可通过环境变量 `MC_PATH` 或 `MC_BETA_PATH` 覆盖。
|