sapdon 3.2.2 → 3.4.0

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.
Files changed (76) hide show
  1. package/README.md +255 -121
  2. package/doc/dev/architecture.md +418 -0
  3. package/doc/dev/cli.md +467 -0
  4. package/doc/dev/core.md +751 -0
  5. package/doc/dev/lr-paradigm.md +85 -0
  6. package/doc/dev/oc.md +582 -0
  7. package/doc/dev/workflow.md +257 -0
  8. package/doc/hello_sapdon/hello_sapdon.md +3 -3
  9. package/doc/user/api/biome.md +558 -0
  10. package/doc/user/api/block.md +1530 -0
  11. package/doc/user/api/entity.md +685 -0
  12. package/doc/user/api/extra.md +231 -0
  13. package/doc/user/api/item.md +1125 -0
  14. package/doc/user/api/neo-guidebook.md +409 -0
  15. package/doc/user/api/recipe.md +427 -0
  16. package/doc/user/api/sapdon-ui.md +185 -0
  17. package/doc/user/api/texture.md +181 -0
  18. package/doc/user/config/build-config.md +83 -0
  19. package/doc/user/config/mod-info.md +33 -0
  20. package/doc/user/faq.md +160 -0
  21. package/doc/user/quick-start.md +122 -0
  22. package/doc/user/tutorials/block.md +474 -0
  23. package/doc/user/tutorials/entity.md +356 -0
  24. package/doc/user/tutorials/item.md +449 -0
  25. package/doc/user/tutorials/neo-guidebook-experience.md +381 -0
  26. package/doc/user/tutorials/neo-guidebook.md +640 -0
  27. package/doc/user/tutorials/recipe.md +278 -0
  28. package/doc/user/tutorials/sapdon-ui.md +207 -0
  29. package/package.json +8 -3
  30. package/prod/cli/index.js +1 -1
  31. package/prod/cli/start.js +1 -1458
  32. package/prod/core/index.d.ts +4564 -2166
  33. package/prod/core/index.js +1 -59015
  34. package/prod/core/package.json +7 -0
  35. package/prod/oc/index.d.ts +350 -108
  36. package/prod/oc/index.js +1 -1
  37. package/prod/oc/package.json +7 -0
  38. package/prod/utils/index.d.ts +20 -9
  39. package/prod/utils/index.js +1 -1
  40. package/prod/utils/package.json +7 -0
  41. package/doc/BlockAPI.md +0 -145
  42. package/doc/api.md +0 -128
  43. package/doc/oc/index.md +0 -0
  44. package/doc/sapdon-ts.md +0 -64
  45. package/src/templates/js_sapdon/build.config +0 -23
  46. package/src/templates/js_sapdon/main.mjs +0 -4
  47. package/src/templates/js_sapdon/mod.info +0 -7
  48. package/src/templates/js_sapdon/pack_icon.png +0 -0
  49. package/src/templates/js_sapdon/package.json +0 -20
  50. package/src/templates/js_sapdon/res/animations/animation_item.animation.json +0 -34
  51. package/src/templates/js_sapdon/res/animations/large_item.animation.json +0 -27
  52. package/src/templates/js_sapdon/res/models/blocks/crop.geo.json +0 -48
  53. package/src/templates/js_sapdon/res/models/entity/animation/animation_item.geo.json +0 -26
  54. package/src/templates/js_sapdon/res/models/entity/animation/large_item.geo.json +0 -28
  55. package/src/templates/js_sapdon/res/textures/blocks/none.png +0 -0
  56. package/src/templates/js_sapdon/res/textures/blocks/test_log_oak.png +0 -0
  57. package/src/templates/js_sapdon/res/textures/blocks/test_log_top.png +0 -0
  58. package/src/templates/js_sapdon/res/textures/items/masterball.png +0 -0
  59. package/src/templates/js_sapdon/scripts/custom_components/cropComponent.js +0 -50
  60. package/src/templates/js_sapdon/scripts/custom_components/items/gui_book.js +0 -37
  61. package/src/templates/js_sapdon/scripts/custom_components/registry.js +0 -25
  62. package/src/templates/js_sapdon/scripts/index.js +0 -0
  63. package/src/templates/ts_sapdon/build.config +0 -23
  64. package/src/templates/ts_sapdon/main.ts +0 -11
  65. package/src/templates/ts_sapdon/mod.info +0 -7
  66. package/src/templates/ts_sapdon/pack_icon.png +0 -0
  67. package/src/templates/ts_sapdon/package.json +0 -20
  68. package/src/templates/ts_sapdon/res/models/blocks/crop.geo.json +0 -48
  69. package/src/templates/ts_sapdon/res/textures/blocks/test_log_oak.png +0 -0
  70. package/src/templates/ts_sapdon/res/textures/blocks/test_log_top.png +0 -0
  71. package/src/templates/ts_sapdon/res/textures/items/masterball.png +0 -0
  72. package/src/templates/ts_sapdon/scripts/components/cropComponent.ts +0 -44
  73. package/src/templates/ts_sapdon/scripts/components/items/guiBook.ts +0 -36
  74. package/src/templates/ts_sapdon/scripts/components/registry.ts +0 -24
  75. package/src/templates/ts_sapdon/scripts/index.ts +0 -7
  76. package/src/templates/ts_sapdon/tsconfig.json +0 -117
@@ -0,0 +1,409 @@
1
+ # NeoGuidebook API 参考
2
+
3
+ NeoGuidebook 是基于 Minecraft Bedrock JSON UI 体系的指南书生成框架。使用链式 API 声明式构建页面,构建时自动序列化为 JSON UI,运行时通过 ActionFormData 触发显示。
4
+
5
+ ---
6
+
7
+ ## 目录
8
+
9
+ 1. [概览](#1-概览)
10
+ 2. [NeoGuidebook 类](#2-neoguidebook-类)
11
+ 3. [NeoGuidebookPage 类](#3-neoguidebookpage-类)
12
+ 4. [NeoGuidebookBridge 类](#4-neoguidebookbridge-类)
13
+ 5. [ItemComponent 辅助](#5-itemcomponent-辅助)
14
+ 6. [page_ids.json 生成](#6-page_idsjson-生成)
15
+ 7. [运行时注册](#7-运行时注册)
16
+
17
+ ---
18
+
19
+ ## 1. 概览
20
+
21
+ ### 工作流程
22
+
23
+ ```
24
+ 构建时 (main.ts) 运行时 (index.ts)
25
+ ───────────────── ─────────────────
26
+ ItemAPI.createItem() system.beforeEvents.startup
27
+ + setCustomComponentV2() → registerCustomComponent()
28
+ + setMaxStackSize() → onUse(event, params)
29
+ + setDisplayName() → ActionFormData
30
+ + setInteractButton() .title("sapdon_ui:book_name")
31
+ .body("page_id")
32
+ NeoGuidebook("ns:name") → 按钮 .button("prev_button")
33
+ + addDoublePageStack(id, L, R) .show(player)
34
+ + addSinglePageStack(id, P)
35
+ + addCustomButton(config) NeoGuidebookBridge
36
+ → 上一页/下一页/首页/章节跳转
37
+ registry.submit()
38
+ → neo_guidebook.json page_ids.json
39
+ → server_form.json 供 Bridge 获取页面列表
40
+ → page_ids.json
41
+ ```
42
+
43
+ ### 脚本 ↔ JSON UI 绑定
44
+
45
+ | ActionForm API | JSON UI 变量 | 说明 |
46
+ |----------------|-------------|------|
47
+ | `.title("sapdon_ui:name")` | `#title_text` | `sapdon_ui:` 前缀路由(SapdonServerUI),精确匹配 `$panel_id` |
48
+ | `.body("page_id")` | `#form_text` | 切换可见页面(匹配页面的 `$binding_text`) |
49
+ | `.button("text")` | `#form_button_text` | 匹配按钮的 `$binding_button_text`,控制哪个按钮 visible |
50
+
51
+ > NeoGuidebook 已迁移到新接口:注册走 `SapdonServerUI.registerPage`(`panelId = sapdon_ui:<name>`),书拆为 `内容面板 + 按键面板`,导航/章节按钮使用 `SapdonTexturedButton`(模板 `server_form.sapdon_textured_button`),不再依赖旧 `ServerUISystem`/`sapdon_form_button_factory`。
52
+
53
+ ---
54
+
55
+ ## 2. NeoGuidebook 类
56
+
57
+ 用于创建指南书 UI 系统。
58
+
59
+ ```typescript
60
+ import { NeoGuidebook } from '@sapdon/core'
61
+
62
+ const book = new NeoGuidebook(identifier, path, size?, options?)
63
+ ```
64
+
65
+ ### 构造参数
66
+
67
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
68
+ |------|------|------|--------|------|
69
+ | `identifier` | `string` | 是 | — | 格式 `"命名空间:名称"`,如 `"my_mod:guidebook"` |
70
+ | `path` | `string` | 是 | — | UI 文件路径,通常 `"ui/"` |
71
+ | `size` | `[number, number]` | 否 | `[320, 207]` | 面板像素尺寸 |
72
+ | `options` | `object` | 否 | `{}` | 可选配置(见下文) |
73
+
74
+ ### options 配置项
75
+
76
+ ```typescript
77
+ {
78
+ debug?: boolean // 是否输出调试信息
79
+ buttons?: {
80
+ prev?: { visible: boolean } // 上一页按钮
81
+ next?: { visible: boolean } // 下一页按钮
82
+ home?: { visible: boolean } // 首页按钮
83
+ close?: { visible: boolean } // 关闭按钮
84
+ }
85
+ textures?: {
86
+ prevDefault?: string // 上一页默认纹理
87
+ prevHover?: string // 上一页悬停纹理
88
+ prevPressed?: string // 上一页按压纹理
89
+ nextDefault?: string // 下一页默认纹理
90
+ nextHover?: string // 下一页悬停纹理
91
+ nextPressed?: string // 下一页按压纹理
92
+ homeDefault?: string // 首页默认纹理
93
+ homeHover?: string // 首页悬停纹理
94
+ homePressed?: string // 首页按压纹理
95
+ }
96
+ }
97
+ ```
98
+
99
+ ### 方法
100
+
101
+ #### addDoublePageStack(page_id, left_page, right_page)
102
+
103
+ 注册一个双页跨页(左右两页同时显示)。
104
+
105
+ ```typescript
106
+ book.addDoublePageStack(
107
+ 'page_index0', // page_id: string — 唯一标识,用于 body() 跳转
108
+ leftPanel, // left_page: Panel — NeoGuidebookPage.getPanel()
109
+ rightPanel, // right_page: Panel
110
+ size?: [string, string] // 可选,左右比例,默认 ["50%","50%"]
111
+ )
112
+ ```
113
+
114
+ #### addSinglePageStack(page_id, page)
115
+
116
+ 注册一个单页(占满整个表单宽度)。
117
+
118
+ ```typescript
119
+ book.addSinglePageStack(
120
+ 'page_index7', // page_id: string
121
+ pagePanel, // page: Panel
122
+ size?: [string, string] // 可选尺寸
123
+ )
124
+ ```
125
+
126
+ #### addCustomButton(config)
127
+
128
+ 添加自定义按钮。
129
+
130
+ ```typescript
131
+ book.addCustomButton({
132
+ id: 'my_button', // 按钮 ID
133
+ defaultTexture: 'textures/ui/...',
134
+ hoverTexture?: 'textures/ui/...',
135
+ pressedTexture?: 'textures/ui/...',
136
+ anchorFrom?: 'bottom_left', // 锚点
137
+ anchorTo?: 'bottom_left',
138
+ offset?: [number, number],
139
+ size?: [number | string, number | string]
140
+ })
141
+ ```
142
+
143
+ #### getPageIds()
144
+
145
+ 获取所有已注册页面的 ID 数组。
146
+
147
+ ```typescript
148
+ const ids: string[] = book.getPageIds()
149
+ // → ["page_index0", "page_index1", ...]
150
+ ```
151
+
152
+ #### getPageCount()
153
+
154
+ 获取页面总数。
155
+
156
+ ```typescript
157
+ const count: number = book.getPageCount()
158
+ ```
159
+
160
+ ---
161
+
162
+ ## 3. NeoGuidebookPage 类
163
+
164
+ 用于构建单个页面的内容。
165
+
166
+ ```typescript
167
+ import { NeoGuidebookPage } from '@sapdon/core'
168
+
169
+ const page = new NeoGuidebookPage(id, size?)
170
+ ```
171
+
172
+ ### 构造参数
173
+
174
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
175
+ |------|------|------|--------|------|
176
+ | `id` | `string` | 是 | — | 页面唯一 ID |
177
+ | `size` | `[string, string]` | 否 | `["100%","100%"]` | 页面尺寸,百分比格式 |
178
+
179
+ ### 布局方法
180
+
181
+ 所有方法返回 `this`,支持链式调用。
182
+
183
+ #### addBookText(text, size?)
184
+
185
+ ```typescript
186
+ page.addBookText(
187
+ '这是正文内容', // text: string
188
+ ['100%', '70%'] // size?: [string, string]
189
+ )
190
+ ```
191
+
192
+ #### addCategoryTitle(title, size?)
193
+
194
+ ```typescript
195
+ page.addCategoryTitle(
196
+ '架构概述', // title: string
197
+ ['100%', '15%'] // size?: [string, string]
198
+ )
199
+ ```
200
+
201
+ #### addBookTitleBar(text, size?)
202
+
203
+ ```typescript
204
+ page.addBookTitleBar(
205
+ '欢迎使用手册', // text: string
206
+ ['100%', '15%'] // size?: [string, string]
207
+ )
208
+ ```
209
+
210
+ #### addEmptySpace(size?)
211
+
212
+ ```typescript
213
+ page.addEmptySpace(['100%', '5%'])
214
+ ```
215
+
216
+ #### addDivider(size?)
217
+
218
+ ```typescript
219
+ page.addDivider(['100%', '3%'])
220
+ ```
221
+
222
+ #### addRecipeGrid(row, col, items, size?)
223
+
224
+ ```typescript
225
+ page.addRecipeGrid(
226
+ 2, // row: number
227
+ 3, // col: number
228
+ ['textures/items/iron_ingot', ...], // items: string[]
229
+ ['100%', '30%'] // size?: [string, string]
230
+ )
231
+ ```
232
+
233
+ #### addBookCategory(title, row, col, buttons, size?)
234
+
235
+ ```typescript
236
+ page.addBookCategory(
237
+ '物品分类', // title: string
238
+ 2, // row: number
239
+ 3, // col: number
240
+ [{ id: 'tools', texture: '...' }], // buttons
241
+ ['100%', '60%'] // size?: [string, string]
242
+ )
243
+ ```
244
+
245
+ #### addChapter(name, texture)
246
+
247
+ ```typescript
248
+ page.addChapter('架构概述', 'textures/items/map')
249
+ ```
250
+
251
+ #### addChapters(chapters)
252
+
253
+ ```typescript
254
+ page.addChapters([
255
+ { chapter_name: '架构概述', chapter_texture: 'textures/items/map' },
256
+ { chapter_name: '核心类', chapter_texture: 'textures/items/iron_ingot' },
257
+ ])
258
+ ```
259
+
260
+ #### addControl(control)
261
+
262
+ 添加任意自定义 UI 控件(透传内部 StackPanel,可放任何 `UIElement` 或原生 JSON 控件对象)。
263
+
264
+ ```typescript
265
+ page.addControl(
266
+ new Label('my_label', undefined)
267
+ .setText(new Text().setText('自定义文字').setColor([0, 0, 0]))
268
+ )
269
+ ```
270
+
271
+ #### addStack(size, control, debug?)
272
+
273
+ 添加自定义控件并指定占位尺寸(透传 `StackPanel.addStack`)。
274
+
275
+ ```typescript
276
+ page.addStack(
277
+ ['100%', '20%'],
278
+ new Image('my_img', undefined).setSprite(new Sprite().setTexture('textures/items/iron_ingot'))
279
+ )
280
+ ```
281
+
282
+ #### buildChapterList(prefix?)
283
+
284
+ ```typescript
285
+ page.buildChapterList() // 默认前缀 "item",生成 item_N_button
286
+ page.buildChapterList("sub") // 多级目录:生成 sub_N_button,避免按钮 id 全局冲突
287
+ ```
288
+
289
+ `prefix` 决定目录按钮的绑定键名:`${prefix}_${index}_button`。单本书只有一个目录页时用默认值;要加子目录/二级目录,不同级别传不同前缀。
290
+
291
+ #### getPanel()
292
+
293
+ ```typescript
294
+ const panel = page.getPanel()
295
+ book.addDoublePageStack('page_0', panel, rightPanel)
296
+ ```
297
+
298
+ #### clear()
299
+
300
+ ```typescript
301
+ page.clear()
302
+ ```
303
+
304
+ ---
305
+
306
+ ## 4. NeoGuidebookBridge 类
307
+
308
+ 运行时导航管理器,封装了 ActionFormData 的显示和页面切换逻辑。
309
+
310
+ ```typescript
311
+ import { NeoGuidebookBridge } from '<path>/page_bridge'
312
+
313
+ const bridge = new NeoGuidebookBridge(uiName, pageIds, options?)
314
+ ```
315
+
316
+ ### 构造参数
317
+
318
+ | 参数 | 类型 | 必填 | 说明 |
319
+ |------|------|------|------|
320
+ | `uiName` | `string` | 是 | 书名字,必须与 `title()` 一致 |
321
+ | `pageIds` | `string[]` | 是 | 页面 ID 列表,来自 `getPageIds()` |
322
+ | `options` | `object` | 否 | `{ debug: boolean }` |
323
+
324
+ ### 方法
325
+
326
+ #### show(player, startIndex)
327
+
328
+ ```typescript
329
+ bridge.show(player, 0) // player: Player, startIndex: number
330
+ ```
331
+
332
+ #### onPage(pageId, callbacks)
333
+
334
+ ```typescript
335
+ bridge.onPage('page_index0', {
336
+ onEnter: (pageId: string, index: number) => { /* 进入页面时调用 */ },
337
+ onLeave: (pageId: string, index: number) => { /* 离开页面时调用 */ },
338
+ })
339
+ ```
340
+
341
+ ### 内置按钮映射
342
+
343
+ | ActionForm 按钮文字 | 对应 JSON UI 控件 | 行为 |
344
+ |-------------------|------------------|------|
345
+ | `"prev_button"` | 上一页按钮 | `currentIndex--` |
346
+ | `"next_button"` | 下一页按钮 | `currentIndex++` |
347
+ | `"home_button"` | 首页按钮 | `currentIndex = 0` |
348
+ | `"item_X_button"` | 章节选择按钮 | `currentIndex = X+1` |
349
+
350
+ ---
351
+
352
+ ## 5. ItemComponent 辅助
353
+
354
+ ```typescript
355
+ import { ItemComponent } from '@sapdon/core'
356
+
357
+ // 设置自定义物品组件(指南书的核心)
358
+ ItemComponent.setCustomComponentV2('sapdon:neo_guibook', {})
359
+
360
+ // 其他物品组件
361
+ ItemComponent.setMaxStackSize(1)
362
+ ItemComponent.setDisplayName('我的手册')
363
+ ItemComponent.setInteractButton('打开')
364
+ ```
365
+
366
+ ### setCustomComponentV2(componentName, options)
367
+
368
+ 参数 `componentName` 必须与运行时 `registerCustomComponent()` 注册的名字一致。这个值也会出现在物品 JSON 的 `components` 中。
369
+
370
+ ---
371
+
372
+ ## 6. page_ids.json 生成
373
+
374
+ `main.ts` 中调用 `getPageIds()` 后将结果写入文件,供运行时脚本使用:
375
+
376
+ ```typescript
377
+ const pageIds: string[] = neo_guidebook.getPageIds()
378
+ fs.writeFileSync(
379
+ path.join(process.cwd(), 'scripts', 'page_ids.json'),
380
+ JSON.stringify(pageIds, null, 2)
381
+ )
382
+ ```
383
+
384
+ 生成的 `page_ids.json` 示例:
385
+
386
+ ```json
387
+ ["page_index0", "page_index1", "page_index2", "page_index3"]
388
+ ```
389
+
390
+ ---
391
+
392
+ ## 7. 运行时注册
393
+
394
+ ```typescript
395
+ // registry.ts — v2 API
396
+ import { system, world } from "@minecraft/server"
397
+ import { GuiBookItemComponent } from "./items/gui_book"
398
+
399
+ let registered = false
400
+
401
+ system.beforeEvents.startup.subscribe((initEvent: StartupEvent) => {
402
+ if (registered) return
403
+ registered = true
404
+ initEvent.itemComponentRegistry.registerCustomComponent(
405
+ "sapdon:neo_guibook",
406
+ GuiBookItemComponent
407
+ )
408
+ })
409
+ ```