sapdon 3.3.3 → 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.
@@ -114,7 +114,7 @@ BlockAPI.createRotatableBlock(
114
114
  | `options.group` | `string` | 分组,默认 `"construction"` |
115
115
  | `options.hide_in_command` | `boolean` | 是否在命令中隐藏,默认 `false` |
116
116
  | `options.rotationType` | `RotationTypes` | 旋转类型,默认 `RotationTypes.CARDINAL` |
117
- | `options.yRotationOffset` | `number` | Y轴旋转偏移,默认 `180` |
117
+ | `options.yRotationOffset` | `number` | Y轴旋转偏移,默认 `0` |
118
118
 
119
119
  **示例**
120
120
 
@@ -160,6 +160,9 @@ interface MaterialInstance {
160
160
  render_method?: 'opaque' | 'double_sided' | 'blend' | 'alpha_test' | 'alpha_test_single_sided'
161
161
  ambient_occlusion?: boolean | number
162
162
  face_dimming?: boolean
163
+ tint_method?: string // 生物群系染色方法,如 "grass"
164
+ alpha_masked_tint?: boolean // 是否基于 alpha 通道应用染色
165
+ isotropic?: boolean // 是否随机旋转 UV
163
166
  }
164
167
  ```
165
168
 
@@ -206,15 +209,28 @@ BlockAPI.createCropBlock(
206
209
  - `minecraft:placement_filter` → 仅允许放置在耕地上方
207
210
  - 每个生长阶段自动调整选择框高度
208
211
 
212
+ **运行时依赖**
213
+
214
+ 作物方块的生长、骨粉交互等行为需要注册框架内置的运行时组件。在 `scripts/index.ts` 中添加:
215
+
216
+ ```typescript
217
+ import { registerBuiltinComponents } from '@sapdon/runtime'
218
+ registerBuiltinComponents()
219
+ ```
220
+
209
221
  **示例**
210
222
 
211
223
  ```typescript
224
+ import { BlockAPI, registry } from '@sapdon/core'
225
+
212
226
  const crop = BlockAPI.createCropBlock('demo:tomato', 'nature', [
213
227
  { stateTag: 0, textures: ['stage_0', 'stage_0', 'stage_0', 'stage_0', 'stage_0', 'stage_0'] },
214
228
  { stateTag: 1, textures: ['stage_1', 'stage_1', 'stage_1', 'stage_1', 'stage_1', 'stage_1'] },
215
229
  { stateTag: 2, textures: ['stage_2', 'stage_2', 'stage_2', 'stage_2', 'stage_2', 'stage_2'] },
216
230
  { stateTag: 3, textures: ['stage_3', 'stage_3', 'stage_3', 'stage_3', 'stage_3', 'stage_3'] }
217
231
  ])
232
+
233
+ registry.submit()
218
234
  ```
219
235
 
220
236
  ---
@@ -256,13 +272,184 @@ BlockAPI.createOreBlock(
256
272
  const ore = BlockAPI.createOreBlock('demo:ruby_ore', 'nature',
257
273
  ['ruby_ore', 'ruby_ore', 'ruby_ore', 'ruby_ore', 'ruby_ore', 'ruby_ore']
258
274
  )
259
- // ore.block方块
275
+ // ore (OreBlock extends BasicBlock) 方块本身
260
276
  // ore.feature — 矿脉特征
261
277
  // ore.feature_rules — 特征规则
262
278
  ```
263
279
 
264
280
  ---
265
281
 
282
+ ---
283
+
284
+ ### createGlassBlock
285
+
286
+ 创建透明玻璃方块。
287
+
288
+ ```typescript
289
+ BlockAPI.createGlassBlock(
290
+ identifier: string,
291
+ category: string,
292
+ texture: string,
293
+ options?: GlassBlockOptions
294
+ ): GlassBlock
295
+ ```
296
+
297
+ **参数**
298
+
299
+ | 参数 | 类型 | 说明 |
300
+ |------|------|------|
301
+ | `identifier` | `string` | 方块唯一标识符 |
302
+ | `category` | `string` | 创造栏分类 |
303
+ | `texture` | `string` | 纹理短名(6 面复用) |
304
+ | `options.group` | `string` | 分组,默认 `"construction"` |
305
+ | `options.hide_in_command` | `boolean` | 是否在命令中隐藏,默认 `false` |
306
+ | `options.geometry` | `string` | 自定义几何模型标识符,如 `"geometry.custom_glass"` |
307
+ | `options.culling` | `string` | 裁剪规则标识符,如 `"wiki:culling.custom_glass"` |
308
+
309
+ **自动添加的组件**
310
+ - `minecraft:material_instances` → 6 面材质实例,`render_method: "blend"`
311
+ - `minecraft:light_dampening` → `0`
312
+ - `minecraft:destructible_by_mining` → `{ seconds_to_destroy: 0.3 }`
313
+ - `minecraft:destructible_by_explosion` → `{ explosion_resistance: 0.3 }`
314
+ - 可选 `minecraft:geometry`(设 `geometry` 参数时自动添加)
315
+
316
+ **示例**
317
+
318
+ ```typescript
319
+ const glass = BlockAPI.createGlassBlock('wiki:glass', 'construction', 'glass_tex')
320
+ ```
321
+
322
+ ---
323
+
324
+ ### createFenceBlock
325
+
326
+ 创建栅栏方块。
327
+
328
+ ```typescript
329
+ BlockAPI.createFenceBlock(
330
+ identifier: string,
331
+ category: string,
332
+ textures_arr: string[],
333
+ options?: FenceBlockOptions
334
+ ): FenceBlock
335
+ ```
336
+
337
+ **参数**
338
+
339
+ | 参数 | 类型 | 说明 |
340
+ |------|------|------|
341
+ | `identifier` | `string` | 方块唯一标识符 |
342
+ | `category` | `string` | 创造栏分类 |
343
+ | `textures_arr` | `string[]` | 6 纹理数组 |
344
+ | `options.group` | `string` | 分组,默认 `"construction"` |
345
+ | `options.hide_in_command` | `boolean` | 是否在命令中隐藏,默认 `false` |
346
+ | `options.leashable` | `boolean` | 是否可被拴绳拴住,默认 `false` |
347
+
348
+ **自动添加的组件**
349
+ - `minecraft:collision_box` → 自定义栅栏柱碰撞箱
350
+ - `minecraft:selection_box` → 同上
351
+ - `minecraft:support` → `{ shape: "fence" }`
352
+ - `minecraft:connection_rule` → 接受所有方向连接
353
+ - 可选 `minecraft:leashable`(设 `leashable` 参数时自动添加)
354
+
355
+ **示例**
356
+
357
+ ```typescript
358
+ const fence = BlockAPI.createFenceBlock('wiki:fence', 'construction',
359
+ ['fence_tex', 'fence_tex', 'fence_tex', 'fence_tex', 'fence_tex', 'fence_tex']
360
+ )
361
+ ```
362
+
363
+ ---
364
+
365
+ ### createStairBlock
366
+
367
+ 创建楼梯方块(8 个 permutation:4 方向 × 2 上下)。
368
+
369
+ ```typescript
370
+ BlockAPI.createStairBlock(
371
+ identifier: string,
372
+ category: string,
373
+ textures_arr: string[],
374
+ options?: StairBlockOptions
375
+ ): StairBlock
376
+ ```
377
+
378
+ **参数**
379
+
380
+ | 参数 | 类型 | 说明 |
381
+ |------|------|------|
382
+ | `identifier` | `string` | 方块唯一标识符 |
383
+ | `category` | `string` | 创造栏分类 |
384
+ | `textures_arr` | `string[]` | 6 纹理数组 |
385
+ | `options.group` | `string` | 分组,默认 `"construction"` |
386
+ | `options.hide_in_command` | `boolean` | 是否在命令中隐藏,默认 `false` |
387
+
388
+ **自动添加的组件**
389
+ - `minecraft:destructible_by_mining` / `minecraft:destructible_by_explosion`
390
+ - `minecraft:support` → `{ shape: "stair" }`
391
+
392
+ **自动注册的 Traits**
393
+ - `minecraft:placement_direction` → 控制 `minecraft:cardinal_direction` 状态
394
+ - `minecraft:placement_position` → 控制 `minecraft:vertical_half` 状态
395
+
396
+ **自动生成的 Permutations(8 个)**
397
+
398
+ 底部 4 方向 + 顶部 4 方向,每个 permutation 设置碰撞箱、选择框和旋转变换。
399
+
400
+ **示例**
401
+
402
+ ```typescript
403
+ const stair = BlockAPI.createStairBlock('wiki:stair', 'construction',
404
+ ['stair_tex', 'stair_tex', 'stair_tex', 'stair_tex', 'stair_tex', 'stair_tex']
405
+ )
406
+ ```
407
+
408
+ ---
409
+
410
+ ### createTrapdoorBlock
411
+
412
+ 创建活板门方块(16 个 permutation:4 方向 × 2 上下 × 2 开闭)。
413
+
414
+ ```typescript
415
+ BlockAPI.createTrapdoorBlock(
416
+ identifier: string,
417
+ category: string,
418
+ texture: string,
419
+ options?: TrapdoorBlockOptions
420
+ ): TrapdoorBlock
421
+ ```
422
+
423
+ **参数**
424
+
425
+ | 参数 | 类型 | 说明 |
426
+ |------|------|------|
427
+ | `identifier` | `string` | 方块唯一标识符 |
428
+ | `category` | `string` | 创造栏分类 |
429
+ | `texture` | `string` | 纹理短名(6 面复用) |
430
+ | `options.group` | `string` | 分组,默认 `"construction"` |
431
+ | `options.hide_in_command` | `boolean` | 是否在命令中隐藏,默认 `false` |
432
+
433
+ **自动添加的组件**
434
+ - `minecraft:material_instances` → 6 面材质实例,`render_method: "blend"`
435
+ - `minecraft:destructible_by_mining` / `minecraft:destructible_by_explosion`
436
+
437
+ **自动注册的 Traits**
438
+ - `minecraft:placement_direction` → 控制 `minecraft:cardinal_direction` 状态
439
+ - `minecraft:placement_position` → 控制 `minecraft:vertical_half` 状态
440
+
441
+ **自动生成的 Permutations(16 个)**
442
+
443
+ 每个 permutation 根据方向、上下半、开闭状态设置碰撞箱。
444
+
445
+ **示例**
446
+
447
+ ```typescript
448
+ const trapdoor = BlockAPI.createTrapdoorBlock('wiki:trapdoor', 'construction', 'trapdoor_tex')
449
+ ```
450
+
451
+ ---
452
+
266
453
  ## BasicBlock
267
454
 
268
455
  所有方块类型的基类。
@@ -337,7 +524,7 @@ block.addPermutation(
337
524
  ```typescript
338
525
  block.registerTrait('minecraft:placement_direction', {
339
526
  enabled_states: ['minecraft:cardinal_direction'],
340
- y_rotation_offset: 180
527
+ y_rotation_offset: 0
341
528
  })
342
529
  ```
343
530
 
@@ -482,6 +669,8 @@ new CropBlock(
482
669
  - `minecraft:placement_filter` → 仅限耕地上方
483
670
  - 每生长阶段设置自定义选择框高度
484
671
 
672
+ **运行时依赖:** 需调用 `registerBuiltinComponents()` 注册内置的生长脚本组件。
673
+
485
674
  ---
486
675
 
487
676
  ## GeometryBlock
@@ -527,16 +716,126 @@ new OreBlock(
527
716
  )
528
717
  ```
529
718
 
530
- ### 属性
719
+ ### 属性(继承自 BasicBlock 之外的额外属性)
531
720
 
532
721
  | 属性 | 类型 | 说明 |
533
722
  |------|------|------|
534
- | `block` | `BasicBlock` | 矿方块实例 |
535
723
  | `feature` | `OreFeature` | 矿脉特征 |
536
724
  | `feature_rules` | `FeatureRule` | 特征规则(默认 Y 0-64,10次/区块,主世界群系) |
537
725
 
538
726
  ---
539
727
 
728
+ ## GlassBlock
729
+
730
+ 继承自 `BasicBlock`,透明玻璃方块。
731
+
732
+ ```typescript
733
+ import { GlassBlock } from '@sapdon/core'
734
+ ```
735
+
736
+ ### 构造函数
737
+
738
+ ```typescript
739
+ new GlassBlock(
740
+ identifier: string,
741
+ category: string,
742
+ texture: string,
743
+ options?: {
744
+ group?: string
745
+ hide_in_command?: boolean
746
+ geometry?: string
747
+ culling?: string
748
+ }
749
+ )
750
+ ```
751
+
752
+ | 参数 | 类型 | 说明 |
753
+ |------|------|------|
754
+ | `texture` | `string` | 单纹理短名,6 面复用 |
755
+
756
+ 构造函数自动添加 `light_dampening: 0`、`render_method: "blend"` 材质实例、挖掘/爆炸抗性。可选 `geometry` + `culling` 支持相邻面剔除。
757
+
758
+ ---
759
+
760
+ ## FenceBlock
761
+
762
+ 继承自 `BasicBlock`,栅栏方块。
763
+
764
+ ```typescript
765
+ import { FenceBlock } from '@sapdon/core'
766
+ ```
767
+
768
+ ### 构造函数
769
+
770
+ ```typescript
771
+ new FenceBlock(
772
+ identifier: string,
773
+ category: string,
774
+ textures_arr: string[],
775
+ options?: {
776
+ group?: string
777
+ hide_in_command?: boolean
778
+ leashable?: boolean
779
+ }
780
+ )
781
+ ```
782
+
783
+ 构造函数自动添加自定义碰撞箱、`support: "fence"`、`connection_rule: "all"`。
784
+
785
+ ---
786
+
787
+ ## StairBlock
788
+
789
+ 继承自 `BasicBlock`,楼梯方块。
790
+
791
+ ```typescript
792
+ import { StairBlock } from '@sapdon/core'
793
+ ```
794
+
795
+ ### 构造函数
796
+
797
+ ```typescript
798
+ new StairBlock(
799
+ identifier: string,
800
+ category: string,
801
+ textures_arr: string[],
802
+ options?: {
803
+ group?: string
804
+ hide_in_command?: boolean
805
+ }
806
+ )
807
+ ```
808
+
809
+ 构造函数自动注册 `minecraft:cardinal_direction` 和 `minecraft:vertical_half` 状态,通过 `placement_direction` 和 `placement_position` trait 控制玩家放置朝向,生成 8 个 permutation(含半砖碰撞箱 + 方向旋转变换)。
810
+
811
+ ---
812
+
813
+ ## TrapdoorBlock
814
+
815
+ 继承自 `BasicBlock`,活板门方块。
816
+
817
+ ```typescript
818
+ import { TrapdoorBlock } from '@sapdon/core'
819
+ ```
820
+
821
+ ### 构造函数
822
+
823
+ ```typescript
824
+ new TrapdoorBlock(
825
+ identifier: string,
826
+ category: string,
827
+ texture: string,
828
+ options?: {
829
+ group?: string
830
+ hide_in_command?: boolean
831
+ }
832
+ )
833
+ ```
834
+
835
+ 构造函数自动注册 `minecraft:cardinal_direction`、`minecraft:vertical_half`、`minecraft:open` 三个状态,生成 16 个 permutation。活板门关闭时为薄板碰撞箱(下半或上半),打开时根据方向生成竖立薄板碰撞箱。
836
+
837
+ ---
838
+
540
839
  ## TileBlock
541
840
 
542
841
  方块与实体的组合,实现方块实体功能。
@@ -712,10 +1011,14 @@ static setFlammableEnabled(enabled: boolean): Map
712
1011
  ### setFlammableCustom
713
1012
 
714
1013
  ```typescript
715
- static setFlammableCustom(catchChanceModifier: number, destroyChanceModifier: number): Map
1014
+ static setFlammableCustom(
1015
+ catchChanceModifier: number,
1016
+ destroyChanceModifier: number,
1017
+ lava_flammable?: 'always' | 'never'
1018
+ ): Map
716
1019
  ```
717
1020
 
718
- 设置自定义燃烧概率(≥ 0)。
1021
+ 设置自定义燃烧概率(≥ 0)。可选 `lava_flammable` 参数控制岩浆能否点燃该方块,默认 `"never"`。
719
1022
 
720
1023
  ### setFriction
721
1024
 
@@ -752,10 +1055,13 @@ static setLoot(path: string): Map
752
1055
  ### setMapColor
753
1056
 
754
1057
  ```typescript
755
- static setMapColor(value: string | number[]): Map
1058
+ static setMapColor(value: string | number[] | { color: string | number[], tint_method?: string }): Map
756
1059
  ```
757
1060
 
758
- 设置地图颜色。支持十六进制字符串 `"#RRGGBB"` 或 RGB 数组 `[255, 0, 0]`。
1061
+ 设置地图颜色。支持:
1062
+ - 十六进制字符串 `"#RRGGBB"`
1063
+ - RGB 数组 `[255, 0, 0]`
1064
+ - 对象格式 `{ color: "#RRGGBB", tint_method: "grass" }` — 带生物群系染色
759
1065
 
760
1066
  ### setTransformation
761
1067
 
@@ -834,10 +1140,16 @@ static setCustomComponentV2(component_id: string, params: object): Map
834
1140
  ### setDestructionParticles
835
1141
 
836
1142
  ```typescript
837
- static setDestructionParticles(texture: string, tint_method?: string): Map
1143
+ static setDestructionParticles(
1144
+ texture: string,
1145
+ options?: {
1146
+ particle_count?: number // 粒子数量 0-255,默认 100
1147
+ tint_method?: string // 染色方法,如 "grass"
1148
+ }
1149
+ ): Map
838
1150
  ```
839
1151
 
840
- 设置破坏粒子纹理。
1152
+ 设置破坏粒子纹理。可选 `particle_count` 控制粒子数量(0-255,默认 100)。
841
1153
 
842
1154
  ### setItemVisual
843
1155
 
@@ -850,15 +1162,39 @@ static setItemVisual(geometry: string, materialInstances: object): Map
850
1162
  ### setLiquidDetection
851
1163
 
852
1164
  ```typescript
1165
+ // 选项对象格式(推荐,支持多检测规则)
1166
+ static setLiquidDetection(options: {
1167
+ detection_rules?: {
1168
+ liquid_type: string
1169
+ can_contain_liquid: boolean
1170
+ on_liquid_touches?: 'blocking' | 'broken' | 'popped' | 'no_reaction'
1171
+ stops_liquid_flowing_from_direction?: string[]
1172
+ use_liquid_clipping?: boolean
1173
+ }[]
1174
+ use_liquid_clipping?: boolean
1175
+ }): Map
1176
+
1177
+ // 旧版单规则格式(向后兼容)
853
1178
  static setLiquidDetection(
854
1179
  canContainLiquid: boolean,
855
1180
  liquidType?: 'water',
856
1181
  onLiquidTouches?: 'blocking' | 'broken' | 'popped' | 'no_reaction',
857
- stopsLiquidFlowingFromDirection?: ('up' | 'down' | 'north' | 'south' | 'east' | 'west')[]
1182
+ stopsLiquidFlowingFromDirection?: string[]
858
1183
  ): Map
859
1184
  ```
860
1185
 
861
- 设置液体检测属性。
1186
+ 设置液体检测属性。使用对象参数时可设置 `detection_rules` 数组(支持水淹等行为)和 `use_liquid_clipping`。
1187
+
1188
+ ```typescript
1189
+ // 示例:水淹方块
1190
+ BlockComponent.setLiquidDetection({
1191
+ detection_rules: [{
1192
+ liquid_type: "water",
1193
+ can_contain_liquid: true,
1194
+ on_liquid_touches: "no_reaction"
1195
+ }]
1196
+ })
1197
+ ```
862
1198
 
863
1199
  ### setBreathability
864
1200
 
@@ -893,6 +1229,134 @@ static toJSON(components: Map): object
893
1229
 
894
1230
  ---
895
1231
 
1232
+ ## BlockCustomComponentBuilder
1233
+
1234
+ 块自定义组件构建器,提供 TypeScript 类型安全的流式 API 定义块事件处理器,并可生成脚本端注册代码。
1235
+
1236
+ ```typescript
1237
+ import { BlockCustomComponentBuilder } from '@sapdon/core'
1238
+ ```
1239
+
1240
+ ### 构造函数
1241
+
1242
+ ```typescript
1243
+ new BlockCustomComponentBuilder(componentId: string)
1244
+ ```
1245
+
1246
+ | 参数 | 类型 | 说明 |
1247
+ |------|------|------|
1248
+ | `componentId` | `string` | 自定义组件标识符,格式 `"命名空间:组件名"` |
1249
+
1250
+ ### 方法
1251
+
1252
+ #### 事件绑定(均返回 `this`,可链式调用)
1253
+
1254
+ | 方法 | 对应事件 | Wiki 说明 |
1255
+ |------|---------|-----------|
1256
+ | `beforeOnPlayerPlace(handler)` | `beforeOnPlayerPlace` | 玩家放置前触发 |
1257
+ | `onBlockStateChange(handler)` | `onBlockStateChange` | 块状态改变时触发 |
1258
+ | `onBreak(handler)` | `onBreak` | 块被破坏时触发 |
1259
+ | `onEntity(handler)` | `onEntity` | 实体在块上执行事件时触发 |
1260
+ | `onEntityFallOn(handler)` | `onEntityFallOn` | 实体坠落在块上时触发 |
1261
+ | `onPlace(handler)` | `onPlace` | 块被放置时触发 |
1262
+ | `onPlayerBreak(handler)` | `onPlayerBreak` | 玩家破坏块时触发 |
1263
+ | `onPlayerInteract(handler)` | `onPlayerInteract` | 玩家与块交互时触发 |
1264
+ | `onRandomTick(handler)` | `onRandomTick` | 随机刻触发 |
1265
+ | `onRedstoneUpdate(handler)` | `onRedstoneUpdate` | 红石信号更新时触发 |
1266
+ | `onStepOff(handler)` | `onStepOff` | 实体离开块时触发 |
1267
+ | `onStepOn(handler)` | `onStepOn` | 实体踏上块时触发 |
1268
+ | `onTick(handler)` | `onTick` | 块计划刻触发 |
1269
+
1270
+ #### `id(): string`
1271
+
1272
+ 返回组件标识符,用于 `BlockComponent.setCustomComponents()`。
1273
+
1274
+ #### `build(): BlockCustomComponentHandlers`
1275
+
1276
+ 构建处理器对象,可用于 runtime 的 `registerCustomComponent`。
1277
+
1278
+ #### `handlerCount(): number`
1279
+
1280
+ 返回已注册的事件处理器数量。
1281
+
1282
+ ### 事件参数类型
1283
+
1284
+ | 接口名 | 属性 |
1285
+ |--------|------|
1286
+ | `BeforeOnPlayerPlaceEvent` | `block`, `cancel`, `dimension`, `face`, `permutationToPlace`, `player?` |
1287
+ | `OnBlockStateChangeEvent` | `block`, `dimension`, `previousPermutation` |
1288
+ | `OnBreakEvent` | `block`, `dimension`, `blockDestructionSource?`, `brokenBlockPermutation`, `entitySource?` |
1289
+ | `OnEntityEvent` | `block`, `blockPermutation`, `dimension`, `entitySource`, `name` |
1290
+ | `OnEntityFallOnEvent` | `block`, `dimension`, `entity?`, `fallDistance` |
1291
+ | `OnPlaceEvent` | `block`, `dimension`, `previousBlock` |
1292
+ | `OnPlayerBreakEvent` | `block`, `brokenBlockPermutation`, `dimension`, `player?` |
1293
+ | `OnPlayerInteractEvent` | `block`, `dimension`, `face`, `faceLocation`, `player?` |
1294
+ | `OnRandomTickEvent` | `block`, `dimension` |
1295
+ | `OnRedstoneUpdateEvent` | `block`, `dimension`, `power` |
1296
+ | `OnStepOffEvent` | `block`, `dimension`, `entity?` |
1297
+ | `OnStepOnEvent` | `block`, `dimension`, `entity?` |
1298
+ | `OnTickEvent` | `block`, `dimension` |
1299
+
1300
+ ### 示例
1301
+
1302
+ ```typescript
1303
+ import { BlockAPI, BlockComponent, BlockCustomComponentBuilder, registry } from '@sapdon/core'
1304
+
1305
+ // 定义块自定义组件事件处理器(构建时)
1306
+ const growComponent = new BlockCustomComponentBuilder('wiki:crop_grow')
1307
+ .onRandomTick(({ block }) => {
1308
+ const stage = block.permutation.getState('sapdon:block_variant_tag') as number
1309
+ if (stage < 3) {
1310
+ block.setPermutation(
1311
+ block.permutation.withState('sapdon:block_variant_tag', stage + 1)
1312
+ )
1313
+ }
1314
+ })
1315
+ .onPlayerInteract(({ block, player }) => {
1316
+ if (player?.getGameMode() === 'creative') {
1317
+ block.setPermutation(
1318
+ block.permutation.withState('sapdon:block_variant_tag', 3)
1319
+ )
1320
+ }
1321
+ })
1322
+
1323
+ // 创建方块并关联组件 ID
1324
+ const crop = BlockAPI.createCropBlock('wiki:tomato', 'nature', [
1325
+ { stateTag: 0, textures: ['stage_0', 'stage_0', 'stage_0', 'stage_0', 'stage_0', 'stage_0'] },
1326
+ { stateTag: 1, textures: ['stage_1', 'stage_1', 'stage_1', 'stage_1', 'stage_1', 'stage_1'] },
1327
+ { stateTag: 2, textures: ['stage_2', 'stage_2', 'stage_2', 'stage_2', 'stage_2', 'stage_2'] },
1328
+ { stateTag: 3, textures: ['stage_3', 'stage_3', 'stage_3', 'stage_3', 'stage_3', 'stage_3'] }
1329
+ ])
1330
+ crop.addComponent(BlockComponent.setCustomComponents([growComponent.id()]))
1331
+
1332
+ registry.submit()
1333
+ ```
1334
+
1335
+ ### 运行时脚本自动生成
1336
+
1337
+ `registry.submit()` 会自动收集所有 `BlockCustomComponentBuilder` 实例,并在构建时通过 `load.js` 生成对应的运行时脚本文件:
1338
+
1339
+ - **脚本文件** → `scripts/custom_components/{componentId}.js`(以 `:` 替换为 `_` 命名)
1340
+ - **索引文件** → `scripts/custom_components/index.js`(以正确 ID 注册所有组件)
1341
+ - 文件已存在时**跳过**,不会覆盖用户修改
1342
+
1343
+ 需要在项目入口文件 `scripts/index.js`(或 `scripts/index.ts`)中添加导入:
1344
+
1345
+ ```typescript
1346
+ import './custom_components/index.js'
1347
+ ```
1348
+
1349
+ 这样 `load.js` 生成的注册代码即可自动执行。
1350
+
1351
+ 内置 OC 运行时组件(如 `sapdon:head_rotation`)注册只需调用:
1352
+
1353
+ ```typescript
1354
+ import { registerBuiltinComponents } from '@sapdon/runtime'
1355
+ registerBuiltinComponents()
1356
+ ```
1357
+
1358
+ ---
1359
+
896
1360
  ## Permutation
897
1361
 
898
1362
  方块变体,由条件和组件集合组成。
@@ -917,6 +1381,113 @@ interface Permutation {
917
1381
 
918
1382
  ---
919
1383
 
1384
+ ---
1385
+
1386
+ ## TintMethod
1387
+
1388
+ 生物群系染色方法常量,用于 `BlockComponent.setMaterialInstances()` 和 `BlockComponent.setMapColor()` 的 `tint_method` 参数。
1389
+
1390
+ ```typescript
1391
+ import { TintMethod } from '@sapdon/core'
1392
+ ```
1393
+
1394
+ ```typescript
1395
+ const TintMethod = {
1396
+ GRASS: 'grass', // 草地色
1397
+ WATER: 'water', // 水色
1398
+ DEFAULT_FOLIAGE: 'default_foliage', // 默认 foliage 色
1399
+ EVERGREEN_FOLIAGE: 'evergreen_foliage', // 常绿 foliage 色
1400
+ DRY_FOLIAGE: 'dry_foliage', // 干 foliage 色
1401
+ BIRCH_FOLIAGE: 'birch_foliage', // 白桦 foliage 色
1402
+ } as const
1403
+ ```
1404
+
1405
+ **示例**
1406
+
1407
+ ```typescript
1408
+ BlockComponent.setMaterialInstances({
1409
+ '*': { texture: 'grass_tex', render_method: 'opaque', tint_method: TintMethod.GRASS }
1410
+ })
1411
+ ```
1412
+
1413
+ ---
1414
+
1415
+ ## FlipbookTextureConfig
1416
+
1417
+ 翻转书纹理配置构建器,用于生成资源包 `flipbook_textures.json`。
1418
+
1419
+ ```typescript
1420
+ import { FlipbookTextureConfig } from '@sapdon/core'
1421
+ ```
1422
+
1423
+ ### 方法
1424
+
1425
+ | 方法 | 说明 |
1426
+ |------|------|
1427
+ | `addEntry(entry: FlipbookEntry)` | 添加一个翻转书纹理条目 |
1428
+ | `addEntries(entries: FlipbookEntry[])` | 批量添加多个条目 |
1429
+ | `toObject()` | 生成 `{ flipbook_textures: [...] }` 对象,可直接注册到资源包 |
1430
+
1431
+ **FlipbookEntry**
1432
+
1433
+ ```typescript
1434
+ interface FlipbookEntry {
1435
+ flipbook_texture: string // 纹理短名
1436
+ atlas_tile?: string // 图集 tile 名称(默认同 flipbook_texture)
1437
+ ticks_per_frame?: number // 每帧停留 tick 数(默认 2)
1438
+ blend_frames?: boolean // 是否混合帧(默认 false)
1439
+ replicate?: number // 复制次数(默认 1)
1440
+ }
1441
+ ```
1442
+
1443
+ **示例**
1444
+
1445
+ ```typescript
1446
+ const flipbook = new FlipbookTextureConfig()
1447
+ .addEntry({ flipbook_texture: 'water_flow', ticks_per_frame: 3 })
1448
+ .addEntry({ flipbook_texture: 'lava_flow', ticks_per_frame: 2, blend_frames: true })
1449
+ ```
1450
+
1451
+ ---
1452
+
1453
+ ## TextureVariationConfig
1454
+
1455
+ 纹理变体配置构建器,用于生成资源包 `terrain_texture.json`。
1456
+
1457
+ ```typescript
1458
+ import { TextureVariationConfig } from '@sapdon/core'
1459
+ ```
1460
+
1461
+ ### 方法
1462
+
1463
+ | 方法 | 说明 |
1464
+ |------|------|
1465
+ | `addTexture(name, path)` | 添加单纹理映射:短名 → 图片路径 |
1466
+ | `addTextureWithVariations(name, variations)` | 添加带权重的多变体纹理 |
1467
+ | `toObject()` | 生成 `{ texture_data: {...} }` 对象,可直接注册到资源包 |
1468
+
1469
+ **TextureVariation**
1470
+
1471
+ ```typescript
1472
+ interface TextureVariation {
1473
+ path: string // 纹理图片路径
1474
+ weight?: number // 随机权重(默认 1)
1475
+ }
1476
+ ```
1477
+
1478
+ **示例**
1479
+
1480
+ ```typescript
1481
+ const tex = new TextureVariationConfig()
1482
+ .addTexture('stone', 'textures/blocks/stone')
1483
+ .addTextureWithVariations('grass', [
1484
+ { path: 'textures/blocks/grass_1', weight: 3 },
1485
+ { path: 'textures/blocks/grass_2', weight: 1 }
1486
+ ])
1487
+ ```
1488
+
1489
+ ---
1490
+
920
1491
  ## 类型汇总
921
1492
 
922
1493
  ```typescript
@@ -927,6 +1498,10 @@ BlockAPI.createRotatableBlock(identifier, category, textures_arr, options?)
927
1498
  BlockAPI.createGeometryBlock(identifier, category, geometry, material_instances, options?)
928
1499
  BlockAPI.createCropBlock(identifier, category, variantDatas, options?)
929
1500
  BlockAPI.createOreBlock(identifier, category, textures_arr, options?)
1501
+ BlockAPI.createGlassBlock(identifier, category, texture, options?)
1502
+ BlockAPI.createFenceBlock(identifier, category, textures_arr, options?)
1503
+ BlockAPI.createStairBlock(identifier, category, textures_arr, options?)
1504
+ BlockAPI.createTrapdoorBlock(identifier, category, texture, options?)
930
1505
 
931
1506
  // 类
932
1507
  class BasicBlock { ... }
@@ -934,12 +1509,22 @@ class Block extends BasicBlock { ... }
934
1509
  class RotatableBlock extends BasicBlock { ... }
935
1510
  class GeometryBlock extends BasicBlock { ... }
936
1511
  class CropBlock extends Block { ... }
937
- class OreBlock { block, feature, feature_rules }
1512
+ class OreBlock extends BasicBlock { feature, feature_rules }
1513
+ class GlassBlock extends BasicBlock { ... }
1514
+ class FenceBlock extends BasicBlock { ... }
1515
+ class StairBlock extends BasicBlock { ... }
1516
+ class TrapdoorBlock extends BasicBlock { ... }
938
1517
  class TileBlock { block, entity }
939
1518
 
940
1519
  // 枚举
941
1520
  RotationTypes = { CARDINAL, FACING, BLOCK_FACE, LOG }
1521
+ TintMethod = { GRASS, WATER, DEFAULT_FOLIAGE, EVERGREEN_FOLIAGE, DRY_FOLIAGE, BIRCH_FOLIAGE }
942
1522
 
943
1523
  // 工具类
944
1524
  BlockComponent = { setMaterialInstances, setGeometry, ... }
1525
+ class FlipbookTextureConfig { addEntry, addEntries, toObject }
1526
+ class TextureVariationConfig { addTexture, addTextureWithVariations, toObject }
1527
+
1528
+ // 块自定义组件构建器
1529
+ class BlockCustomComponentBuilder { constructor(componentId), id(), build(), handlerCount(), onTick(), ... }
945
1530
  ```