From 4896c1a4f2af2578baae6f69bdbe2d4c79bffd7f Mon Sep 17 00:00:00 2001 From: boybook Date: Thu, 20 Mar 2025 00:13:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=90=AC=E8=BF=90=E4=B8=80=E6=89=B9Bedrock=20w?= =?UTF-8?q?iki=E5=86=85=E5=AE=B9=EF=BC=8C=E5=AE=8C=E5=96=84=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/wiki/1-Mod脚本开发/1-快速入门Mod开发.md | 4 +- .../{2-为什么是System.md => 为什么是System.md} | 44 +- docs/wiki/2-方块/1-基础/blocks-intro.md | 44 +- docs/wiki/3-实体/2-巧思案例/boat-entities.md | 91 +- .../2-巧思案例/detecting-other-entities.md | 305 +- .../2-巧思案例/disabling-team-damage.md | 124 +- docs/wiki/3-实体/2-巧思案例/dummy-entities.md | 67 +- docs/wiki/3-实体/2-巧思案例/entity-attack.md | 435 ++- .../3-实体/2-巧思案例/entity-holds-item.md | 56 +- .../wiki/3-实体/2-巧思案例/entity-movement.md | 191 +- .../wiki/3-实体/2-巧思案例/flying-entities.md | 141 +- .../3-实体/2-巧思案例/introduction-to-aec.md | 108 +- .../2-巧思案例/invulnerable-entities.md | 64 +- docs/wiki/3-实体/2-巧思案例/look-at-entity.md | 41 +- .../3-实体/2-巧思案例/sleeping-entities.md | 173 +- docs/wiki/3-实体/2-巧思案例/solid-entities.md | 70 +- docs/wiki/3-实体/2-巧思案例/timers.md | 289 +- .../3-实体/2-巧思案例/village-mechanic.md | 206 +- .../3-实体/3-文档/vanilla-usage-components.md | 4 +- .../3-文档/vanilla-usage-spawn-rules.md | 4 +- docs/wiki/3-实体/3-文档/vuc-full.md | 4 +- docs/wiki/3-实体/3-文档/vusr-full.md | 4 +- docs/wiki/4-Json-UI/1-基础/json-ui-intro.md | 374 ++- .../4-Json-UI/2-巧思案例/add-hud-elements.md | 5 + .../2-巧思案例/aseprite-animations.md | 4 +- .../2-巧思案例/preserve-title-texts.md | 37 +- .../4-Json-UI/3-文档/json-ui-documentation.md | 78 +- docs/wiki/commands/block-entities.md | 173 ++ docs/wiki/commands/block-states.md | 118 + docs/wiki/commands/damage.md | 96 + docs/wiki/commands/entity-counter.md | 89 + docs/wiki/commands/index.md | 14 + docs/wiki/commands/intro-to-command-blocks.md | 141 + docs/wiki/commands/mcfunctions.md | 158 + docs/wiki/commands/nbt-commands.md | 108 + docs/wiki/commands/new-execute.md | 247 ++ docs/wiki/commands/on-first-join.md | 73 + docs/wiki/commands/on-first-world-load.md | 78 + docs/wiki/commands/on-player-death.md | 95 + docs/wiki/commands/on-player-join.md | 86 + docs/wiki/commands/on-player-leave.md | 107 + docs/wiki/commands/on-player-respawn.md | 86 + docs/wiki/commands/playsound.md | 79 + docs/wiki/commands/relative-coordinates.md | 46 + docs/wiki/commands/scoreboard-operations.md | 135 + docs/wiki/commands/scoreboard-timers.md | 200 ++ docs/wiki/commands/selectors.md | 217 ++ docs/wiki/commands/tellraw.md | 132 + docs/wiki/concepts/contents.md | 84 + docs/wiki/concepts/emojis.md | 289 ++ docs/wiki/concepts/index.md | 3 + docs/wiki/concepts/molang.md | 47 + docs/wiki/concepts/namespaces.md | 51 + docs/wiki/concepts/overwriting-assets.md | 120 + docs/wiki/concepts/shaders.md | 161 + docs/wiki/concepts/sounds.md | 331 ++ docs/wiki/concepts/subpacks.md | 95 + docs/wiki/concepts/text-and-translations.md | 156 + docs/wiki/concepts/textures-list.md | 43 + docs/wiki/documentation/advanced-molang.md | 70 + .../wiki/documentation/creative-categories.md | 180 ++ docs/wiki/documentation/file-types.md | 106 + docs/wiki/documentation/fog-ids.md | 163 + docs/wiki/documentation/index.md | 3 + .../material-config-description.md | 618 ++++ docs/wiki/documentation/materials.md | 419 +++ docs/wiki/documentation/pack-structure.md | 113 + docs/wiki/documentation/projectiles.md | 256 ++ docs/wiki/documentation/queries.md | 567 ++++ docs/wiki/documentation/shared-constructs.md | 40 + docs/wiki/documentation/sound-definitions.md | 2712 +++++++++++++++++ docs/wiki/guide/addons.md | 72 + docs/wiki/guide/advancedmanifest.md | 47 + docs/wiki/guide/blockbench.md | 283 ++ docs/wiki/guide/custom-entity.md | 1431 +++++++++ docs/wiki/guide/custom-item.md | 322 ++ docs/wiki/guide/download-packs.md | 33 + docs/wiki/guide/format-version.md | 110 + docs/wiki/guide/index.md | 13 + docs/wiki/guide/introduction.md | 60 + docs/wiki/guide/loot-table.md | 179 ++ docs/wiki/guide/project-setup-android.md | 261 ++ docs/wiki/guide/project-setup.md | 300 ++ docs/wiki/guide/software-preparation.md | 179 ++ docs/wiki/guide/troubleshooting.md | 81 + docs/wiki/guide/understanding-json.md | 151 + docs/wiki/items/attachables.md | 251 ++ docs/wiki/items/custom-armor.md | 562 ++++ docs/wiki/items/custom-weapon.md | 277 ++ docs/wiki/items/enchantments.md | 54 + docs/wiki/items/equipped-item-commands.md | 260 ++ docs/wiki/items/index.md | 10 + docs/wiki/items/item-components.md | 510 ++++ docs/wiki/items/item-identifiers.md | 138 + docs/wiki/items/item-tags.md | 125 + docs/wiki/items/items-intro.md | 156 + docs/wiki/items/numerical-item-ids.md | 1422 +++++++++ docs/wiki/items/spawning-items.md | 176 ++ docs/wiki/items/spear.md | 402 +++ docs/wiki/items/throwable.md | 382 +++ docs/wiki/items/tool-durability.md | 267 ++ docs/wiki/items/troubleshooting-items.md | 243 ++ docs/wiki/items/vanilla-usage-items.md | 536 ++++ docs/wiki/items/vui-full.md | 1005 ++++++ docs/wiki/loot/index.md | 10 + docs/wiki/loot/item-functions.md | 746 +++++ docs/wiki/loot/loot-tables.md | 292 ++ docs/wiki/loot/randomized-structure-loot.md | 125 + docs/wiki/loot/recipes.md | 778 +++++ docs/wiki/loot/trade-tables.md | 703 +++++ docs/wiki/loot/trading-behavior.md | 32 + docs/wiki/meta/addon-performance.md | 218 ++ docs/wiki/meta/index.md | 3 + docs/wiki/meta/jq.md | 154 + docs/wiki/meta/style-guide.md | 167 + docs/wiki/meta/useful-links.md | 157 + docs/wiki/meta/using-schemas.md | 63 + docs/wiki/meta/version-control.md | 89 + .../nbt/experimental-education-edition.md | 52 + docs/wiki/nbt/index.md | 10 + docs/wiki/nbt/mcstructure.md | 127 + docs/wiki/nbt/nbt-in-depth.md | 88 + docs/wiki/nbt/step-by-step-example.md | 84 + docs/wiki/nbt/structure-limits.md | 47 + docs/wiki/particles/disabling-particles.md | 40 + docs/wiki/particles/index.md | 10 + docs/wiki/particles/particles-and-sounds.md | 336 ++ docs/wiki/particles/particles.md | 43 + docs/wiki/particles/vanilla-particles.md | 225 ++ docs/wiki/servers/index.md | 3 + docs/wiki/servers/raknet-and-mcpe.md | 126 + docs/wiki/servers/server-software.md | 212 ++ docs/wiki/visuals/animated-entity-texture.md | 123 + docs/wiki/visuals/animation-effects.md | 181 ++ docs/wiki/visuals/bedrock-modeling.md | 122 + docs/wiki/visuals/custom-skin-packs.md | 137 + docs/wiki/visuals/death-animations.md | 390 +++ docs/wiki/visuals/deferred-qna.md | 248 ++ docs/wiki/visuals/glowing-texture.md | 100 + docs/wiki/visuals/index.md | 14 + docs/wiki/visuals/introduction.md | 17 + docs/wiki/visuals/leash-position.md | 53 + docs/wiki/visuals/material-creations.md | 223 ++ docs/wiki/visuals/materials.md | 239 ++ docs/wiki/visuals/math-based-animations.md | 99 + docs/wiki/visuals/player-geometry.md | 517 ++++ docs/wiki/visuals/remove-shadows.md | 122 + docs/wiki/visuals/retexturing-spawn-eggs.md | 59 + docs/wiki/visuals/structure-presentation.md | 53 + docs/wiki/vr/editing-your-first-model.md | 145 + docs/wiki/vr/index.md | 11 + docs/wiki/vr/installing-bedrock-vr.md | 49 + docs/wiki/vr/pack_setup.md | 57 + docs/wiki/world-generation/biome-tags.md | 166 + docs/wiki/world-generation/biomes.md | 1876 ++++++++++++ docs/wiki/world-generation/custom-ores.md | 116 + .../feature-block-conditions.md | 182 ++ docs/wiki/world-generation/feature-types.md | 1724 +++++++++++ docs/wiki/world-generation/heightmap-noise.md | 116 + docs/wiki/world-generation/index.md | 10 + .../world-generation/structure-features.md | 393 +++ docs/wiki/world-generation/surface-builder.md | 202 ++ .../world-generation-intro.md | 340 +++ 163 files changed, 33930 insertions(+), 1464 deletions(-) rename docs/wiki/1-Mod脚本开发/{2-为什么是System.md => 为什么是System.md} (86%) create mode 100644 docs/wiki/commands/block-entities.md create mode 100644 docs/wiki/commands/block-states.md create mode 100644 docs/wiki/commands/damage.md create mode 100644 docs/wiki/commands/entity-counter.md create mode 100644 docs/wiki/commands/index.md create mode 100644 docs/wiki/commands/intro-to-command-blocks.md create mode 100644 docs/wiki/commands/mcfunctions.md create mode 100644 docs/wiki/commands/nbt-commands.md create mode 100644 docs/wiki/commands/new-execute.md create mode 100644 docs/wiki/commands/on-first-join.md create mode 100644 docs/wiki/commands/on-first-world-load.md create mode 100644 docs/wiki/commands/on-player-death.md create mode 100644 docs/wiki/commands/on-player-join.md create mode 100644 docs/wiki/commands/on-player-leave.md create mode 100644 docs/wiki/commands/on-player-respawn.md create mode 100644 docs/wiki/commands/playsound.md create mode 100644 docs/wiki/commands/relative-coordinates.md create mode 100644 docs/wiki/commands/scoreboard-operations.md create mode 100644 docs/wiki/commands/scoreboard-timers.md create mode 100644 docs/wiki/commands/selectors.md create mode 100644 docs/wiki/commands/tellraw.md create mode 100644 docs/wiki/concepts/contents.md create mode 100644 docs/wiki/concepts/emojis.md create mode 100644 docs/wiki/concepts/index.md create mode 100644 docs/wiki/concepts/molang.md create mode 100644 docs/wiki/concepts/namespaces.md create mode 100644 docs/wiki/concepts/overwriting-assets.md create mode 100644 docs/wiki/concepts/shaders.md create mode 100644 docs/wiki/concepts/sounds.md create mode 100644 docs/wiki/concepts/subpacks.md create mode 100644 docs/wiki/concepts/text-and-translations.md create mode 100644 docs/wiki/concepts/textures-list.md create mode 100644 docs/wiki/documentation/advanced-molang.md create mode 100644 docs/wiki/documentation/creative-categories.md create mode 100644 docs/wiki/documentation/file-types.md create mode 100644 docs/wiki/documentation/fog-ids.md create mode 100644 docs/wiki/documentation/index.md create mode 100644 docs/wiki/documentation/material-config-description.md create mode 100644 docs/wiki/documentation/materials.md create mode 100644 docs/wiki/documentation/pack-structure.md create mode 100644 docs/wiki/documentation/projectiles.md create mode 100644 docs/wiki/documentation/queries.md create mode 100644 docs/wiki/documentation/shared-constructs.md create mode 100644 docs/wiki/documentation/sound-definitions.md create mode 100644 docs/wiki/guide/addons.md create mode 100644 docs/wiki/guide/advancedmanifest.md create mode 100644 docs/wiki/guide/blockbench.md create mode 100644 docs/wiki/guide/custom-entity.md create mode 100644 docs/wiki/guide/custom-item.md create mode 100644 docs/wiki/guide/download-packs.md create mode 100644 docs/wiki/guide/format-version.md create mode 100644 docs/wiki/guide/index.md create mode 100644 docs/wiki/guide/introduction.md create mode 100644 docs/wiki/guide/loot-table.md create mode 100644 docs/wiki/guide/project-setup-android.md create mode 100644 docs/wiki/guide/project-setup.md create mode 100644 docs/wiki/guide/software-preparation.md create mode 100644 docs/wiki/guide/troubleshooting.md create mode 100644 docs/wiki/guide/understanding-json.md create mode 100644 docs/wiki/items/attachables.md create mode 100644 docs/wiki/items/custom-armor.md create mode 100644 docs/wiki/items/custom-weapon.md create mode 100644 docs/wiki/items/enchantments.md create mode 100644 docs/wiki/items/equipped-item-commands.md create mode 100644 docs/wiki/items/index.md create mode 100644 docs/wiki/items/item-components.md create mode 100644 docs/wiki/items/item-identifiers.md create mode 100644 docs/wiki/items/item-tags.md create mode 100644 docs/wiki/items/items-intro.md create mode 100644 docs/wiki/items/numerical-item-ids.md create mode 100644 docs/wiki/items/spawning-items.md create mode 100644 docs/wiki/items/spear.md create mode 100644 docs/wiki/items/throwable.md create mode 100644 docs/wiki/items/tool-durability.md create mode 100644 docs/wiki/items/troubleshooting-items.md create mode 100644 docs/wiki/items/vanilla-usage-items.md create mode 100644 docs/wiki/items/vui-full.md create mode 100644 docs/wiki/loot/index.md create mode 100644 docs/wiki/loot/item-functions.md create mode 100644 docs/wiki/loot/loot-tables.md create mode 100644 docs/wiki/loot/randomized-structure-loot.md create mode 100644 docs/wiki/loot/recipes.md create mode 100644 docs/wiki/loot/trade-tables.md create mode 100644 docs/wiki/loot/trading-behavior.md create mode 100644 docs/wiki/meta/addon-performance.md create mode 100644 docs/wiki/meta/index.md create mode 100644 docs/wiki/meta/jq.md create mode 100644 docs/wiki/meta/style-guide.md create mode 100644 docs/wiki/meta/useful-links.md create mode 100644 docs/wiki/meta/using-schemas.md create mode 100644 docs/wiki/meta/version-control.md create mode 100644 docs/wiki/nbt/experimental-education-edition.md create mode 100644 docs/wiki/nbt/index.md create mode 100644 docs/wiki/nbt/mcstructure.md create mode 100644 docs/wiki/nbt/nbt-in-depth.md create mode 100644 docs/wiki/nbt/step-by-step-example.md create mode 100644 docs/wiki/nbt/structure-limits.md create mode 100644 docs/wiki/particles/disabling-particles.md create mode 100644 docs/wiki/particles/index.md create mode 100644 docs/wiki/particles/particles-and-sounds.md create mode 100644 docs/wiki/particles/particles.md create mode 100644 docs/wiki/particles/vanilla-particles.md create mode 100644 docs/wiki/servers/index.md create mode 100644 docs/wiki/servers/raknet-and-mcpe.md create mode 100644 docs/wiki/servers/server-software.md create mode 100644 docs/wiki/visuals/animated-entity-texture.md create mode 100644 docs/wiki/visuals/animation-effects.md create mode 100644 docs/wiki/visuals/bedrock-modeling.md create mode 100644 docs/wiki/visuals/custom-skin-packs.md create mode 100644 docs/wiki/visuals/death-animations.md create mode 100644 docs/wiki/visuals/deferred-qna.md create mode 100644 docs/wiki/visuals/glowing-texture.md create mode 100644 docs/wiki/visuals/index.md create mode 100644 docs/wiki/visuals/introduction.md create mode 100644 docs/wiki/visuals/leash-position.md create mode 100644 docs/wiki/visuals/material-creations.md create mode 100644 docs/wiki/visuals/materials.md create mode 100644 docs/wiki/visuals/math-based-animations.md create mode 100644 docs/wiki/visuals/player-geometry.md create mode 100644 docs/wiki/visuals/remove-shadows.md create mode 100644 docs/wiki/visuals/retexturing-spawn-eggs.md create mode 100644 docs/wiki/visuals/structure-presentation.md create mode 100644 docs/wiki/vr/editing-your-first-model.md create mode 100644 docs/wiki/vr/index.md create mode 100644 docs/wiki/vr/installing-bedrock-vr.md create mode 100644 docs/wiki/vr/pack_setup.md create mode 100644 docs/wiki/world-generation/biome-tags.md create mode 100644 docs/wiki/world-generation/biomes.md create mode 100644 docs/wiki/world-generation/custom-ores.md create mode 100644 docs/wiki/world-generation/feature-block-conditions.md create mode 100644 docs/wiki/world-generation/feature-types.md create mode 100644 docs/wiki/world-generation/heightmap-noise.md create mode 100644 docs/wiki/world-generation/index.md create mode 100644 docs/wiki/world-generation/structure-features.md create mode 100644 docs/wiki/world-generation/surface-builder.md create mode 100644 docs/wiki/world-generation/world-generation-intro.md diff --git a/docs/wiki/1-Mod脚本开发/1-快速入门Mod开发.md b/docs/wiki/1-Mod脚本开发/1-快速入门Mod开发.md index 042a533e..b7a2c06c 100644 --- a/docs/wiki/1-Mod脚本开发/1-快速入门Mod开发.md +++ b/docs/wiki/1-Mod脚本开发/1-快速入门Mod开发.md @@ -100,8 +100,8 @@ class MyClientSystem(ClientSystem): BOOM!就这么简单! -::: tip :bulb: 为什么需要这些System? -不太理解为什么需要这些System?来阅读进一步的解释吧![为什么是System](./2-为什么是System.md) +:::details :bulb: 为什么需要这些System? + ::: ## 3. 运行你的Mod diff --git a/docs/wiki/1-Mod脚本开发/2-为什么是System.md b/docs/wiki/1-Mod脚本开发/为什么是System.md similarity index 86% rename from docs/wiki/1-Mod脚本开发/2-为什么是System.md rename to docs/wiki/1-Mod脚本开发/为什么是System.md index bfb23b01..5e93d2cf 100644 --- a/docs/wiki/1-Mod脚本开发/2-为什么是System.md +++ b/docs/wiki/1-Mod脚本开发/为什么是System.md @@ -1,6 +1,8 @@ -# 深入理解 System 的概念 +--- +hidden: true +--- -## 🧩 为什么需要两个系统(System)?用餐厅来理解! +### 🧩 为什么需要两个系统(System)?用餐厅来理解! 想象一下游戏就像一家餐厅: - **服务器系统** = 厨房(决定食物实际内容) @@ -14,7 +16,7 @@ graph TB end ``` -## 👨‍🍳 服务器系统:游戏的"厨房" +### 👨‍🍳 服务器系统:游戏的"厨房" - **职责**: 决定游戏中真正发生了什么 - **简单理解**: @@ -23,7 +25,7 @@ graph TB - 控制物品掉落 - 存储真实的游戏数据 -## 👨‍💼 客户端系统:游戏的"前厅" +### 👨‍💼 客户端系统:游戏的"前厅" - **职责**: 让玩家看到并互动 - **简单理解**: @@ -32,7 +34,7 @@ graph TB - 播放爆炸、火焰等特效 - 展示菜单和界面 -## 📮 系统间如何交流:像传纸条一样 +### 📮 系统间如何交流:像传纸条一样 当你在游戏中点击方块,发生了什么? @@ -49,14 +51,14 @@ sequenceDiagram 前厅->>你: 播放挖矿动画和声音,显示物品 ``` -## ⚠️ 为什么不能混在一起? +### ⚠️ 为什么不能混在一起? 就像餐厅里顾客不能随便进厨房一样: - ❌ 客户端不能直接修改游戏数据(否则会作弊) - ❌ 服务器不负责播放声音和动画(它只关心真实数据) -## 🌟 简单例子:击打树木得钻石 +### 🌟 简单例子:击打树木得钻石 ### 简化理解版 1. **你点击树木**(客户端检测到) @@ -65,7 +67,7 @@ sequenceDiagram 4. **服务器通知客户端**:"请在玩家背包里显示一颗新钻石" 5. **客户端更新画面**:你看到钻石出现在背包里 -## 🔑 记住这个简单规则 +### 🔑 记住这个简单规则 想象游戏是一部电影: - **服务器是导演**(决定故事情节) @@ -73,7 +75,7 @@ sequenceDiagram 记住:**服务器决定发生什么,客户端决定如何展示**! -## 💡 初学者提示 +### 💡 初学者提示 如果遇到问题,先问自己: - "这个功能应该由谁负责?是真实游戏规则还是显示效果?" @@ -82,9 +84,9 @@ sequenceDiagram 学会这种思考方式,你的Mod就能正确运行啦! -## :ribbon: 那么总结一下吧! +### :ribbon: 那么总结一下吧! -### 核心架构:客户端-服务器分离 +#### 核心架构:客户端-服务器分离 ```mermaid graph TB @@ -98,9 +100,9 @@ graph TB end ``` -### 双系统模型的必要性 +#### 双系统模型的必要性 -#### 服务器系统 (ServerSystem) +##### 服务器系统 (ServerSystem) - **职责**: 维护游戏的"真实状态" - **具体功能**: - 处理游戏核心逻辑(如战斗计算、物品掉落) @@ -108,7 +110,7 @@ graph TB - 执行世界生成与物理规则 - **拥有数据的最终决定权** -#### 客户端系统 (ClientSystem) +##### 客户端系统 (ClientSystem) - **职责**: 处理玩家的直接体验 - **具体功能**: - 渲染游戏画面与UI界面 @@ -116,7 +118,7 @@ graph TB - 播放音效与粒子效果 - 进行预测性渲染(平滑过渡) -### 系统间通信的关键:事件机制 +#### 系统间通信的关键:事件机制 ```mermaid sequenceDiagram @@ -131,12 +133,12 @@ sequenceDiagram Client->>Player: 显示视觉反馈 ``` -#### 事件驱动设计的优势 +##### 事件驱动设计的优势 - **松耦合**: 系统间无需直接相互调用 - **可扩展**: 多个系统可响应同一事件 - **清晰职责**: 服务端决定结果,客户端呈现效果 -#### 实例:击打方块流程 +##### 实例:击打方块流程 1. **客户端**: 检测到玩家点击方块,发送`BlockUseEvent` 2. **服务端**: - 接收到事件,判断方块是否可被破坏 @@ -145,20 +147,20 @@ sequenceDiagram - 播放方块破坏动画和音效 - 显示掉落物 -### 常见问题与最佳实践 +#### 常见问题与最佳实践 -#### 避免的错误模式 +##### 避免的错误模式 - ❌ 在客户端直接修改游戏状态 - ❌ 在服务端处理UI渲染逻辑 - ❌ 遗漏事件监听导致功能不同步 -#### 最佳实践 +##### 最佳实践 - ✅ 服务端验证所有游戏逻辑(防作弊) - ✅ 合理使用自定义事件进行系统间通信 - ✅ 保持客户端代码专注于视觉体验优化 - ✅ 在事件参数中携带足够的上下文信息 -### 跨系统通信示例 +#### 跨系统通信示例 ```python # 服务端发送自定义事件到客户端 diff --git a/docs/wiki/2-方块/1-基础/blocks-intro.md b/docs/wiki/2-方块/1-基础/blocks-intro.md index 4a3f37fe..3541d139 100644 --- a/docs/wiki/2-方块/1-基础/blocks-intro.md +++ b/docs/wiki/2-方块/1-基础/blocks-intro.md @@ -295,28 +295,22 @@ tile.wiki:compass_block.name=指南针方块 ## 下一步学习 -
- - 学习各类可用[方块组件](/blocks/block-components)打造独特玩法。 -

- 使用[geometry(几何组件)](/blocks/block-components#geometry)为方块添加自定义模型!还可以通过[collision_box(碰撞箱)](/blocks/block-components#collision-box)和[selection_box(选择框)](/blocks/block-components#selection-box)配置物理交互区域。 -
- - 利用[方块状态](/blocks/block-states)和[permutations(状态切换)](/blocks/block-permutations)实现条件触发的组件功能。 -

- 例如为储液罐方块添加多级液面高度功能,并支持多种液体类型。 -
- - 在原版复刻分类中查看多个完整实现案例。 -

- 从简单的[自定义玻璃方块](/blocks/custom-glass-blocks)开始,体验[material_instances(材质实例)](/blocks/block-components#material-instances)的应用! -
-
\ No newline at end of file + \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/boat-entities.md b/docs/wiki/3-实体/2-巧思案例/boat-entities.md index 5950599c..6f1afc17 100644 --- a/docs/wiki/3-实体/2-巧思案例/boat-entities.md +++ b/docs/wiki/3-实体/2-巧思案例/boat-entities.md @@ -1,9 +1,9 @@ --- -title: Creating Boats -category: Tutorials +title: 创建船只 +category: 教程 tags: - - recipe - - intermediate + - 配方 + - 进阶 mentions: - SirLich - Joelant05 @@ -11,25 +11,29 @@ mentions: - StealthyExpertX - TheItsNameless --- -:::warning Requires Format Version 1.16.100 or Lower -The behavior format version now requires 1.16.100 or lower for the `minecraft:behavior.rise_to_liquid_level` and `minecraft:buoyant` methods to work. -If you find a new method that works in the newer format versions, you should consider helping to contribute by updating the wiki. +# 创建船只 + + + +:::warning 需要格式版本1.16.100或更低 + +当前行为格式版本要求1.16.100或更低版本才能使`minecraft:behavior.rise_to_liquid_level`和`minecraft:buoyant`功能生效。 +如果您发现新格式版本中的替代实现方法,欢迎协助更新本Wiki内容。 ::: -## Using Runtime Identifiers +## 使用运行时标识符 -You can read more about runtime identifiers [here](/entities/runtime-identifier). Using runtime identifiers, you can implement most of the boat's hard-coded behaviors. However, your boat won't rotate with you, and it will always face North. +详细内容请参阅[运行时标识符指南](/entities/runtime-identifier)。使用运行时标识符可以实现船只的大部分硬编码行为,但会导致船只无法随玩家转向且始终面向北方。 -## Using Components +## 利用组件系统实现 -Currently, the best way to create a boat entity is by using components. 1.16 introduced new components that we can use to our advantage: `minecraft:behavior.rise_to_liquid_level` and `minecraft:buoyant`. Striders use the first one in vanilla to make them float on lava, but we can repurpose it for water as well. +目前最佳的船只创建方案是通过组件系统实现。1.16版本新增的两个组件可资利用:`minecraft:behavior.rise_to_liquid_level`与`minecraft:buoyant`。官方设计中前者用于岩浆怪的岩浆漂浮特性,我们可以将其移植到水面上使用。 -## 1st method: minecraft:behavior.rise_to_liquid_level +## 第一种方法:minecraft:behavior.rise_to_liquid_level -BP/entities/bar - -```json +::: code-group +```json [BP/entities/bar] { "minecraft:entity": { "format_version": "1.14.0", @@ -40,23 +44,23 @@ Currently, the best way to create a boat entity is by using components. 1.16 int "is_experimental": false }, "components": { - //This is the component that does the magic + // 这是实现效果的核心组件 "minecraft:behavior.rise_to_liquid_level": { "priority": 0, - //This property can adjust how high your boat is above the water + // 控制船体相对于水面的基准高度 "liquid_y_offset": 0.5, - //Positive vertical displacement, in other words, how much the boat will move up + // 正垂直位移量,决定船体抬升幅度 "rise_delta": 0.05, - //Negative vertical displacement, in other words, how much the boat will move down + // 负垂直位移量,决定船体下沉幅度 "sink_delta": 0.05 - //Use rise_delta and sink_delta to simulate waves/bouncing effect + // 通过升降参数可模拟波浪浮动效果 }, - //Sets the boat speed in water + // 设置水上移动速率 "minecraft:underwater_movement": { "value": 5 }, - //This component is important, without it the boat will sink + // 关键组件,移除会导致船体沉没 "minecraft:navigation.walk": { "can_sink": false }, @@ -68,17 +72,17 @@ Currently, the best way to create a boat entity is by using components. 1.16 int "position": [0, 0, 0] } }, - //Add this component if you want your boat to be controlled with WASD + // 添加此组件实现WASD方向控制 "minecraft:input_ground_controlled": {}, "minecraft:health": { "value": 10, "max": 10 }, - //Sets the boat speed on the ground (set this to zero if you don't want your boats to move on the ground) + // 设置地面移动速度(设置为0可禁用地表移动) "minecraft:movement": { "value": 3 }, - //This is to prevent the boat from not stopping whenever a player exits, said the boat + // 防止玩家下船后无法停止移动 "minecraft:movement.basic": {}, "minecraft:collision_box": { "width": 1, @@ -89,12 +93,12 @@ Currently, the best way to create a boat entity is by using components. 1.16 int } } ``` +::: -## 2nd method: minecraft:buoyant +## 第二种方法:minecraft:buoyant - - -```json +::: code-group +```json [] { "minecraft:entity": { "format_version": "1.14.0", @@ -106,27 +110,27 @@ Currently, the best way to create a boat entity is by using components. 1.16 int }, "components": { "minecraft:buoyant": { - //Determines whether gravity should be taken into account (useful with waterfalls) + // 是否受重力影响(处理瀑布场景很有用) "apply_gravity": true, - //Range: 0-1. This controls how high the boat is above the water + // 范围0-1,控制船体默认高度 "base_buoyancy": 1.0, - //A "wave" makes the entity bounce up and down. A big wave simply amplifies this effect. Note: setting simulate_waves to false won't make the effect go away completely. + // 「浪涌」模拟船体上下波动效果(false也不会完全消除效果) "simulate_waves": true, - //How likely a "big" wave will hit this boat + // 产生「大浪」的概率 "big_wave_probability": 0.03, - //How strong the "big" wave will be + // 「大浪」强度系数 "big_wave_speed": 10.0, - //How strong will the boat be dragged down in case this component is removed + // 移除浮力后的下沉阻力 "drag_down_on_buoyancy_removed": 0, - //Blocks this entity can be buoyant in. Only actual liquids are allowed: lava and water + // 支持浮力的液态方块(仅限水和岩浆) "liquid_blocks": ["water"] }, - //Sets the boat speed in water + // 设置水上移动速率 "minecraft:underwater_movement": { "value": 5 }, - //This component is important, without it the boat will sink + // 关键组件,移除会导致船体沉没 "minecraft:navigation.walk": { "can_sink": false }, @@ -138,17 +142,17 @@ Currently, the best way to create a boat entity is by using components. 1.16 int "position": [0, 0, 0] } }, - //Add this component if you want your boat to be controlled with WASD + // 添加此组件实现WASD方向控制 "minecraft:input_ground_controlled": {}, "minecraft:health": { "value": 10, "max": 10 }, - //Sets the boat speed on the ground (set this to zero if you don't want your boats to move on the ground) + // 设置地面移动速度(设置为0可禁用地表移动) "minecraft:movement": { "value": 3 }, - //This is to prevent the boat from not stopping whenever a player exits the boat + // 防止玩家下船后无法停止移动 "minecraft:movement.basic": {}, "minecraft:collision_box": { "width": 1, @@ -159,7 +163,8 @@ Currently, the best way to create a boat entity is by using components. 1.16 int } } ``` +::: -## What method to use? +## 方法选择建议 -Both methods are suitable but have their pros and cons. If you want to disable the bouncing effect, use the first method. If you want more control over it, use the second method. I use the second method for static objects, such as buoys, and the first method for movable entities, such as boats, emulating the vanilla behavior. +两种方式各有优劣。若需禁用波动效果建议采用第一种方式;若需要进行精细调控可选择第二种方法。开发实践中,第二种常用于浮标等静态物体,第一种则更适合船只等运动实体,能更好地还原原版特性。 \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/detecting-other-entities.md b/docs/wiki/3-实体/2-巧思案例/detecting-other-entities.md index b48fa61b..a24d37dd 100644 --- a/docs/wiki/3-实体/2-巧思案例/detecting-other-entities.md +++ b/docs/wiki/3-实体/2-巧思案例/detecting-other-entities.md @@ -1,8 +1,8 @@ --- -title: Detecting Other Entities -category: Tutorials +title: 侦测其他实体 +category: 教程 tags: - - intermediate + - 中级 mentions: - ANightDazingZoroark - SmokeyStack @@ -12,210 +12,189 @@ mentions: - TheItsNameless --- -You might have thought about making your entities fire an event when other entities are nearby. This article details the various known ways to do so. +# 侦测其他实体 + + + +当需要让实体在附近存在其他实体时触发事件,本文将详细介绍多种已知实现方式。 ## minecraft:entity_sensor -This is probably the most basic way to detect other entities. The main issues is it only accepts one entry and testing if the entity is out of range can be very tricky. Because it's an entity component, you can just place into your entity behavior file and edit the Minecraft filters. Here's a demonstration: +这是最基础的侦测方式。主要限制是只能接收单一条目,且检测实体退出范围较困难。作为实体组件,可直接植入实体行为文件并配置Minecraft过滤器: -BP/entities/my_entity.json#components - -```json +::: code-group +```json [BP/entities/my_entity.json#components] "minecraft:entity_sensor": { - "sensor_range": 2.5, //this is for the radius in blocks it will detect other entities in - "relative_range": false, //if true, the sensor range is additive on top of the entity's hitbox size - "require_all": true, //if true, all nearby entities must pass the filter conditions for the event to send - "minimum_count": 1, //minimum amount of entities required for the event to fire. by default, it's 1 - "maximum_count": 4, //maximum amount of entities required for the event to fire. by default it's -1, which means infinity - "event_filters": { //you can put any filter you want here, the one that's being used in this example just detects players + "sensor_range": 2.5, //检测半径(格子数) + "relative_range": false, //若为true,检测范围会叠加实体碰撞箱 + "require_all": true, //若为true,所有邻近实体需通过过滤条件才会触发事件 + "minimum_count": 1, //触发事件的最小实体数量(默认1) + "maximum_count": 4, //触发事件的最大实体数量(默认-1表示无限) + "event_filters": { //自定义过滤器(本例检测玩家) "test": "is_family", "subject": "other", "value": "player" }, - "event": "event:on_player_detected" //the event that fires when all the conditions in event_filters are met + "event": "event:on_player_detected" //条件满足时触发的事件 } ``` +::: -## `/execute` +## `/execute` 命令 -Using the new `/execute` command that has been introduced since 1.19.50, you can execute commands as long as another entity is nearby. +使用1.19.50版本新增的`/execute`命令,可在附近存在实体时执行指令。以下示例使猪在检测到玩家时发出"oink oink"声(可自定义事件): -This example you'll be following will make pigs say "oink oink" upon detecting players, though you can replace those with whatever you want. First of all, copy-paste these BP animations. - -BP/animations/detection_animation.json - -```json +::: code-group +```json [BP/animations/detection_animation.json] { - "format_version": "1.10.0", - "animations": { - "animation.pig.find_player": { - "animation_length": 0.05, - "loop": true, - "timeline": { - "0": [ - "/execute as @s if entity @e[type=player, r=4] run event entity @s wiki:player_detected" - ] - } + "format_version": "1.10.0", + "animations": { + "animation.pig.find_player": { + "animation_length": 0.05, + "loop": true, + "timeline": { + "0": [ + "/execute as @s if entity @e[type=player, r=4] run event entity @s wiki:player_detected" + ] + } + }, + "animation.pig.find_no_player": { + "animation_length": 0.05, + "loop": true, + "timeline": { + "0": [ + "/execute as @s unless entity @e[type=player, r=4] run event entity @s wiki:no_player_detected" + ] + } + } + } +} +``` +::: + +首个动画用于检测实体存在,第二个检测实体离开。可通过`/event`命令添加[虚拟组件](/entities/dummy-components)或更新[实体属性](https://learn.microsoft.com/zh-cn/minecraft/creator/documents/introductiontoentityproperties)。 + +::: code-group +```json [BP/animation_controllers/pig_animation_controllers.json] +{ + "format_version": "1.10.0", + "animation_controllers": { + "controller.animation.pig_find_player": { + "initial_state": "default", + "states": { + "default": { + "animations": ["find_player"], + "transitions": [{ + "detected": "q.is_sheared" + }] }, - "animation.pig.find_no_player": { - "animation_length": 0.05, - "loop": true, - "timeline": { - "0": [ - "/execute as @s unless entity @e[type=player, r=4] run event entity @s wiki:no_player_detected" - ] - } + "detected": { + "animations": ["find_no_player"], + "transitions": [{ + "default": "!q.is_sheared" + }], + "on_entry": ["/say oink oink"] } + } } + } } ``` +::: -The first one is for detecting if the entity is present, and the other for detecting if the entity is not present. The events used in the `/event` part of the `/execute` commands can be used for adding a [dummy component](/entities/dummy-components) or updating an [actor property](https://learn.microsoft.com/en-us/minecraft/creator/documents/introductiontoentityproperties). - -Next of all, copy paste this BP animation controller. This assumes that you set up the `/event` parts of the `/execute` commands to add or remove `minecraft:is_sheared`. - -BP/animation_controllers/pig_animation_controllers.json - -```json -{ - "format_version": "1.10.0", - "animation_controllers": { - "controller.animation.pig_find_player": { - "initial_state": "default", - "states": { - "default": { - "animations": ["find_player"], - "transitions": [ - { - "detected": "q.is_sheared" - } - ] - }, - "detected": { - "animations": ["find_no_player"], - "transitions": [ - { - "default": "!q.is_sheared" - } - ], - "on_entry": ["/say oink oink"] - } - } - } - } -} -``` -Finally, copy-paste this snippet into the behavior file for the pig-like so. Make sure to insert this in `description`. - -BP/entities/my_entity.json#description - -```json +::: code-group +```json [BP/entities/my_entity.json#description] "animations": { - "manage_find_player": "controller.animation.pig_find_player", - "find_player": "animation.pig.find_player", - "find_no_player": "animation.pig.find_no_player" + "manage_find_player": "controller.animation.pig_find_player", + "find_player": "animation.pig.find_player", + "find_no_player": "animation.pig.find_no_player" }, "scripts": { - "animate": [ - "manage_find_player" - ] + "animate": ["manage_find_player"] } ``` +::: -## Molang, BP Animations & Animation Controllers +## Molang、动画与动画控制器 -The `for_each` function and `q.get_nearby_entities` or `q.get_nearby_entities_except_self` can also be used for detecting other entities. They are more effective than using `minecraft:entity_sensor` because they are better at detecting if the entity you want to detect goes away than with `minecraft:entity_sensor`. The only downside is that they're experimental. +使用`for_each`函数配合`q.get_nearby_entities`或`q.get_nearby_entities_except_self`可更高效检测实体(实验性功能),能更好处理实体离开的情况。 -Just like in the previous method we will make pigs say "oink oink" upon detecting players, though you can replace those with whatever you want. First of all, copy-paste this BP animation: - -BP/animations/detection_animation.json - -```json +::: code-group +```json [BP/animations/detection_animation.json] { - "format_version": "1.10.0", - "animations": { - "animation.pig.find_player": { - "animation_length": 0.05, - "loop": true, - "timeline": { - "0": [ - "v.x = 0.0; for_each(t.player, q.get_nearby_entities_except_self(16, 'minecraft:player'), { v.x = v.x + 1; }); return v.x > 0.0;" - ] - } - } - } + "format_version": "1.10.0", + "animations": { + "animation.pig.find_player": { + "animation_length": 0.05, + "loop": true, + "timeline": { + "0": [ + "v.x = 0.0; for_each(t.player, q.get_nearby_entities_except_self(16, 'minecraft:player'), { v.x = v.x + 1; }); return v.x > 0.0;" + ] + } + } + } } ``` +::: -The first parameter that `q.get_nearby_entities_except_self` needs to work is the radius in blocks it will detect other entities in. The other is the identifier of the mob you want to make it detect. +若要检测具备特定Molang属性的实体: -Now that's good and all, but on the off chance, you want to make the pig detect players with some attribute that can be detected with Molang, use this. - -BP/animations/detection_animation.json - -```json +::: code-group +```json [BP/animations/detection_animation.json] { - "format_version": "1.10.0", - "animations": { - "animation.pig.find_player": { - "animation_length": 0.05, - "loop": true, - "timeline": { - "0": [ - "v.x = 0.0; for_each(t.player, q.get_nearby_entities_except_self(2, 'minecraft:player'), { v.x = v.x + (t.player -> q.is_sheared); }); return v.x > 0.0;" - ] - } - } - } + "format_version": "1.10.0", + "animations": { + "animation.pig.find_player": { + "animation_length": 0.05, + "loop": true, + "timeline": { + "0": [ + "v.x = 0.0; for_each(t.player, q.get_nearby_entities_except_self(2, 'minecraft:player'), { v.x = v.x + (t.player -> q.is_sheared); }); return v.x > 0.0;" + ] + } + } + } } ``` +::: -Next of all, copy paste this BP animation controller: - -BP/animation_controllers/pig_animation_controllers.json - -```json +::: code-group +```json [BP/animation_controllers/pig_animation_controllers.json] { - "format_version": "1.10.0", - "animation_controllers": { - "controller.animation.pig_find_player": { - "initial_state": "default", - "states": { - "default": { - "animations": ["find_player"], - "transitions": [ - { - "detected": "v.x > 0" - } - ] - }, - "detected": { - "animations": ["find_player"], - "transitions": [ - { - "default": "v.x <= 0" - } - ], - "on_entry": ["/say oink oink"] - } - } - } - } + "format_version": "1.10.0", + "animation_controllers": { + "controller.animation.pig_find_player": { + "initial_state": "default", + "states": { + "default": { + "animations": ["find_player"], + "transitions": [{ + "detected": "v.x > 0" + }] + }, + "detected": { + "animations": ["find_player"], + "transitions": [{ + "default": "v.x <= 0" + }], + "on_entry": ["/say oink oink"] + } + } + } + } } ``` +::: -Finally, copy-paste this snippet into the behavior file for the pig-like so. Make sure to insert this in `description`. - -BP/entities/my_entity.json#description - -```json +::: code-group +```json [BP/entities/my_entity.json#description] "animations": { - "manage_find_player": "controller.animation.pig_find_player", - "find_player": "animation.pig.find_player" + "manage_find_player": "controller.animation.pig_find_player", + "find_player": "animation.pig.find_player" }, "scripts": { - "animate": [ - "manage_find_player" - ] + "animate": ["manage_find_player"] } ``` +::: \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/disabling-team-damage.md b/docs/wiki/3-实体/2-巧思案例/disabling-team-damage.md index 55769d8d..85cdb3aa 100644 --- a/docs/wiki/3-实体/2-巧思案例/disabling-team-damage.md +++ b/docs/wiki/3-实体/2-巧思案例/disabling-team-damage.md @@ -1,8 +1,8 @@ --- -title: Disabling Team-damage -category: Tutorials +title: 禁用团队伤害 +category: 教程 tags: - - intermediate + - 中级 mentions: - SirLich - solvedDev @@ -12,28 +12,32 @@ mentions: - TCLynx --- -If you wish to disable team damage (so one cannot hurt their teammates), assign a tag with the team name to every teammate (I'm going to use `team1`, `team2`, `team3` and `team4` for this example). -WARNING: This will NOT work on realms, the reason for this is that on realms there is a bug where modified player.json files in the behavior packs do not work, and the gmae just ignores them (This may be fixed in the future but as of 1.20.15 it is not fixed. (This also applies to older version of minecraft as well.)) -Now add this damage sensor component into your `player.json`s `"components": {}`. See comments for explanation. +# 禁用团队伤害 -BP/entities/player.json#components + -```json +若需禁用团队伤害(使玩家无法攻击队友),请为每位玩家分配带有队伍名称的标签(本教程将使用`team1`、`team2`、`team3`和`team4`作为示例)。 +警告:该方法在领域服(Realms)中**不可用**,原因是领域服存在一个漏洞会导致行为包中修改后的player.json文件失效,游戏会直接忽略这些修改(该问题可能在后续版本中修复,但在1.20.15版本中尚未解决。此问题也影响更早的Minecraft版本)。 + +现在将以下伤害感应器组件添加至你的`player.json`文件的`"components": {}`部分。查看注释以获取详细说明。 + +::: code-group +```json [BP/entities/player.json#components] "minecraft:damage_sensor":{ "triggers":[ - { //if you already have a damage sensor, simply copy this object into the "triggers" array + { //若已有伤害感应器组件,只需将此对象复制到"triggers"数组中 "on_damage":{ "filters":{ "any_of":[ { "all_of":[ - { "test":"has_tag", "value":"team1" }, //Does the player have this tag? - { "test":"has_tag", "subject":"other", "value":"team1" } //If so, does the entity they're trying to hurt have this tag? + { "test":"has_tag", "value":"team1" }, //该玩家是否拥有此标签? + { "test":"has_tag", "subject":"other", "value":"team1" } //被攻击实体是否拥有此标签? ] }, { - "all_of":[ - { "test":"has_tag", "value":"team2" }, //repeats for every team + "all_of":[ //以下为重复结构,为每个队伍添加相同配置 + { "test":"has_tag", "value":"team2" }, { "test":"has_tag", "subject":"other", "value":"team2" } ] }, @@ -58,30 +62,26 @@ Now add this damage sensor component into your `player.json`s `"components": {}` ] } }, - "deals_damage":false //if any of these filters evaluate to true in the current attack interaction, the target will not be hurt. + "deals_damage":false //若任意过滤器条件满足,本次攻击将不会造成伤害 } ] } - ``` +::: -### Projectiles +### 抛射物处理 -Due to the primitive filters used by projectile entities, you have to use a completely different method to achieve this. +由于抛射物实体使用的原始滤镜系统,实现此功能需要完全不同的方法。该方案需要以下组件: +- 标签(Tags) +- 周期性检测(Ticking) +- 条件伤害(Hurt on Condition) +- 函数(Functions) -The process uses: -- Tags -- Ticking -- Hurt on Condition -- Functions - -BP/entities/player.json#components - -```json - -//"components" -"minecraft:timer": { //This is for applying teams to a projectile to nearby - "time": [ //untagged projectiles, through an event. +::: code-group +```json [BP/entities/player.json#components] +//"components"部分 +"minecraft:timer": { //用于通过事件给附近未标记的抛射物添加队伍标签 + "time": [ 0.0, 0.1 ], @@ -91,9 +91,9 @@ The process uses: "target": "self" } }, -"minecraft:hurt_on_condition": { //The projectile will be unable to directly deal - "damage_conditions": [ //damage, so instead we'll apply tags to the - { //player, which will trigger this . . . +"minecraft:hurt_on_condition": { //使抛射物无法直接造成伤害 + "damage_conditions": [ //改为通过标签系统触发伤害 + { "filters": { "test": "has_tag", "value": "damage" @@ -103,9 +103,9 @@ The process uses: } ] }, -"minecraft:damage_sensor": { //. . . which in turn, will trigger an event - "triggers": { //to remove this tag, so the damage only - "cause": "projectile", //happens once. +"minecraft:damage_sensor": { //触发事件来移除damage标签 + "triggers": { //确保伤害只生效一次 + "cause": "projectile", "deals_damage": true, "on_damage": { "filters": { @@ -117,15 +117,15 @@ The process uses: } } -//"events" -"wiki:projectile_team": { //The function here will apply tags depending on - "run_command": { //which team tags the player has. +//"events"部分 +"wiki:projectile_team": { //根据玩家队伍标签应用对应的抛射物标签 + "run_command": { "command": [ "function wiki-apply_team" ] } }, -"wiki:stop_damage": { //The event that simply removes the damage tag. +"wiki:stop_damage": { //移除damage标签的事件 "run_command": { "command": [ "tag @s remove damage" @@ -133,23 +133,13 @@ The process uses: } } ``` +::: -BP/functions/wiki-apply_team.mcfunction +::: code-group -``` -execute @s[tag=team1] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team1 -execute @s[tag=team2] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team2 -execute @s[tag=team3] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team3 -execute @s[tag=team4] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team4 - -``` - -BP/entities/arrow.json - -```json - -//"components" -"on_hit": { //On_hit, trigger an event . . . +```json [BP/entities/arrow.json] +//"components"部分 +"on_hit": { //击中时触发事件... "definition_event": { "affect_projectile": true, "event_trigger": { @@ -160,25 +150,35 @@ execute @s[tag=team4] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team4 "remove_on_hit": {} } -//"events" -"wiki:hit": { //. . . which executes a function, applying - "run_command": { //the damage tag to any players of a different team! +//"events"部分 +"wiki:hit": { //...执行函数,为不同队伍玩家添加damage标签 + "run_command": { "command": [ "function wiki-apply_damage" ] } } ``` +::: -BP/functions/wiki-apply_damage.mcfunction +::: code-group +```mcfunction [BP/functions/wiki-apply_team.mcfunction] +execute @s[tag=team1] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team1 +execute @s[tag=team2] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team2 +execute @s[tag=team3] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team3 +execute @s[tag=team4] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team4 ``` +::: + +::: code-group + +```mcfunction [BP/functions/wiki-apply_damage.mcfunction] execute @s[tag=team1] ~ ~ ~ tag @p[rm=0,r=1,tag=!team1] add damage execute @s[tag=team2] ~ ~ ~ tag @p[rm=0,r=1,tag=!team2] add damage execute @s[tag=team3] ~ ~ ~ tag @p[rm=0,r=1,tag=!team3] add damage execute @s[tag=team4] ~ ~ ~ tag @p[rm=0,r=1,tag=!team4] add damage - ``` +::: -If you modify `arrow.json`, take into consideration the component groups. - +> 注意:若修改`arrow.json`文件,请仔细考虑组件分组(component groups)的影响。 \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/dummy-entities.md b/docs/wiki/3-实体/2-巧思案例/dummy-entities.md index ff7db8dc..bdd9e598 100644 --- a/docs/wiki/3-实体/2-巧思案例/dummy-entities.md +++ b/docs/wiki/3-实体/2-巧思案例/dummy-entities.md @@ -1,8 +1,8 @@ --- -title: Dummy Entities -category: Tutorials +title: 虚拟实体 +category: 教程 tags: - - beginner + - 初学者 mentions: - SirLich - Joelant05 @@ -10,26 +10,29 @@ mentions: - aexer0e --- -Dummy entities are invisible entities which are used behind the scenes for game-play purposes. Dummy entities are a very useful tool, and this document will cover some of the ways they are utilized, as well as showing how to set up the resource side of things. +# 虚拟实体 -## Using Dummies + -This is a non-exhaustive list of how dummies can be used: +虚拟实体是游戏场景中不可见的幕后实用实体。本文将介绍这种多功能工具的使用场景,并展示如何配置资源文件。 -- **For data storage**: by adding tags to the entity, we can use it as a "game manager", much like Armor Stands used to be used. -- **As a named entity:** by name-tagging a dummy, and then using `execute` to select for it, you can make command-blocks `/say` with a pretty display name. -- **As a location marker:** you can run `execute` commands located at a dummy to get relative coordinates at a location. -- **As a waypoint:** by making entities which are aggressive to your dummy, you can pathfind entities to any location by placing a dummy there. +## 核心用途 -## Creating Dummies +以下是虚拟实体的部分应用场景: -### Behavior Entity +- **数据存储**:通过给实体添加标签,我们可以将其作为"游戏管理器"使用(类似过去盔甲架的用法)。 +- **命名实体**:通过命名标签标识虚拟实体,配合`execute`指令选中目标,可以用命令块实现带精美显示名称的`/say`命令。 +- **坐标标记**:通过`execute`指令跟踪虚拟实体位置,获取相对坐标系的基准点。 +- **路径向导**:使敌对生物将虚拟实体设为目标,即可将实体路径引导至虚拟实体所在位置。 -You can use whatever behaviors you like, but here is a good template. The important aspects are: no damage, and can't be pushed. +## 创建教程 -BP/entities/dummy.json +### 行为配置 -```json +这里提供一个标准模板(关键特性:免疫伤害且不可推动)。 + +::: code-group +```json [BP/entities/dummy.json] { "format_version": "1.16.0", "minecraft:entity": { @@ -40,11 +43,11 @@ You can use whatever behaviors you like, but here is a good template. The import "is_experimental": false }, "components": { - "minecraft:breathable": { //Optional, allows the entity to breath underwater + "minecraft:breathable": { // 可选,使实体能够在水中呼吸 "breathes_water": true }, "minecraft:physics": { - "has_gravity": false, //Optional, allows the entity to not be affected by gravity or water + "has_gravity": false, // 可选,使实体不受重力和水流影响 "has_collision": false }, "minecraft:custom_hit_test": { @@ -74,13 +77,12 @@ You can use whatever behaviors you like, but here is a good template. The import } ``` -If you want to disable collision at all (so you can place a block at it's position), you can use arrow runtime identifier, however, there can be some side effects. +若要完全禁用碰撞(允许在其位置放置方块),可以使用弓箭runtime ID,但可能存在副作用。 -### Resource Entity +### 资源配置 -RP/entity/dummy.json - -```json +::: code-group +```json [RP/entity/dummy.json] { "format_version": "1.10.0", "minecraft:client_entity": { @@ -100,12 +102,12 @@ If you want to disable collision at all (so you can place a block at it's positi } } ``` +::: -### Geometry +### 模型配置 -RP/models/entity/dummy.json - -```json +::: code-group +```json [RP/models/entity/dummy.json] { "format_version": "1.12.0", "minecraft:geometry": [ @@ -119,12 +121,12 @@ If you want to disable collision at all (so you can place a block at it's positi ] } ``` +::: -### Render Controller (Optional) +### 渲染控制器(可选) -RP/render_controllers/dummy.json - -```json +::: code-group +```json [RP/render_controllers/dummy.json] { "format_version": "1.10.0", "render_controllers": { @@ -140,7 +142,8 @@ If you want to disable collision at all (so you can place a block at it's positi } } ``` +::: -### Texture (Optional) +### 材质贴图(可选) -You can either leave the texture location blank, or open the model in blockbench and create a blank texture. +可以选择留空材质路径,或者使用Blockbench创建空白材质文件。 \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/entity-attack.md b/docs/wiki/3-实体/2-巧思案例/entity-attack.md index 41c6e34d..37fee515 100644 --- a/docs/wiki/3-实体/2-巧思案例/entity-attack.md +++ b/docs/wiki/3-实体/2-巧思案例/entity-attack.md @@ -1,6 +1,6 @@ --- -title: Entity Attacks -category: Tutorials +title: 实体攻击机制 +category: 教程 mentions: - Luthorius - TheDoctor15 @@ -9,43 +9,46 @@ mentions: - epxzzy - ThomasOrs tags: - - intermediate + - 中级 --- -Entity attacks are a complex subject that require many different things to work correctly: +# 实体攻击机制 -- Navigation and movement abilities to move towards its target -- Targeting abilities to pick which entity to attack -- Attack type, such as melee or ranged -- Attack damage and effects + -## Selecting Targets +实体攻击需要多种系统协同工作才能正确运行: -### Movement +- 导航及移动能力以接近目标 +- 目标选择能力以确定攻击对象 +- 攻击类型(如近战或远程) +- 伤害数值及附加效果 -Before a mob can attack, it will need various [movement components](/entities/entity-movement). +## 目标选择 -Before starting to create your entity attacks, you should ensure that your entity can walk around, and navigate its surroundings. +### 移动机制 + +生物发起攻击前需要搭载多种[移动组件](/entities/entity-movement)。 + +在开始配置攻击行为前,请确保实体具备基础移动和路径规划能力。 :::warning -Even if you are making an unmoving entity (like turret), you still need to add navigation component, so your entity can find the entity to shoot. +即使要创建固定式防御单位(如炮塔),仍需要添加导航组件以便自动寻找射击目标。 ::: -### Triggering Hostility +### 激活敌对行为 -There are many ways to trigger hostility. The most common type `nearest_attackable_target`, is shown here. It generally allows you to define which entities this entity is interested in attacking: +触发敌对状态有多种方式。以下为最常用的`nearest_attackable_target`组件示例,主要用于定义实体的主要攻击目标类型: - - -```json +::: code-group +```json [原始CodeHeader的值] "minecraft:behavior.nearest_attackable_target": { - "must_see": true, //If true, potential target must be in mob's line of sight - "reselect_targets": true, //Allows mob to select new target, if one is closer than current - "within_radius": 25.0, //Radius that potential target must be withing - "must_see_forget_duration": 17.0, //If "must_see" = true, time before forgetting target + "must_see": true, //如果为true,目标必须处于实体视线内 + "reselect_targets": true, //允许切换更近的目标 + "within_radius": 25.0, //有效搜索半径 + "must_see_forget_duration": 17.0, //目标消失视野后的记忆时间 "entity_types": [ { - "filters": { //Entities to attack + "filters": { //有效攻击目标筛选 "test": "is_family", "subject": "other", "value": "player" @@ -55,25 +58,25 @@ There are many ways to trigger hostility. The most common type `nearest_attackab ] } ``` +::: -For more fine control, you may also consider using one of the following components: +如需更精细控制,可选用以下组件: -| Component | Note | -| -------------------------------------------------------- | ------------------------------------------------------------ | -| minecraft:behavior.nearest_attackable_target | Targets entity meeting the given requirements | -| minecraft:behavior.nearest_prioritized_attackable_target | Allows for "priority": [integer] to be set after each filter | -| minecraft:behavior.defend_trusted_target | Targets entity that hurts any entities specified in filters | +| 组件 | 说明 | +| ---------------------------------------------------- | ------------------------------------------------------------ | +| minecraft:behavior.nearest_attackable_target | 定位符合筛选条件的实体 | +| minecraft:behavior.nearest_prioritized_attackable_target | 可通过filter后设置"priority": [整数]定义优先级 | +| minecraft:behavior.defend_trusted_target | 防御指定类型的友方单位 | -But there is also one more - `minecraft:lookat` +另有特殊组件`minecraft:lookat`: -This last component is slightly different to the other three, as it is for detecting and targeting entities that attempt eye contact. It is structured like so: +该组件与其他三种不同,用于检测与实体发生视线交互的目标。配置示例: -BP/entities/enderman.json - -```json +::: code-group +```json [BP/entities/enderman.json] "minecraft:lookat": { "search_radius": 64.0, - "set_target": true, //Becomes a valid target if true + "set_target": true, //标记为有效目标 "look_cooldown": 5.0, "filters": { "all_of": [ @@ -87,24 +90,24 @@ This last component is slightly different to the other three, as it is for detec "domain": "head", "subject": "other", "operator": "not", - "value": "carved_pumpkin" //All players not with carved_pumpkin equipped on head + "value": "carved_pumpkin" //未装备雕刻南瓜的玩家 } ] } } ``` - -### Target selecting - -:::tip -This section shows you how to configure the "Targeting" components, explained above. ::: -Mobs find targets by using [filters](https://bedrock.dev/docs/stable/Entities#Filters) can be used to determine which entities are a valid target, through `test`, `subject`, `operator`, and `value`. +### 目标筛选机制 - +:::tip +本节说明如何配置上述「目标定位」组件。 +::: -```json +实体通过[筛选器](https://bedrock.dev/docs/stable/Entities#Filters)判定有效目标,使用`test`、`subject`、`operator`和`value`参数进行组合判断。 + +::: code-group +```json [原始CodeHeader的值] "entity_types":[ { "filters":{ @@ -121,7 +124,7 @@ Mobs find targets by using [filters](https://bedrock.dev/docs/stable/Entities#Fi "operator":"==", "value":"iron_golem" } - //anything that is equal to either" snow_golem" or "iron_golem" + //雪傀儡或铁傀儡 ] }, "max_dist":24 @@ -142,34 +145,34 @@ Mobs find targets by using [filters](https://bedrock.dev/docs/stable/Entities#Fi "operator":"=!", "value":"turtle_helmet" } - //anything equal to player AND not wearing "turtle_helmet" on head + //未装备海龟盔甲的玩家 ] }, "max_dist":24 } ] ``` +::: -This would only target `snow_golem`s, `iron_golem`s, and `player`s that are **not** wearing `turtle_helmet`s. +该配置将锁定雪傀儡、铁傀儡及未佩戴海龟头盔的玩家。 -## Types of Attack +## 攻击类型 -Here are the available attacks: +可用攻击方式列表: -| Component | Note | +| 组件 | 说明 | | ---------------------------------------------------- | -------------------------------------------------------- | -| [minecraft:behavior.melee_attack](#melee) | Deals damage to a single target | -| [minecraft:behavior.ranged_attack](#ranged) | Fires a projectile towards a target | -| [minecraft:area_attack](#area) | Effectively melee attacks on anything withing range | -| [minecraft:behavior.knockback_roar](#knockback-roar) | Similar to minecraft:area_attack, but much more flexible | +| [minecraft:behavior.melee_attack](#近战攻击) | 单体近战攻击 | +| [minecraft:behavior.ranged_attack](#远程攻击) | 发射弹射物 | +| [minecraft:area_attack](#范围攻击) | 范围内全体打击 | +| [minecraft:behavior.knockback_roar](#击退怒吼) | 高自定义度的冲击波攻击 | -### Melee +### 近战攻击 -Melee attacks are the most common type of attack, they cause knockback, and have a 100% success rate at accuracy. +最常见的攻击类型,带有击退效果且必定命中。 - - -```json +::: code-group +```json [原始CodeHeader的值] "wiki:melee_attack": { "minecraft:attack": { "damage": 3, @@ -178,81 +181,81 @@ Melee attacks are the most common type of attack, they cause knockback, and have }, "minecraft:behavior.melee_attack": { "priority": 3, - "melee_fov": 90.0, //The allowable FOV the actor will use to determine if it can make a valid melee attack + "melee_fov": 90.0, //实体发动近战攻击时的有效视野角度 "speed_multiplier": 1, "track_target": false, "require_complete_path": true } } ``` +::: -Set the damage, choose a mob effect, and change some additional properties. +可配置伤害数值、状态效果及攻击参数。 -The value defined in components stating integers of damage can simply be a constant, or a string containing 2 numbers, for a range of possible values. +伤害数值支持固定值或区间范围: -`"damage": 3` would result in 3 each time +- `"damage": 3`:固定造成3点伤害 +- `"damage": [2, 6]`:随机造成2-6点伤害 -`"damage": [ 2, 6 ]` would result in any integer between 2 and 6 +状态效果支持列表: -Both the mob effect and duration timer are optional, but when they are used, the available effects are as following: - -| Effect Name | +| 效果列表 | | --------------- | -| speed | -| slowness | -| haste | -| mining_fatigue | -| strength | -| instant_health | -| instant_damage | -| jump_boost | -| nausea | -| regeneration | -| resistance | -| fire_resistance | -| water_breathing | -| invisibility | -| blindness | -| night_vision | -| hunger | -| weakness | -| poison | -| wither | -| health_boost | -| absorption | -| saturation | -| levitation | -| fatal_poison | -| slow_falling | -| conduit_power | -| bad_omen | -| village_hero | -| darkness | +| 速度 | +| 缓慢 | +| 急迫 | +| 挖掘疲劳 | +| 力量 | +| 瞬间治疗 | +| 瞬间伤害 | +| 跳跃提升 | +| 反胃 | +| 生命恢复 | +| 抗性提升 | +| 防火 | +| 水下呼吸 | +| 隐身 | +| 失明 | +| 夜视 | +| 饥饿 | +| 虚弱 | +| 中毒 | +| 凋零 | +| 生命提升 | +| 伤害吸收 | +| 饱和 | +| 飘浮 | +| 剧毒 | +| 缓降 | +| 潮涌能量 | +| 不祥之兆 | +| 村庄英雄 | +| 黑暗 | -### Ranged +### 远程攻击 -Fires specified [projectiles](/documentation/projectiles) towards target at set intervals. +按设定间隔发射指定[弹射物](/documentation/projectiles)。 - - -```json +::: code-group +```json [原始CodeHeader的值] "wiki:ranged_attack": { "minecraft:behavior.ranged_attack": { "priority": 2, - "ranged_fov": 90.0, //The allowable FOV the actor will use to determine if it can make a valid ranged attack - "attack_interval_min": 1.0, - "attack_interval_max": 3.0, - "attack_radius": 15.0 + "ranged_fov": 90.0, //实体发动远程攻击时的有效视野角度 + "attack_interval_min": 1.0, //最小攻击间隔 + "attack_interval_max": 3.0, //最大攻击间隔 + "attack_radius": 15.0 //攻击范围 }, "minecraft:shooter": { - "def": "wiki:projectile" + "def": "wiki:projectile" //自定义弹射物定义 } } ``` +::: -List of vanilla projectiles: +原版弹射物类型: -| Vanilla Projectiles | +| 原版弹射物 | | -------------------------------- | | minecraft:arrow | | minecraft:dragon_fireball | @@ -271,33 +274,32 @@ List of vanilla projectiles: | minecraft:wither_skull_dangerous | | minecraft:xp_bottle | -Only one item has an effect on an entity's ranged attacks. Crossbows. If one is equipped, it is first required for it to be "charged" before the entity can fire anything. Regardless of the projectile stated in `minecraft:shooter`, the item to charge the crossbow with should always be `minecraft:arrow`. +弩类武器需先装填后发射: - - -```json +::: code-group +```json [原始CodeHeader的值] "minecraft:behavior.charge_held_item": { "priority": 2, "items": [ - "minecraft:arrow" + "minecraft:arrow" //弩的弹药类型固定为箭 ] } ``` +::: -Once `minecraft:behavior.charge_held_item` has been achieved, the entity will be able to execute the process of `minecraft:behavior.ranged_attack`, and will then need to charge again. +完成装填后方可触发`minecraft:behavior.ranged_attack`。 -### Area +### 范围攻击 -These attacks damage all entities within a set radius. It is different to both ranged and melee in that this component doesn’t actually require a target. Regardless of the entities behaviour, _all_ entities will be affected by this. It appears to be similar to melee attacks, as it deals knockback in a similar manner, though dealing damage at a constant rate. +对范围内的所有实体造成伤害。与常规攻击不同,无需特定目标即可触发。 - - -```json +::: code-group +```json [原始CodeHeader的值] "minecraft:area_attack" : { - "damage_range": 1, //distance in blocks - "damage_per_tick": 2, - "cause": "contact", - "entity_filter": { + "damage_range": 1, //伤害作用范围(方块) + "damage_per_tick": 2, //每tick伤害量 + "cause": "contact", //伤害来源类型 + "entity_filter": { //有效目标筛选 "any_of": [ { "test": "is_family", @@ -313,58 +315,58 @@ These attacks damage all entities within a set radius. It is different to both r } } ``` +::: -[Entity damage sources](https://bedrock.dev/docs/stable/Addons#Entity%20Damage%20Source). It is important to take these into consideration, as certain items in vanilla can protect from some, like armour enchantments, and you can also make mobs immune to specific sources using `minecraft:damage_sensor`. +需参考[实体伤害源类型](https://bedrock.dev/docs/stable/Addons#Entity%20Damage%20Source)进行配置,注意部分原版装备可减免特定类型伤害。 -### Knockback Roar +### 击退怒吼 -Many similarities between this and `minecraft:area_attack`, this component though having much more flexibility. +高灵活性范围攻击,可产生冲击波效果。 - - -```json +::: code-group +```json [原始CodeHeader的值] "wiki:roar_attack": { "minecraft:behavior.knockback_roar":{ "priority":2, - "duration":0.7, - "attack_time":0.2, - "knockback_damage":1, - "knockback_horizontal_strength":1, - "knockback_vertical_strength":1, - "knockback_range":5, - "knockback_filters":{ + "duration":0.7, //技能总时长 + "attack_time":0.2, //实际造成伤害时间点 + "knockback_damage":1, //击退伤害 + "knockback_horizontal_strength":1, //水平击退力度 + "knockback_vertical_strength":1, //垂直击退力度 + "knockback_range":5, //作用范围 + "knockback_filters":{ //击退目标筛选 "test":"is_family", "subject":"other", "operator":"==", "value":"player" }, - "damage_filters":{ + "damage_filters":{ //伤害目标筛选 "test":"is_family", "subject":"other", "operator":"==", "value":"player" }, - "on_roar_end":{ + "on_roar_end":{ //技能结束触发事件 "event":"wiki:other_event" }, - "cooldown_time":10 + "cooldown_time":10 //冷却时间 } } ``` +::: -This is more like a shockwave of damage. Extremely versatile in uses. Produces a particle effect, which can be disabled by adding a modified version of `knockback_roar.json` to a resource pack's particles folder. +若需要隐藏默认粒子效果,可在资源包中覆盖相关粒子文件。 -## More on Attacks +## 进阶攻击配置 -Entity Attacks don't have to be as simple as Mob being hostile towards X target, doing X attack, dealing X damage. +攻击行为可通过事件系统进行更高级的交互设计。 -### Difficulty Dependant Attacks +### 难度分级攻击 -Express components and values to use for each difficulty. +不同游戏难度配置不同攻击参数: -BP/entities/bee.json - -```json +::: code-group +```json [BP/entities/bee.json] "easy_attack": { "minecraft:attack": { "damage": 2 @@ -385,18 +387,23 @@ Express components and values to use for each difficulty. } } ``` +::: -### Switching Modes +### 模式切换系统 -You can use events to make your mob only attack under specific circumstances, or swap between the different types of attack. This can be achieved through simple usage of [events](/entities/entity-events) and component groups. Two prime examples being `minecraft:environment_sensor` and `minecraft:target_nearby_sensor`. The two are pretty similar in regards of structure, difference being that one is for sensing environments and the other for testing for target distance. +通过[事件系统](/entities/entity-events)和组件组实现攻击模式切换。常用传感器组件: -#### Attacks +| 传感器类型 | 说明 | +| ---------------------- | ----------------------- | +| minecraft:environment_sensor | 环境条件监测 | +| minecraft:target_nearby_sensor | 目标距离监测 | -Component groups are required to define the different modes of attack, such as: +#### 组件组示例 - +远程攻击配置组: -```json +::: code-group +```json [原始CodeHeader的值] "wiki:ranged_components": { "minecraft:shooter": { "def": "wiki:projectile" @@ -410,10 +417,12 @@ Component groups are required to define the different modes of attack, such as: } } ``` +::: - +近战攻击配置组: -```json +::: code-group +```json [原始CodeHeader的值] "wiki:melee_components": { "minecraft:attack": { "damage": 6 @@ -423,85 +432,41 @@ Component groups are required to define the different modes of attack, such as: } } ``` +::: -Those are examples of your attack modes, but they are not the only ones you can use. `wiki:ranged_components` and `wiki:melee_components` are generic names for the components within them, they can have any name, but it's what's nested inside them that counts. +#### 事件触发器 -#### Events +距离传感器示例: -These component groups won't actually do anything by themselves. Another component group is required, and some events to add/remove the attack modes. - - - -```json -"wiki:melee_swap": { //When triggered, adds component group for ranged and removes melee component group - "remove": { - "component_groups": [ - "wiki:ranged_components" - ] - }, - "add": { - "component_groups": [ - "wiki:melee_components" - ] - } -} -``` - - - -```json -"wiki:ranged_swap": { //When triggered, adds component group for melee and removes ranged component group - "remove": { - "component_groups": [ - "wiki:melee_components" - ] - }, - "add": { - "component_groups": [ - "wiki:ranged_components" - ] - } -} -``` - -The events are effectively for just turning attack modes on and off, by adding and removing different component groups. - -#### Sensors - -To trigger the events, another component group is used. Sensors are components that can trigger events when certain conditions are fulfilled. Here are 2 examples of different sensors: - -- For sensing the distance between the mob and target - - - -```json +::: code-group +```json [原始CodeHeader的值] "wiki:switcher_range": { "minecraft:target_nearby_sensor": { "inside_range": 4.0, "outside_range": 5.0, "must_see": true, - "on_inside_range": { //When target is within 4 blocks range, trigger "wiki:melee_swap" event + "on_inside_range": { //4格内切换近战 "event": "wiki:melee_swap", "target": "self" }, - "on_outside_range": { //When target is beyond 5 blocks range, trigger "wiki:ranged_swap" event + "on_outside_range": { //5格外切换远程 "event": "wiki:ranged_swap", "target": "self" } } } ``` +::: -- For sensing certain features of the environment of which the mob is exposed to +环境传感器示例: - - -```json +::: code-group +```json [原始CodeHeader的值] "wiki:switcher_environment": { "minecraft:environment_sensor": { "triggers": [ - { - "filters": { //When underwater, trigger "wiki:melee_swap" event + { //水下转为近战 + "filters": { "test": "is_underwater", "subject": "self", "operator": "==", @@ -509,8 +474,8 @@ To trigger the events, another component group is used. Sensors are components t }, "event": "wiki:melee_swap" }, - { - "filters": { //When not underwater, trigger "wiki:ranged_swap" event + { //陆地转为远程 + "filters": { "test": "is_underwater", "subject": "self", "operator": "==", @@ -522,49 +487,39 @@ To trigger the events, another component group is used. Sensors are components t } } ``` - -This uses `Filters`, similar to how the [target is initially selected](#target-selecting). - -:::tip -You aren't limited to just 2 attack types, you can have as many as you want! Just make sure to have the event's and sensors to compensate for them. ::: -## Visual Animations +:::tip +攻击类型切换不限于两种模式,可根据需求扩展更多。 +::: -Attacks and animations go hand in hand. Within resource packs, the following 3 directories are required: +## 动作表现配置 -- animations (entityname.animation.json) -- animation_controllers (entityname.animation_controller.json) -- entity (entityname.json) +攻击需配合动画系统实现完整表现。 -Or as long as you know the names of vanilla animations and animation controllers, you can define them in the latter directory and folder. +### 动画资源 -### Animations +建议使用[Blockbench](/guide/blockbench)制作动画,需在资源包中包含: -Animations are self explanatory. The files themselves contain all specific animations for the given entity. The recommended way to make animations is by using [blockbench](/guide/blockbench). +- animations文件夹(实体动画定义) +- animation_controllers文件夹(动画控制器) +- entity文件夹(实体定义) -Though it is possible to create them in a simple text editor. - -| Vanilla Attack Animations | +| 原版攻击动画 | | -------------------------------------------- | | "animation.zombie.attack_bare_hand" | | "animation.skeleton.attack.v1.0" | | "animation.humanoid.bow_and_arrow.v1.0" | | "animation.humanoid.damage_nearby_mobs.v1.0" | -A few examples of Animations. Locate /vanilla_resource_pack/animations for all of them. +### 动画控制器 -### Animation Controllers +控制动画的触发逻辑: -List of states that trigger animations. - -| Vanilla Attack Animation Controllers | +| 原版动画控制器 | | ---------------------------------------------- | | "controller.animation.zombie.attack_bare_hand" | | "controller.animation.skeleton.attack" | | "controller.animation.humanoid.bow_and_arrow" | -| "controller.animation.humanoid.attack" | -A few examples of Animation Controllers. Locate /vanilla_resource_pack/animation_controllers for all of them - -More information on animations can be found [here](https://bedrock.dev/docs/stable/Animations). +更多动画系统细节请参考[官方文档](https://bedrock.dev/docs/stable/Animations)。 \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/entity-holds-item.md b/docs/wiki/3-实体/2-巧思案例/entity-holds-item.md index bf114f75..b113add8 100644 --- a/docs/wiki/3-实体/2-巧思案例/entity-holds-item.md +++ b/docs/wiki/3-实体/2-巧思案例/entity-holds-item.md @@ -1,8 +1,8 @@ --- -title: Entity Holds Item -category: Tutorials +title: 实体手持物品 +category: 教程 tags: - - intermediate + - 中等难度 mentions: - pieterdefour - SirLich @@ -15,46 +15,49 @@ mentions: - 7dev7urandom --- +# 实体手持物品 + + + ::: tip -This tutorial assumes you have a basic understanding of entities, loot tables, and Blockbench. +本教程假设您已对实体、战利品表和Blockbench有基本了解。 ::: -In this tutorial, you will learn to have an entity spawn with an item in its hand. I'll be using a custom `mandalorian_armorer` entity and a custom `hammer` item for the examples. +在本教程中,您将学习如何让实体生成时手持物品。示例中将使用自定义实体 `mandalorian_armorer` 和自定义物品 `hammer`。 -## Model +## 模型 -First of all, you'll need to have a model in Blockbench that has a map called `rightArm`. Within this map, there needs to be a submap called 'rightItem'. -Now set the position of the pivot point of this submap, so it sits in the place you want the entity to hold the item at. +首先需要在Blockbench中创建包含名为 `rightArm` 骨架的模型。该骨架内必须包含名为 `rightItem` 的子骨架。 +将该子骨架的枢轴点定位至您期望实体手持物品的位置。 ![](/assets/images/tutorials/entity-holds-item/blockbench.png) -## Behavior Pack-side +## 行为包配置 -Now you'll need to add a `minecraft:equipment` component in the component list for your entity and add a loot table with the desired item. +接下来需在实体的组件列表中添加 `minecraft:equipment` 组件,并配置包含目标物品的战利品表。 -In our example it will look like this: +示例配置如下: -BP/entity/mandolorian.json#components - -```json +::: code-group +```json [BP/entity/mandolorian.json#components] "minecraft:equipment": { "table": "loot_tables/entities/gear/mandolorian.json" } ``` - -## Loot Table - -Finally, add the loot table for your entity. It needs to be in `loot_tables/entities/.json` in the behavior pack. In our case, it's called `mandolorian.json`. - -:::warning -This isn't the same loot table as what it drops on death. So make sure it has a different name. ::: -To have the entity always spawn with the same item, add the following loot table: +## 战利品表配置 -BP/loot_tables/entities/gear/mandolorian.json +最后在行为包的 `loot_tables/entities/<你的战利品表名称>.json` 路径下添加对应战利品表。本示例中文件名为 `mandolorian.json`。 -```json +:::warning +此战利品表与生物死亡掉落表不同,请确保使用不同命名。 +::: + +要让实体始终持握特定物品,按照以下格式配置战利品表: + +::: code-group +```json [BP/loot_tables/entities/gear/mandolorian.json] { "pools": [ { @@ -70,7 +73,8 @@ To have the entity always spawn with the same item, add the following loot table ] } ``` +::: -If everything went well, you'd have something looking like this: +成功配置后,效果应如下图所示: -![](/assets/images/tutorials/entity-holds-item/finished_result.png) +![](/assets/images/tutorials/entity-holds-item/finished_result.png) \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/entity-movement.md b/docs/wiki/3-实体/2-巧思案例/entity-movement.md index 0902a676..bf4afe6d 100644 --- a/docs/wiki/3-实体/2-巧思案例/entity-movement.md +++ b/docs/wiki/3-实体/2-巧思案例/entity-movement.md @@ -1,6 +1,6 @@ --- -title: Entity Movement -category: Tutorials +title: 实体移动 +category: 教程 mentions: - SirLich - sermah @@ -8,138 +8,126 @@ mentions: - TheDoctor15 --- -In Minecraft, entities have the ability to move through the world, either by walking, swimming or flying. To get these behaviors, your entity will generally need quite a few behaviors, broken out into various types. +# 实体移动 -As you read this tutorial, keep in mind that your entity will need at least: + -- [A component that sets the entities movement speed.](#movement-speed) -- [A component to set how the entity will move (walking, flying, etc)](#movement-type) -- [A component to set the entities navigation abilities, so it can generate paths.](#navigation-abilities) -- [A component that sets where/when the entity should move (AI Goals).](#ai) +在Minecraft中,实体可以通过行走、游泳或飞行的方式在世界中移动。要为实体赋予这些行为能力,通常需要配置多种不同类型的组件。 + +阅读本教程时请注意,您的实体至少需要以下组件: + +- [设置移动速度的基础组件](#移动速度) +- [定义移动方式的组件(行走/飞行等)](#移动方式) +- [设定导航能力的组件,用于生成移动路径](#导航能力) +- [控制实体移动时机和方向的AI组件](#人工智能) :::tip -The best way to create a moving entity is by picking a similar entity from the vanilla behavior pack, and copying the components into your entity. +创建移动实体的最佳方式是从原版行为包中找到类似实体,将其组件配置复制到您的实体中。 -For example entities like Phantom, or Ghast, or Parrot are all flying entities, but have very different in-game behavior! Use the closest-matching entity as a template. +例如像夜魅(Phantom)、恶魂(Ghast)或鹦鹉这类飞行实体,虽然具有完全不同的游戏行为,但它们都是通过基本相似的组件实现移动功能的。建议选择与目标实体最接近的原版生物作为模板。 ::: -## Movement Speed +## 移动速度 -The first thing your entity needs is a speed component. This sets how quickly your entity will move through the world. +首先需要为实体配置移动速度组件,这些参数决定了实体在世界中的移动快慢。 -| Component | Note | -| ---------------------------------------------------------------------------------------------------------------- | -------------------------------- | -| [minecraft:movement](/entities/vanilla-usage-components#movement) | Set movement speed (required) | -| [minecraft:underwater_movement](/entities/vanilla-usage-components#underwater-movement) | Set movement speed in the water. | -| [minecraft:flying_speed](/entities/vanilla-usage-components#flying-speed) | Set the speed in the air. | +| 组件 | 说明 | +| ---------------------------------------------------------------------------------------------------- | ----------------------------- | +| [minecraft:movement](/entities/vanilla-usage-components#movement) | 设置基础移动速度(必需组件) | +| [minecraft:underwater_movement](/entities/vanilla-usage-components#underwater-movement) | 设置水下移动速度 | +| [minecraft:flying_speed](/entities/vanilla-usage-components#flying-speed) | 设置空中飞行速度 | -You should always include `minecraft:movement`. Add the other two as needed. +所有实体必须包含`minecraft:movement`组件。其他两个组件按需添加。 -All vanilla "swimming" entities like Dolphin include `underwater_movement`. Only some flying entities have `flying_speed`. It is not known why this is the case. +原版水中生物(如海豚)都包含`underwater_movement`组件。部分飞行生物具有`flying_speed`组件(具体配置因生物而异)。 -## Movement Type +## 移动方式 -Your entity will also need a movement type. Movement types set hard-coded behavior for _how_ your entity will move through the world. +实体需要配置移动类型组件来定义其基础运动模式。注意每个实体只能选择一种移动类型,请根据实际需求选择最匹配的类型。 -You may only include one movement type in your entity. Select the component that most closely matches your needs. Generally `basic`, `amphibious` and `fly` are good ones to use. +| 组件 | 说明 | +| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| [minecraft:movement.amphibious](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.amphibious) | 两栖移动模式,允许同时在水中游泳和陆地行走 | +| [minecraft:movement.basic](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.basic) | 基础移动模式 | +| [minecraft:movement.fly](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.fly) | 飞行移动模式 | +| [minecraft:movement.generic](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.generic) | 通用移动模式,支持多种移动能力 | +| [minecraft:movement.hover](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.hover) | 悬停移动模式 | +| [minecraft:movement.jump](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.jump) | 跳跃移动模式,可配置跳跃间隔时间 | +| [minecraft:movement.skip](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.skip) | 蹦跳移动模式 | +| [minecraft:movement.sway](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.sway) | 摆动移动模式,模拟水生生物游动姿态 | -| Component | Note | -| --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -| [minecraft:movement.amphibious](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.amphibious) | This move control allows the mob to swim in the water and walk on land. | -| [minecraft:movement.basic](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.basic) | This component accents the movement of an entity. | -| [minecraft:movement.fly](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.fly) | This move control causes the mob to fly. | -| [minecraft:movement.generic](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.generic) | This move control allows a mob to fly, swim, climb, etc. | -| [minecraft:movement.hover](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.hover) | This move control causes the mob to hover. | -| [minecraft:movement.jump](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.jump) | Move control causes the mob to jump as it moves with a specified delay between jumps. | -| [minecraft:movement.skip](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.skip) | This move control causes the mob to hop as it moves. | -| [minecraft:movement.sway](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.sway) | This move control causes the mob to sway side to side, giving the impression it is swimming. | +## 移动修正 -## Movement Modifiers +下列组件可为实体移动提供额外的物理效果调整,常规情况下不是必须组件,但需要了解其功能。 -Movement modifiers provide additional information about how your entity will move through the world. These components are not required for normal entities, but you should be aware of them. +| 组件 | 说明 | +| ---------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| [minecraft:water_movement](https://bedrock.dev/docs/stable/Entities#minecraft%3Awater_movement) | 设置实体在水中的摩擦力 | +| [minecraft:rail_movement](https://bedrock.dev/docs/stable/Entities#minecraft%3Arail_movement) | 使实体能够沿轨道移动(限轨道移动) | +| [minecraft:friction_modifier](https://bedrock.dev/docs/stable/Entities#minecraft%3Afriction_modifier) | 设置实体陆地移动摩擦力 | -| Component | Note | -| ----------------------------------------------------------------------------------------------------- | -------------------------------------------------- | -| [minecraft:water_movement](https://bedrock.dev/docs/stable/Entities#minecraft%3Awater_movement) | Sets the friction the entity experiences in water. | -| [minecraft:rail_movement](https://bedrock.dev/docs/stable/Entities#minecraft%3Arail_movement) | Sets that the entity can move on rails (only). | -| [minecraft:friction_modifier](https://bedrock.dev/docs/stable/Entities#minecraft%3Afriction_modifier) | Sets the friction the entity experiences on land. | +## 导航能力 -## Navigation - -The next thing your entity needs is a navigation component. Navigation components have quite a few fields, like whether the entity can open doors or avoid sunlight. How you set these fields is generally more important than the navigation component you pick! - -The reason there are so many navigation components is that each one gives a slightly different hard-coded behavior. Pick the navigation component whose name/description best matches the kind of navigation your entity will be doing. - -You can only have one navigation component at any given time. +导航组件定义了路径生成规则。每个导航组件都有独特的硬编码逻辑,需要根据实体的具体需求选择最匹配的类型。 :::tip -This component is very important. You should check vanilla examples for inspiration on what fields and values to use. +此组件对实体行为影响重大,建议参考原版生物的配置获取启发 ::: -| Component | Note | -| ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -| [minecraft:navigation.climb](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.climb) | Allows this entity to generate paths that include vertical walls like the vanilla Spiders do. | -| [minecraft:navigation.float](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.float) | Allows this entity to generate paths by flying around the air like the regular Ghast. | -| [minecraft:navigation.generic](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.generic) | Allows this entity to generate paths by walking, swimming, flying and climbing around, and jumping up and down a block. | -| [minecraft:navigation.fly](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.fly) | Allows this entity to generate paths in the air as the vanilla Parrots do. | -| [minecraft:navigation.swim](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.swim) | Allows this entity to generate paths that include water. | -| [minecraft:navigation.walk](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.walk) | Allows this entity to generate paths by walking around and jumping up and down a block like regular mobs. | +| 组件 | 说明 | +| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| [minecraft:navigation.climb](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.climb) | 允许生成墙面路径(类似蜘蛛的爬墙能力) | +| [minecraft:navigation.float](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.float) | 允许空中漂浮移动(类似恶魂的移动方式) | +| [minecraft:navigation.generic](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.generic) | 通用导航模式,支持行走、游泳、飞行和攀爬等多种路径生成 | +| [minecraft:navigation.fly](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.fly) | 空中飞行导航(类似鹦鹉的飞行路径计算) | +| [minecraft:navigation.swim](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.swim) | 水体环境导航 | +| [minecraft:navigation.walk](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.walk) | 标准行走导航(类似普通生物的移动逻辑) | -## Navigation Abilities +## 增强组件 -On top of the movement and the navigation component, there exist many additional components to augment the abilities of your entity as they move through the world. +以下是增强实体移动能力的可选组件: -| Component | Note | -| ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -| [minecraft:annotation.break_door](https://bedrock.dev/docs/stable/Entities#minecraft%3Aannotation.break_door) | Allows entity to break doors. It must also be turned on in the navigation component. | -| [minecraft:annotation.open_door](https://bedrock.dev/docs/stable/Entities#minecraft%3Aannotation.open_door) | Allows entity to open doors. It must also be turned on in the navigation component. | -| [minecraft:buoyant](https://bedrock.dev/docs/stable/Entities#minecraft%3Abuoyant) | Specifies which liquids the entity can float in. | -| [minecraft:can_climb](https://bedrock.dev/docs/stable/Entities#minecraft%3Acan_climb) | Allows this entity to climb up ladders. | -| [minecraft:can_fly](https://bedrock.dev/docs/stable/Entities#minecraft%3Acan_fly) | Marks the entity as being able to fly. The pathfinder won't be restricted to paths where a solid block is required underneath it. | -| [minecraft:can_power_jump](https://bedrock.dev/docs/stable/Entities#minecraft%3Acan_power_jump) | Allows the entity to power jump like the horse does in vanilla. | -| [minecraft:floats_in_liquid](https://bedrock.dev/docs/stable/Entities#minecraft%3Afloats_in_liquid) | Sets that this entity can float in liquid blocks. | -| [minecraft:jump.dynamic](https://bedrock.dev/docs/stable/Entities#minecraft%3Ajump.dynamic) | Defines a dynamic type jump control that will change jump properties based on the speed modifier of the mob. | -| [minecraft:jump.static](https://bedrock.dev/docs/stable/Entities#minecraft%3Ajump.static) | Gives the entity the ability to jump. | +| 组件 | 说明 | +| -------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| [minecraft:annotation.break_door](https://bedrock.dev/docs/stable/Entities#minecraft%3Aannotation.break_door) | 允许实体破坏门(需同时在导航组件中启用) | +| [minecraft:annotation.open_door](https://bedrock.dev/docs/stable/Entities#minecraft%3Aannotation.open_door) | 允许实体开门(需同时在导航组件中启用) | +| [minecraft:buoyant](https://bedrock.dev/docs/stable/Entities#minecraft%3Abuoyant) | 指定实体可以漂浮的液体类型 | +| [minecraft:can_climb](https://bedrock.dev/docs/stable/Entities#minecraft%3Acan_climb) | 允许实体攀爬梯子 | +| [minecraft:can_fly](https://bedrock.dev/docs/stable/Entities#minecraft%3Acan_fly) | 标记实体飞行能力(导航系统不会强制要求踏板支撑) | +| [minecraft:can_power_jump](https://bedrock.dev/docs/stable/Entities#minecraft%3Acan_power_jump) | 允许进行强力跳跃(类似马匹的跳跃机制) | +| [minecraft:floats_in_liquid](https://bedrock.dev/docs/stable/Entities#minecraft%3Afloats_in_liquid) | 使实体能够在液体中漂浮 | +| [minecraft:jump.dynamic](https://bedrock.dev/docs/stable/Entities#minecraft%3Ajump.dynamic) | 根据移动速度自动调整跳跃属性 | +| [minecraft:jump.static](https://bedrock.dev/docs/stable/Entities#minecraft%3Ajump.static) | 赋予实体基本的跳跃能力 | -There are also components like `minecraft:preferred_path`, which will modify navigation based on block-based path-cost. +## 人工智能 -## AI Goals +导航组件定义了移动方式,而AI目标组件决定移动的时机和目的地。AI目标通过优先级系统(数值越低优先级越高)控制行为选择。 -The navigation component tells the entity _how_ to generate paths, but it doesn't say _when_ or _where_ to generate paths. This is what the AI components are for. +通常需要叠加多个不同优先级的AI组件来形成自然的行为模式。以下为部分常用AI组件示例: -AI Goals are prefixed with `behavior` and follow a priority system to pick which behavior to run. The lower priorities will be picked first. - -In general, you should usually add quite a few AI components, with different priorities. Layered together, these will create realistic movement and behavior for your entity. As always, vanilla entities provide a good template for which components to add, and with what properties/priorities. - -There are too many AI components that generate paths to list in this document. A few will be provided as examples: - -| Component | -| --------------------------------------------------------------------------------------------------------------------------------- | +| 组件 | +| ---------------------------------------------------------------------------------------------------------------------------- | | [minecraft:behavior.random_stroll](https://bedrock.dev/docs/stable/Entities#minecraft%3Abehavior.random_stroll) | | [minecraft:behavior.follow_owner](https://bedrock.dev/docs/stable/Entities#minecraft%3Abehavior.follow_owner) | | [minecraft:behavior.move_to_water](https://bedrock.dev/docs/stable/Entities#minecraft%3Abehavior.move_to_water) | | [minecraft:behavior.stroll_towards_village](https://bedrock.dev/docs/stable/Entities#minecraft%3Abehavior.stroll_towards_village) | -For a full list, visit [bedrock.dev](https://bedrock.dev/docs/stable/Entities#AI%20Goals). +完整列表请访问[基岩开发文档](https://bedrock.dev/docs/stable/Entities#AI%20Goals)。 -### Pathfinding +### 路径规划 -Making entities go to specific places is one of the most common requests for Marketplace content. -The best way to do pathfinding uses a second entity, which the first entity will be attracted to. I am going to call this secondary entity the **marker**. If you are confused on how to create a marker, visit the [Dummy Entities](/entities/dummy-entities) page. +实现实体自动寻路是常用需求。推荐使用通过"诱饵实体"(Marker)进行引导的方案。若需要创建诱饵实体,请参考[虚拟实体教程](/entities/dummy-entities)。 -#### Idea +#### 实现思路 -The way we are going to do pathfinding is actually fairly simple: Make our entity aggressive towards our marker, and then simply place our marker where we want our entity to path to. The hard part is knowing what components to add so we get really long-range pathing. +基本原理是使主实体对诱饵实体产生敌对行为,通过放置诱饵实体引导主实体移动。关键点在于配置正确的组件参数以实现长距离寻路。 -#### Components +#### 组件配置 -These components can be edited as needed to create good pathing. Make sure to update the `nearest_attackable_target` to point to your marker entity. This takes a `family_type`, so you should set one of those on your marker. +以下配置中需要将`nearest_attackable_target`指向虚体诱饵(需要为诱饵实体设置family_type属性)。同时不要忘记添加常规的移动和导航组件。 -Don't forget to add some basic movement and navigation components so your entity is able to move. - - - -```json +::: code-group +```json [标记目标锁定] "minecraft:behavior.nearest_attackable_target": { "priority": 0, "reselect_targets": true, @@ -172,14 +160,14 @@ Don't forget to add some basic movement and navigation components so your entity "max": 1000 } ``` +::: -#### Detecting a reached waypoint +#### 航点到达检测 -You can use `minecraft:target_nearby_sensor` to detect when you have reached the marker entity: +使用目标临近传感器检测是否到达标记位置: - - -```json +::: code-group +```json [临近传感器] "minecraft:target_nearby_sensor": { "inside_range": 2.0, "outside_range": 4.0, @@ -192,11 +180,12 @@ You can use `minecraft:target_nearby_sensor` to detect when you have reached the } } ``` +::: -## Other +## 其他技巧 :::tip -You can trigger entity walking animation via command. +可通过命令强制触发实体行走动画: `/execute as @e[type=...] at @s run tp @s ^^^0.1` -This way you can control where entity goes and make it look natural. -::: +使用这种方式可以实现对实体移动路径的精确控制,并保持自然的动画效果。 +::: \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/flying-entities.md b/docs/wiki/3-实体/2-巧思案例/flying-entities.md index a5770421..1758e081 100644 --- a/docs/wiki/3-实体/2-巧思案例/flying-entities.md +++ b/docs/wiki/3-实体/2-巧思案例/flying-entities.md @@ -1,9 +1,9 @@ --- -title: Flying Entities -category: Tutorials +title: 飞行实体的控制方法 +category: 教程 tags: - - recipe - - intermediate + - 配方 + - 中级 mentions: - SirLich - Joelant05 @@ -16,39 +16,42 @@ mentions: - TheItsNameless --- -Whether making a plane or a dragon, adding controllability to flying entities will probably challenge most devs who haven't dabbled around this concept. Since there is no "right" way of adding a piloting mechanic to flying entities, I'll showcase 3 main workaround ways you can use to achieve this. +# 飞行实体的控制方法 -## Great Jump, Slow Fall + -While not exactly "flying", setting the entity's jumping power high and giving it slow falling & speed effects as it falls is probably the most straightforward method. +无论是制作飞机还是飞龙,为飞行实体添加可控性对于未接触过此类概念的开发者来说都具有挑战性。由于没有"标准"方法来实现飞行操控,本文将展示三种主要的替代方案。 -To achieve this, we will need to add the `"minecraft:horse.jump_strength"` component to our entity. Adding this will allow you to control its jumping power and disable dismounting when the player presses the jump button. +## 高跳缓降法 - +虽然不算严格意义上的"飞行",但通过设置实体高跳跃能力并附加缓降和加速效果是最直接的方式。 -```json +需要给实体添加 `"minecraft:horse.jump_strength"` 组件,该组件可控制跳跃高度并禁用跳跃键下马功能。 + +::: code-group +```json [组件配置] "minecraft:horse.jump_strength": { "value": 7 } ``` +::: -We can also use `"value"` as an object to utilize the **range bar** players will see when holding down the jump button. +使用范围值对象可显示蓄力进度条: - - -```json +::: code-group +```json [蓄力进度条配置] "minecraft:horse.jump_strength": { "value": { "range_min": 0.6, "range_max": 1.2 } } ``` +::: -Now we will give it slow falling and speed as it's falling so that it doesn't instantly fall. To do this, we will make an animation controller and give it those effects when it's not on the ground as so: +通过动画控制器在空中时附加缓降和加速效果: -(You can read a tutorial on how to use animation controllers to execute commands [here](/animation-controllers/entity-commands).) +(可参考[实体命令动画控制器教程](/animation-controllers/entity-commands)) - - -```json +::: code-group +```json [动画控制器] "controller.animation.dragon.flying":{ "states":{ "default":{ @@ -75,12 +78,12 @@ Now we will give it slow falling and speed as it's falling so that it doesn't in } } ``` +::: -We'll also need to hook it up to our entity as so: +实体描述符需关联控制器: - - -```json +::: code-group +```json [实体配置] "description":{ "identifier":"wiki:dragon", "is_spawnable":true, @@ -96,20 +99,18 @@ We'll also need to hook it up to our entity as so: } } ``` +::: -Now, we should have a mechanic at least resemblant of flying. You can change the values like jump_strength and speed, but the entity will always fall using this method. +通过调整跳跃力度和速度参数可改变飞行体验,但实体最终仍会下落。 -## Controlling Through Looking +## 视角控制法 -This is probably the most popular method of piloting flying entities, and unlike the first method, this one gives players control over the vertical movement of the entity so that you don't always have to fall every time you jump, with the downside being you can't look around freely without changing the entity's vertical trajectory. +这是最流行的飞行控制方式,通过检测玩家俯仰角来控制垂直运动。优点是可主动控制升降,缺点是视角转动会影响飞行轨迹。 -This method detects the riding player's vertical rotation and applies levitation/slow_falling effects to the entity accordingly. +使用命令方块检测玩家垂直视角并应用飘浮/缓降效果: -There are multiple ways of achieving that, but in this tutorial, we'll be using the target selectors `rym` (minimum y-rotation) and `ry` (maximum y-rotation) in a chain of repeating command-blocks to detect the player's pitch, and depending on the range, giving our entity levitation or slowly falling. - - - -``` +::: code-group +```mcfunction execute @a[rxm=-90,rx=-25] ~~~ effect @e[type=wiki:dragon,r=1] levitation 1 6 true execute @a[rxm=-25,rx=-15] ~~~ effect @e[type=wiki:dragon,r=1] levitation 1 3 true execute @a[rxm=-15,rx=-5] ~~~ effect @e[type=wiki:dragon,r=1] levitation 1 2 true @@ -117,17 +118,14 @@ execute @a[rxm=-5,rx=20] ~~~ effect @e[type=wiki:dragon,r=1] levitation 1 1 true execute @a[rxm=20,rx=35] ~~~ effect @e[type=wiki:dragon,r=1] slow_falling 1 1 true execute @a[rxm=35,rx=90] ~~~ effect @e[type=wiki:dragon,r=1] clear ``` +::: -**Depending on how big your entity is and how far away the player's seat is from its pivot, you might need to change the radius `r` to a more significant value.** +**注意:根据实体尺寸和坐骑点位置可能需要调整选择器半径 `r` 的数值** -After you run those commands in a repeating command block, you should control its vertical movement by looking up and down. -or you may use a simple animation controller and link it to the entity, so it always plays the function. +建议通过动画控制器关联玩家实现持续效果: -It's recommended that you link this animation controller to the player. - - - -```json +::: code-group +```json [玩家动画控制器] { "format_version": "1.10.0", "animation_controllers": { @@ -159,12 +157,12 @@ It's recommended that you link this animation controller to the player. } } ``` +::: -The entity will probably still be too slow when flying, so we'll borrow our animation controller from the first method with some changes to give the entity speed when it's flying. +通过改良版动画控制器维持飞行速度: - - -```json +::: code-group +```json [改良版速度控制器] "controller.animation.dragon.flying":{ "states":{ "default":{ @@ -213,14 +211,12 @@ The entity will probably still be too slow when flying, so we'll borrow our anim } } ``` +::: -_Since the entity's effects might be cleared when it's being flown, we changed the animation controller to give the entity speed every tick it's not on the ground._ +添加骑乘检测标签来优化误触发问题: -You might also notice that the entity levitates when you go near it. We can fix this by giving the entity a tag when it's being ridden (removing it when it isn't being ridden) and only applying those effects when the entity has the tag by making and animating another animation controller and updating our commands. - - - -```json +::: code-group +```json [骑乘检测控制器] "controller.animation.dragon.test_rider":{ "states":{ "default":{ @@ -246,10 +242,12 @@ You might also notice that the entity levitates when you go near it. We can fix } } ``` +::: - +对应调整命令选择器: -``` +::: code-group +```mcfunction execute @a[rxm=-90,rx=-25] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] levitation 1 6 true execute @a[rxm=-25,rx=-15] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] levitation 1 3 true execute @a[rxm=-15,rx=-5] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] levitation 1 2 true @@ -257,29 +255,27 @@ execute @a[rxm=-5,rx=20] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] levit execute @a[rxm=20,rx=35] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] slow_falling 1 1 true execute @a[rxm=35,rx=90] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] clear ``` +::: -## Controlling Through Jumping +## 跳跃键控制法 -A third method of controlling flying entities uses the player's jump button. The entity rises when the player is holding the jump button and falls when they release their jump button. +通过跳跃键实现升降控制:按住跳跃上升,松开自动下降。 -To do this, we need an animation controller attached to the player rather than the entity itself to detect when the player uses their jump button. We also need to disable dismounting when the player presses the jump button. +首先禁用默认跳跃功能: -First, on the entity, disable dismounting and jumping: - - - -```json +::: code-group +```json [实体组件配置] "minecraft:horse.jump_strength": { "value": 0 }, "minecraft:can_power_jump": {} ``` +::: -Next, we need an animation controller that causes the entity to levitate when the player uses their jump button and resets the levitation when they release their jump button. +创建响应跳跃输入的动画控制器: - - -```json +::: code-group +```json [跳跃键控制器] "controller.animation.fly_dragon":{ "initial_state":"falling", "states":{ @@ -306,12 +302,12 @@ Next, we need an animation controller that causes the entity to levitate when th } } ``` +::: -Now, we need a copy of the player's behavior file, which we will modify slightly. You can find the player's behavior file in the vanilla behavior pack provided by Mojang (found [here](https://aka.ms/behaviorpacktemplate)). Once you have copied the player's behavior file to your own behavior pack, find their `"description"` object and add the animation controller. We also want to ensure that the entity will only respond to the player's jump input when the player is riding it, so we can use a Molang query in the player's behavior to only activate the animation controller when the player is riding. +需修改玩家行为文件(需从[官方模板包](https://aka.ms/behaviorpacktemplate)获取)并添加控制器: - - -```json +::: code-group +```json [玩家配置文件] "description":{ "identifier":"minecraft:player", "is_spawnable":false, @@ -328,12 +324,12 @@ Now, we need a copy of the player's behavior file, which we will modify slightly } } ``` +::: -The entity can now be controlled with the jump key, but there's a bug. If the player dismounts the entity while holding the jump key, it will continue rising. We can fix this with an animation controller on the entity itself that resets the levitation whenever a player dismounts it. +添加离鞍状态复位控制器: - - -```json +::: code-group +```json [离鞍复位控制器] "controller.animation.reset_levitation":{ "initial_state":"no_rider", "states":{ @@ -357,3 +353,4 @@ The entity can now be controlled with the jump key, but there's a bug. If the pl } } ``` +::: \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/introduction-to-aec.md b/docs/wiki/3-实体/2-巧思案例/introduction-to-aec.md index c3041df6..4ea965a5 100644 --- a/docs/wiki/3-实体/2-巧思案例/introduction-to-aec.md +++ b/docs/wiki/3-实体/2-巧思案例/introduction-to-aec.md @@ -1,78 +1,82 @@ --- -title: Introduction to AOE Clouds -category: Tutorials +title: AOE云区域效果介绍 +category: 教程 tags: - - intermediate + - 中阶 mentions: - Sprunkles137 - MedicalJewel105 --- -**Area-of-effect clouds**, also known as AOE clouds and `minecraft:area_effect_cloud` internally, are special entities that have many unique properties. Normally these entities are created through throwing lingering potions, but with structures and some NBT editing magic we can manipulate them in very powerful ways for map-making. +# AOE云区域效果介绍 -## Overview + -Area-of-effect clouds have several special features we can take advantage of: +**区域效果云**(Area-of-effect clouds),在内部也被称为AOE云或`minecraft:area_effect_cloud`,是一种具有独特属性的特殊实体。这些实体通常通过投掷滞留药水生成,但借助结构文件和NBT编辑魔法,我们可以在地图制作中以极其强大的方式操控它们。 -- As [dummy entities](/entities/dummy-entities), they are highly performant and barely affect framerate, and they are also completely static and have no collision with the world. This makes them perfect for situations around players or where precise positioning is important. -- It does not send the client updates. Once it spawns in, it will visually appear to be frozen in place until it despawns. However, it can still be moved around through commands just fine. -- It can apply any potion effect in highly configurable ways. The duration can be set down to the tick, as well as whether or not the effect is ambient, or displays on the screen, if it emits particles, etc. -- Entities with a runtime identifier of `minecraft:area_effect_cloud` inherit these same properties. +## 概述 -## Method 1: Projectile Component +区域效果云具备以下可被利用的特性: -The projectile component supports spawning in area-of-effect clouds on hit. Minecraft uses this to spawn in AOE clouds from lingering potions. +- 作为[虚拟实体](/entities/dummy-entities),它们在性能表现优异,几乎不影响帧率,且完全静态且不与世界发生碰撞。这使其非常适用于需要围绕玩家或精确定位的场景。 +- 不会向客户端发送更新。生成后视觉上会定格在初始位置直至消失,但仍可通过指令自由移动。 +- 能以高度可配置的方式施加任何药水效果(精准到游戏刻的持续时间设定,调节环境效果、屏幕提示显示、粒子发射等属性)。 +- 具有运行时标识符`minecraft:area_effect_cloud`的实体将继承相同属性。 -[Projectiles Documentation](/documentation/projectiles#spawn-aoe-cloud) +## 方法一:投射物组件 -## Method 2: NBT Editing +投射物组件支持在命中时生成区域效果云。Minecraft正是通过此机制实现投掷滞留药水生成AOE云。 -Another way to spawn in these area-of-effect clouds is through structure files. This grants us finer control over the potion effects the cloud can have. So, our first order of business is getting a means to edit these structures. +[投射物组件文档](/documentation/projectiles#spawn-aoe-cloud) -### NBT Editors +## 方法二:NBT编辑 -One of the following NBT editors are recommended: +另一种方式是通过结构文件生成区域效果云。这使我们可以更精细控制云效果属性。首先需要准备合适的NBT编辑工具。 -- [NBT Studio](https://github.com/tryashtar/nbt-studio) (a standalone program by tryashtar) -- [NBT Viewer](https://marketplace.visualstudio.com/items?itemName=Misodee.vscode-nbt) (a Visual Studio Code extension by Misode) +### NBT编辑器 -### Structure file +推荐使用以下任一NBT编辑器: -For convenience, this article contains a premade structure file you can download and use. Inside is an AOE cloud that exists for the maximum possible time. +- [NBT Studio](https://github.com/tryashtar/nbt-studio)(由tryashtar开发的独立程序) +- [NBT Viewer](https://marketplace.visualstudio.com/items?itemName=Misodee.vscode-nbt)(由Misode开发的VSCode扩展) -Download MCSTRUCTURE +### 结构文件 -Refer to this article for editing structure files: [.mcstructure](/nbt/mcstructure) +本文包含预制的结构文件可供下载使用。文件内设置了一个存在时间最大化的AOE云效果。 -### NBT Format +::: code-group +```json [点击下载MCSTRUCTURE文件] +``` +::: -| Tag | Type | Description | -| --------------------- | ------- | ----------------- | -| Duration | Integer | How long the cloud exists for before expiring, in ticks. | -| DurationOnUse | Integer | How much the duration should change when effects are applied. | -| InitialRadius | Float | The size of this cloud's radius when created. | -| ParticleColor | Integer | The color of the particle effect, in decimal. | -| ParticleId | Integer | The particle effect this cloud emits. 0 emits no particles. | -| PotionId | Short | This cloud's potion effect ID when created. Has no effect. | -| RadiusChangeOnPickup | Float | Unknown. | -| RadiusOnUse | Float | How much the radius should change when effects are applied. | -| RadiusPerTick | Float | How much the radius changes every tick. | -| ReapplicationDelay | Integer | The interval at which effects can be applied, in ticks. | -| mobEffects | List | Describes what potion effects should be applied. | +结构文件编辑指南请参考:[.mcstructure文件解析](/nbt/mcstructure) -Below are the parameters for the `mobEffects` tag. +### NBT数据格式 -| Tag | Type | Description | -| ------------------------------- | ------- | --------------- | -| Ambient | Byte | Defines whether this effect's particles should be translucent or not. | -| Amplifier | Byte | The strength of this potion effect. | -| DisplayOnScreenTextureAnimation | Byte | Unknown. | -| Duration | Integer | The amount of time this effect is applied for, in ticks. | -| DurationEasy | Integer | Unknown, seemingly unused. | -| DurationNormal | Integer | Unknown, seemingly unused. | -| DurationHard | Integer | Unknown, seemingly unused. | -| Id | Byte | The potion effect ID for this effect. | -| ShowParticles | Byte | Defines whether this effect's particles should appear or not. | +| 字段 | 类型 | 说明 +| --------------------- | ------- | ------------- +| Duration | 整型 | 效果云存在总时长(单位:刻) +| DurationOnUse | 整型 | 应用效果后持续时间的增量 +| InitialRadius | 浮点型 | 初始生成时的半径 +| ParticleColor | 整型 | 粒子颜色(十进制数值) +| ParticleId | 整型 | 发射的粒子类型ID(0表示无粒子) +| PotionId | 短整型 | 药水效果ID(创建时使用,无实质效果) +| RadiusChangeOnPickup | 浮点型 | (未知用途) +| RadiusOnUse | 浮点型 | 应用效果后的半径变化量 +| RadiusPerTick | 浮点型 | 每刻半径的变化量 +| ReapplicationDelay | 整型 | 两次效果应用的最小间隔(刻) +| mobEffects | 列表 | 实体携带的药水效果配置 + +以下是`mobEffects`标签的参数说明: + +| 字段 | 类型 | 说明 +| ------------------------------- | ------- | ------------- +| Ambient | 字节 | 效果粒子是否为半透明形态 +| Amplifier | 字节 | 效果强度等级(0表示I级) +| DisplayOnScreenTextureAnimation | 字节 | (未知用途) +| Duration | 整型 | 效果持续时间(刻) +| DurationEasy | 整型 | (未知用途,疑似未使用) +| DurationNormal | 整型 | (未知用途,疑似未使用) +| DurationHard | 整型 | (未知用途,疑似未使用) +| Id | 字节 | 药水效果类型ID +| ShowParticles | 字节 | 是否显示效果粒子 \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/invulnerable-entities.md b/docs/wiki/3-实体/2-巧思案例/invulnerable-entities.md index dddee5eb..a0dd5545 100644 --- a/docs/wiki/3-实体/2-巧思案例/invulnerable-entities.md +++ b/docs/wiki/3-实体/2-巧思案例/invulnerable-entities.md @@ -1,6 +1,6 @@ --- -title: Invulnerable Entities -category: Tutorials +title: 无敌实体 +category: 教程 tags: - beginner mentions: @@ -10,58 +10,62 @@ mentions: - MedicalJewel105 --- -## Using Damage Sensor +# 无敌实体 -The best and most flexible way of disabling damage for entities is using the `minecraft:damage_sensor` component. The component allows us to use `filters` to determine which damage sources can damage our entity. + -The best way to learn about this component is by using the vanilla examples for damage sensor or reading [documentation](https://bedrock.dev/docs/stable/Entities#minecraft:damage_sensor) +## 使用伤害传感器组件 -### Completely Invulnerable Entity +禁用实体伤害的最佳且最灵活的方式是使用 `minecraft:damage_sensor` 组件。该组件允许我们通过 `filters` 过滤器来指定哪些伤害源可以作用于实体。 -BP/entities/entity.json#minecraft:entity/components +了解这个组件的最好方法是查阅原版伤害传感器示例或阅读[官方文档](https://bedrock.dev/docs/stable/Entities#minecraft:damage_sensor) -```json +### 完全无敌的实体 + +::: code-group +```json [BP/entities/entity.json#minecraft:entity/components] "minecraft:damage_sensor": { "triggers": { - "cause": "all", - "deals_damage": false + "cause": "all", // 捕捉全部伤害类型 + "deals_damage": false // 取消实际伤害效果 } } ``` +::: -### Disable Damage from Player +### 禁止玩家伤害 -BP/entities/entity.json#minecraft:entity/components - -```json +::: code-group +```json [BP/entities/entity.json#minecraft:entity/components] "minecraft:damage_sensor": { "triggers": { - "on_damage": { - "filters": { - "test": "is_family", - "subject": "other", - "value": "player" + "on_damage": { // 当受到伤害时触发 + "filters": { // 过滤器配置 + "test": "is_family", // 检测对象类型 + "subject": "other", // 检测施加伤害的主体 + "value": "player" // 当伤害来源为玩家时生效 } }, - "deals_damage": false + "deals_damage": false // 取消实际伤害效果 } } ``` +::: -## Min Health +## 最低生命值限制 -The `min` property in the `minecraft:health` component allows us to make invincible entities that cannot die. This includes when using `/kill @e`. This is not considered a good solution because entities like this are hard to get rid of. +通过 `minecraft:health` 组件中的 `min`(最小值)属性,我们可以创建无法自然死亡的无敌实体(即使使用 `/kill @e` 命令也无法清除)。需要注意的是该方案可能引发后续问题——这类实体会永久驻留世界。 -If you choose to use this component, please make sure you have another method for killing the entity. Triggering `minecraft:instant_despawn` from something like an environment sensor, a timer, or an interact is a good solution. You also can call it using `/event`. +如果使用此方案,**请务必配置备用清除机制**。例如通过环境传感器组件、计时器组件或互动组件触发的 `minecraft:instant_despawn` 事件实现清除,也可以通过执行 `/event` 命令手动触发。 -BP/entities/entity.json#minecraft:entity/components - -```json +::: code-group +```json [BP/entities/entity.json#minecraft:entity/components] "minecraft:health": { - "value": 1, - "max": 1, - "min": 1 + "value": 1, // 当前生命值 + "max": 1, // 最大生命值 + "min": 1 // 生命值下限(设置为与max相等将保持血量恒定) } ``` +::: -Note that setting it to 0 breaks some death and spawn animations/effects. +> **技术提示**:将该值设置为0可能会导致部分死亡和重生动画/粒子效果无法正常显示。 \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/look-at-entity.md b/docs/wiki/3-实体/2-巧思案例/look-at-entity.md index 0213cef7..f1db47f2 100644 --- a/docs/wiki/3-实体/2-巧思案例/look-at-entity.md +++ b/docs/wiki/3-实体/2-巧思案例/look-at-entity.md @@ -1,8 +1,8 @@ --- -title: Look at Entity -category: Tutorials +title: 看向实体 +category: 教程 tags: - - intermediate + - 中级 mentions: - shanewolf38 - MedicalJewel105 @@ -10,35 +10,42 @@ mentions: - SmokeyStack --- -The following tutorial provides a resource pack method to detect when the player is looking at an entity. The code below must be placed inside the entity that will be looked at by the player, and will provide a variable `v.look_at_entity` which returns true when the entity is being looked at. +# 看向实体 -## variable + -RP/entity/mob.entity.json +以下教程提供了一种资源包方法,用于检测玩家何时看向实体。下方代码必须放置在会被玩家注视的实体文件中,并通过变量`v.look_at_entity`返回true值来指示实体当前是否被注视。 -```json +## 变量 + +::: code-group +```json [RP/entity/mob.entity.json] "pre_animation": [ "v.look_at_entity = Math.abs(Math.abs(q.rotation_to_camera(1) - q.camera_rotation(1)) - 180) < (20 / q.distance_from_camera) && Math.abs(q.rotation_to_camera(0) + q.camera_rotation(0)) < (10 / q.distance_from_camera);" ], ``` -:::tip -Because the query `q.rotation_to_camera` is based at the origin of the entity (their feet), the vertical detection range will be based around the bottom of the entity. The code below creates a modified variable for the vertical angle which takes a positional offset into account to allow the vertical detection range to be based around the center of the entity. +:::tip 补充说明 +由于查询参数`q.rotation_to_camera`基于实体的原点(脚部位置),垂直检测范围将围绕实体底部进行计算。下方代码通过创建经过位置偏移修正的垂直角度变量,使垂直检测范围能够基于实体中心进行计算。 ::: -RP/entity/mob.entity.json - -```json +::: code-group +```json [RP/entity/mob.entity.json] "pre_animation": [ "v.rotation_to_camera_0 = -Math.atan2(-q.distance_from_camera * Math.sin(q.rotation_to_camera(0)) - 1, q.distance_from_camera * Math.cos(q.rotation_to_camera(0)));", "v.look_at_entity = Math.abs(Math.abs(q.rotation_to_camera(1) - q.camera_rotation(1)) - 180) < (20 / q.distance_from_camera) && Math.abs(v.rotation_to_camera_0 + q.camera_rotation(0)) < (60 / q.distance_from_camera);" ], ``` -## Modifying +## 参数调整 +当前代码主要适配标准Minecraft生物规格(1×2方块)。如需适配不同尺寸的实体,需要调整以下参数: +- 数值 `-1` 控制生物中心位置偏移量(负值向上,正值向下) +- 数值 `20` 控制水平角度敏感度 +- 数值 `60` 控制垂直角度敏感度 -The provided code is very accurate for the standard Minecraft mob size of 1 block wide and 2 blocks tall, but for entities of different sizes the parameters should be changed. The `- 1` controls the positional offset of the center of the mob (- is upward, + is downward), the `20` controls the horizontal angle sensitivity, and the `60` controls the vertical angle sensitivity. +## 实现原理 +该变量的工作原理是检测两种旋转角度是否相反: +1. 实体需要转向玩家的旋转角度 +2. 玩家需要转向实体的旋转角度 -## Explanation - -The variable detects when the player is looking at the entity by checking if the rotation angle required for the entity to look at the player is opposite the rotation angle required for the player to look at the entity. The horizontal and vertical angle sensitivity are modified by the distance of the entity from the camera to maintain accuracy. +通过对比水平和垂直方向的角度差值(数值大小通过相机与实体的距离进行动态缩放),即可精确判定注视状态。 \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/sleeping-entities.md b/docs/wiki/3-实体/2-巧思案例/sleeping-entities.md index 888ca6ef..0b3c8efb 100644 --- a/docs/wiki/3-实体/2-巧思案例/sleeping-entities.md +++ b/docs/wiki/3-实体/2-巧思案例/sleeping-entities.md @@ -1,48 +1,51 @@ --- -title: Sleeping Entities -category: Tutorials +title: 睡眠实体 +category: 教程 tags: - - intermediate + - 中级 mentions: - MedicalJewel105 - SirLich --- -This tutorial will explain how to make entity sleep. +# 睡眠实体 -## Sleeping in beds + -This behavior is inspired from villagers. +本文将指导如何为实体添加睡眠功能。 -### Features +## 在床上睡眠 -- Entity sleeps during the night and wakes up at day time. -- Interaction with entity will wake it up and after a while it goes sleeping again. -- If entity is hurt, it wakes up. +该行为的灵感来源于村民设计。 -### Behavior Pack +### 特性 -In this section behavior pack components will be discussed. +- 实体在夜晚自动入睡,天亮时苏醒 +- 与实体互动可唤醒它,并在一段时间后重新入睡 +- 实体受到伤害时会立即清醒 -#### Components +### 行为包配置 -Let's start with some basic components that you need to add to your entity. +本节将解析行为包所需组件。 -BP/entities/sleeping_entity.json#components +#### 组件 -```json +首先在实体组件中添加基础元素: + +::: code-group +```json [行为包] "minecraft:dweller": { "dwelling_type": "village", "dweller_role": "inhabitant", "can_find_poi": true } ``` +::: -Undocumented, needed for entity to be able to sleep. +此组件未经官方文档记载,但实体需要它以实现睡眠功能。 -BP/entities/sleeping_entity.json#components - -```json +::: code-group +```json [行为包] "minecraft:environment_sensor": { "triggers": [ { @@ -55,21 +58,20 @@ Undocumented, needed for entity to be able to sleep. ] } ``` - -This component is required for entity understand when to sleep. -It runs event if it isn't day time. - -:::warning -You need some basic navigation components for your entity be able to move to bed. ::: -#### Component Groups +用于识别何时进入睡眠状态,会在非白天时段触发`sleep`事件。 -Now you need some component groups for your entity with some components. +:::warning +注意:实体需具备基础导航组件才能移动到床上。 +::: -BP/entities/sleeping_entity.json#component_groups +#### 组件组 -```json +接下来为实体配置复合组件组: + +::: code-group +```json [行为包] "sleeping": { "minecraft:behavior.sleep": { "priority": 0, @@ -118,26 +120,23 @@ Now you need some component groups for your entity with some components. } } ``` +::: +参数解析: - `minecraft:behavior.sleep` +定义睡眠行为核心参数,优先级须设为`0`(最高级别) -Determines sleep details, priority needs to be at `0` (the biggest weight). - -- `minecraft:damage_sensor`` - -Add it if you want your entity wake up if it is being attacked. +- `minecraft:damage_sensor` +实现受击苏醒功能 - `minecraft:environment_sensor` - -Runs `wake_up` event when it is day time. +白昼时触发`wake_up`事件 - `minecraft:interact` +允许玩家无伤害唤醒实体 -This makes player to be able wake up entity without hurting it. - -BP/entities/sleeping_entity.json#component_groups - -```json +::: code-group +```json [行为包] "sleep_timer": { "minecraft:timer": { "time": 15, @@ -147,17 +146,16 @@ This makes player to be able wake up entity without hurting it. } } ``` +::: -This component group is required for entity to fall asleep again (with some delay) after it was woken up. +此组件组用于设置唤醒后的重新入睡延时。 -#### Events +#### 事件配置 -Here you will find all events that you need. -I don't really think it needs explanation. +以下事件系统逻辑相对直观: -BP/entities/sleeping_entity.json#events - -```json +::: code-group +```json [行为包] "sleep": { "add": { "component_groups": [ @@ -197,18 +195,18 @@ I don't really think it needs explanation. } } ``` +::: -### Resource Pack +### 资源包配置 -Don't forget that you need to add sleeping animation and controller for it to your entity! +请确保为实体添加睡眠动画和动画控制器! -#### Animation +#### 动画配置 -Just copy/paste it. +直接复制以下配置: -RP/animations/sleeping_entity.animation.json - -```json +::: code-group +```json [资源包] { "format_version": "1.8.0", "animations": { @@ -228,14 +226,14 @@ Just copy/paste it. } } ``` +::: -#### Animation Controller +#### 动画控制器 -Again just copy/paste it if you need. +推荐直接套用此模板: -RP/animations_controllers/ac.sleeping_entity.sleep.json - -```json +::: code-group +```json [资源包] { "format_version": "1.10.0", "animation_controllers": { @@ -262,36 +260,32 @@ Again just copy/paste it if you need. } } ``` +::: -Note that you will need to define animation in client entity like this: +注意:需在客户端实体定义中关联动画:`"sleeping": "animation.sleeping_entity.sleep"` -`"sleeping": "animation.sleeping_entity.sleep"` - -### Result +### 效果演示 ![](/assets/images/tutorials/sleeping-entities/result.png) -## Taking naps +## 小憩系统 -This behavior is inspired from foxes. +此行为灵感来源于狐狸设计。 -### Features +### 特色功能 -- Entity sleeps when feels safe, far from mobs or when the weather is not a thunderstorm. -- Approaching the entity will make it wake up unless it's a trusted or sneaking player, or it's another entity with the family group `sleeping_entity`. -- If entity is hurt, it wakes up. +- 实体在安全环境(远离敌对生物且无雷暴天气)下进入小憩状态 +- 仅允许信任的潜行玩家或同族`sleeping_entity`实体靠近时不惊醒 +- 受击后自动苏醒 -### Behavior Pack +### 行为包配置 -In this section behavior pack components will be discussed. +#### 核心组件 -#### Components +仅需一个核心组件: -For this behavior you will need only one component: - -BP/entities/sleeping_entity.json#components - -```json +::: code-group +```json [行为包] "minecraft:behavior.nap": { "priority": 8, "cooldown_min": 2.0, @@ -350,22 +344,22 @@ For this behavior you will need only one component: } } ``` +::: -If you want to also use the trusting mechanic, add: +如需实现信任机制,可附加: -BP/entities/sleeping_entity.json#components - -```json +::: code-group +```json [行为包] "minecraft:trust": {} ``` +::: -### Resource Pack +### 资源包配置 -In our resource pack you can run an animation when entity starts to sleep. +可通过动画控制器实现睡眠动画: -RP/animations_controllers/ac.sleeping_entity.sleep.json - -```json +::: code-group +```json [资源包] { "format_version": "1.10.0", "animation_controllers": { @@ -392,5 +386,6 @@ In our resource pack you can run an animation when entity starts to sleep. } } ``` +::> -The last thing, you will have to create and register a sleeping animation for you entity. If you don't know how to do it check out the [BlockBench page](/guide/blockbench.html#animating). \ No newline at end of file +最后需要为实体创建并注册睡眠动画,若存在制作难题可参考[BlockBench动画教程](/guide/blockbench.html#animating)。 \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/solid-entities.md b/docs/wiki/3-实体/2-巧思案例/solid-entities.md index 8c900006..5d24e406 100644 --- a/docs/wiki/3-实体/2-巧思案例/solid-entities.md +++ b/docs/wiki/3-实体/2-巧思案例/solid-entities.md @@ -1,9 +1,9 @@ --- -title: Solid Entities -category: Tutorials +title: 实体碰撞体 +category: 教程 tags: - - recipe - - intermediate + - 配方指南 + - 中级 mentions: - SirLich - Joelant05 @@ -13,78 +13,82 @@ mentions: - ThomasOrs --- -Solid entities are entities that the player can bump into, step on, or otherwise physically interact with without passing through. Entities like this have many uses, such as emulating blocks. +# 实体碰撞体 -This page will discuss some of the ways that solid entities can be created. + -Not all techniques are ideal for all scenarios. Experiment, and figure out what works best for you. +实体碰撞体是指玩家能够碰撞、踩踏或与之发生物理互动,而不会穿透的实体。这类实体有多种用途,例如模拟方块效果。 -## Runtime Identifiers +本页将探讨几种创建实体碰撞体的方法。 -[Runtime identifiers](/entities/runtime-identifier) can be used to achieve solid entities, but currently only 2, each with a specific shape, and their own side effects. Neither collision shapes are possible to change or scale. +并非所有技术都适用于所有场景。建议多加实验,找到最适合您需求的方案。 -### Boat +## 运行时标识符 -BP/entities/entity_name.json +通过[运行时标识符](/entities/runtime-identifier)可以实现实体碰撞效果。但目前仅支持两种预设形态,每种形态具有特定的碰撞箱及副作用。且两种模型的碰撞形状均不可调节或缩放。 -```json +### 船型实体 + +::: code-group +```json [BP/entities/entity_name.json] { "format_version": "1.16.0", "minecraft:entity": { "description": { "identifier": "wiki:solid_entity", "runtime_identifier": "minecraft:boat" - . . . + // 此处省略其他配置... } } } ``` +::: -- Boat-shaped solid collision -- Certain other boat-like effects +- 采用船形的实体碰撞箱 +- 具备部分船只特有交互特性 -### Shulker +### 潜影贝型实体 -BP/entities/entity_name.json - -```json +::: code-group +```json [BP/entities/entity_name.json] { "format_version": "1.16.0", "minecraft:entity": { "description": { "identifier": "wiki:solid_entity", "runtime_identifier": "minecraft:shulker" - . . . + // 此处省略其他配置... } } } ``` +::: -- 1x1 block sized solid collision. -- Sticks to block grid. -- Teleports randomly when supporting block removed. +- 1×1方块尺寸的实体碰撞箱 +- 固定于方块网格 +- 当支撑方块被移除时会随机瞬移 -## minecraft:is_stackable +## minecraft:is_stackable 组件 -Add `minecraft:is_stackable` to your entity you want to be treated as being solid. -**Note:** This requires editing `player.json` if you wish the entity to be solid for the player. +通过给实体添加`minecraft:is_stackable`组件可使其具有实体碰撞属性。 +**注意:** 如果希望实体对玩家而言具有碰撞,需要修改`player.json`文件。 `"minecraft:is_stackable": {}` -You will also need to add `minecraft:push_through` and set its `value` parameter to 1. +同时还需添加`minecraft:push_through`组件,并将其`value`参数设为1: `"minecraft:push_through": 1` -(they should both go in `components`) +(这两个组件都应置于`components`项下) -## Faking it with blocks +## 模拟方块效果 -In some scenarios, it's probably better to `/setblock` or `/fill` to place barrier blocks, either statically or dynamically. There needs to be both a way of placing the barriers, and removing them. +某些情况下更适合使用`/setblock`或`/fill`命令静态或动态放置屏障方块。需配套提供屏障的放置与清除机制: `/fill ~ ~ ~ ~ ~1 ~ barrier 0 replace air` -Places barriers in a 1x1x2 area. +在1×1×2区域生成屏障方块。 `/fill ~1 ~1 ~1 ~-1 ~-1 ~-1 air 0 replace barrier` -Removes barriers within a 3x3x3 area. +清除3×3×3范围内的屏障方块。 -These [commands](/animation-controllers/entity-commands) will have to be triggering at a constant rate, for consistency. They can either be triggered through entity components, or animation controllers. +为保证效果连贯性,这些[动画控制器实体指令](/animation-controllers/entity-commands)需要保持持续激活状态。可通过实体组件或动画控制器实现持续触发。 \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/timers.md b/docs/wiki/3-实体/2-巧思案例/timers.md index 3f679e41..f10de473 100644 --- a/docs/wiki/3-实体/2-巧思案例/timers.md +++ b/docs/wiki/3-实体/2-巧思案例/timers.md @@ -1,8 +1,8 @@ --- -title: Entity Timers -category: Tutorials +title: 实体计时器 +category: 教程 tags: - - intermediate + - 中级 mentions: - SirLich - Joelant05 @@ -13,32 +13,36 @@ mentions: - zheaEvyline --- -Time-based interactions are extremely useful tools for map making. This article hopes to provide an extensive list which details the many ways which timers can be made. For convenience, this page will be split up into two main sections: component-based timers and animation-based timers. Each has their own advantages and disadvantages, which will be outlined in their respective sections. -You might also find useful [Scoreboard Timers](/commands/scoreboard-timers). +# 实体计时器 -## Component-based timers + -Component-based timers are done inside the entity.json file of the behavior pack. They have the distinct advantage of persisting upon the entity being reloaded, but are limited by the number of timing components (duplicate components replace each other, which means defining multiple timers using the `minecraft:timer` component isn't possible). +基于时间的交互是地图制作的超实用工具。本文旨在提供一份详尽的指南,详解多种创建计时器的方法。为方便阅读,本页将分为两大部分:组件计时器和动画计时器。每种方式都有其独特优劣,我们将在对应章节详细探讨。 -### minecraft:timer +你可能也会对[计分板计时器](/commands/scoreboard-timers)感兴趣。 -This is the simplest but most effective component for triggering events after an elapsed amount of time. The component [minecraft:timer](https://bedrock.dev/docs/1.14.0.0/1.14.30.2/Entities#minecraft:timer) provides three main ways in which the amount of time before the event can be defined: +## 基于组件的计时器 -- Exact timing: an exact amount of time after which the event will fire is defined (e.g. 3.4 seconds) -- Random interval: an interval is defined in which the event will fire at a random time inside that interval (e.g. between 3 to 5 seconds) -- Weighted random choice: a number of times are defined and assigned weights, one of which will be chosen for the event to fire (e.g. a 20% chance for the event to fire at 5 seconds, and an 80% chance to fire at 20 seconds) +组件计时器通过行为包的`entity.json`文件实现。其最大优点是实体重载时仍能保持计时状态,但受限于可用的计时组件数量(重复组件会互相覆盖,意味着无法通过`minecraft:timer`组件创建多个独立计时器)。 -In the vanilla Behavior Pack, this component is used in all kinds of circumstances. For example: +### minecraft:timer组件 -- The dolphin can only spend 20 seconds on land before it dries out -- Bees will perish between 10 and 60 seconds after stinging -- The wandering trader will only stay for either 2400 or 3600 seconds +这是最简单却最高效的延时触发事件组件。[minecraft:timer](https://bedrock.dev/docs/1.14.0.0/1.14.30.2/Entities#minecraft:timer)提供三种主要时间设定方式: -A simple example which triggers an event after 5.6 seconds: +- **精确计时**:固定时间后触发事件(例如3.4秒) +- **随机区间**:在指定时间区间内随机触发(例如3到5秒之间) +- **权重随机选择**:定义多组时间选项配比权重,随机选择其中一个时间触发(例如20%概率5秒触发,80%概率20秒触发) - +在官方行为包中,该组件被广泛应用。例如: -```json +- 海豚在陆地超过20秒后会脱水 +- 蜜蜂在蜇人后10-60秒随机死亡 +- 流浪商人停留时间为2400秒或3600秒 + +基础示例(5.6秒后触发事件): + +::: code-group +```json [实体组件] "minecraft:timer": { "time": 5.6, "time_down_event": { @@ -46,31 +50,19 @@ A simple example which triggers an event after 5.6 seconds: } } ``` +::: -A more complex example which triggers an event after a randomized amount of delay using weighted values: +进阶示例(使用权重系统随机延时触发): - - -```json +::: code-group +```json [实体组件] "minecraft:timer": { - "looping": false, //true will fires event after every execution, false will fire event only once. + "looping": false, //true表示循环执行,false表示仅执行一次 "random_time_choices": [ - { - "weight": 25, - "value": 0.5 //Half a second of delay - }, - { - "weight": 25, - "value": 10 //Ten seconds of delay - }, - { - "weight": 25, - "value": 30 //Thirty seconds of delay - }, - { - "weight": 25, - "value": 120 //2 minutes of delay - } + {"weight":25, "value":0.5}, //0.5秒延时 + {"weight":25, "value":10}, //10秒延时 + {"weight":25, "value":30}, //30秒延时 + {"weight":25, "value":120} //2分钟延时 ], "time_down_event": { "event": "wiki:event", @@ -78,69 +70,59 @@ A more complex example which triggers an event after a randomized amount of dela } } ``` +::: -A particularly useful way to handle time events is using a single, looping `minecraft:timer` component and processing the events on each tick (or however often you decide to fire the timer). This is done by using the `randomize` parameter in events, where a weight may be used determine how often other events will be run. This can get you a lot of extra mileage out of a single timer component. +高效利用技巧:通过循环触发`minecraft:timer`,配合事件中的`randomize`参数实现多样效果。这里通过权重控制事件触发频率: - - -```json +::: code-group +```json [事件配置] "wiki:do_event": { "randomize": [ { - "weight": 1, - "add": { - "component_groups": [ - "wiki:my_event" - ] - } + "weight": 1, //1/56概率触发稀有事件 + "add": {"component_groups":["wiki:my_event"]} }, { - "weight": 5, - "add": { - "component_groups": [ - "wiki:my_more_frequent_event" - ] - } + "weight": 5, //5/56概率触发常见事件 + "add": {"component_groups":["wiki:my_more_frequent_event"]} }, { - "weight": 50 //Fires nothing + "weight": 50 //50/56概率无事件触发 } ] } ``` +::: -### minecraft:environment_sensor +### minecraft:environment_sensor组件 -Another component ([minecraft:environment_sensor](https://bedrock.dev/docs/stable/Entities#minecraft:environment_sensor)) which can be very useful for time-based events is `minecraft:environment_sensor`. Pairing this sensor with the `hourly_clock_time` or `clock_time` filters can be used to trigger events based off in-game time. +当结合`hourly_clock_time`或`clock_time`筛选器时,[minecraft:environment_sensor](https://bedrock.dev/docs/stable/Entities#minecraft:environment_sensor)可用于游戏内时间触发事件。 -Here is an example which is used to fire an event 800 ticks after the start of the day (valid range is 0 to 24000): +示例(每日开始800tick后触发事件): - - -```json +::: code-group +```json [实体组件] "minecraft:environment_sensor": { - "triggers": [ - { - "filters": { - "test": "hourly_clock_time", - "operator": "=", - "value": 800 - }, - "event": "wiki:my_daily_event" - } - ] + "triggers": [{ + "filters": { + "test": "hourly_clock_time", + "operator": "=", + "value": 800 + }, + "event": "wiki:my_daily_event" + }] } ``` +::: -### minecraft:ageable +### minecraft:ageable组件 -If this component ([minecraft:ageable](https://bedrock.dev/docs/stable/Entities#minecraft:ageable)) is not being used in the entity's behavior for a different purpose, it can be useful as an additional timer. It's important to note that it requires the `minecraft:is_baby` component to be defined in order to function. +当行为包未占用[miinecraft:ageable](https://bedrock.dev/docs/stable/Entities#minecraft:ageable)时,可配合`minecraft:is_baby`组件实现计时功能。 -Here is an example which fires an event after four seconds: +示例(4秒后触发事件): - - -```json +::: code-group +```json [实体组件] "minecraft:is_baby": {}, "minecraft:ageable": { "duration": 4, @@ -150,171 +132,138 @@ Here is an example which fires an event after four seconds: } } ``` +::: -### Other dummy-timers: +### 其他计时组件思路 -Taking a peak at the docs suggest there are other components which can also can be used for timing. Essentially, you are looking for any component with a "time down event" or a "duration". +查阅文档可发现更多具有"time_down_event"或"duration"参数的潜在组件,例如: -Non-exhaustive list of promising examples: +- `minecraft:angry`(需要攻击目标,时间限定整数) +- `minecraft.behavior.hide` +- `minecraft:behavior.celebrate` -- `minecraft:angry` (requires the entity to have a target, time must be an integer) -- `minecraft.behavior.hide` -- `minecraft:behavior.celebrate` +## 基于动画的计时器 -## Animation-based timers +行为包动画是实现定时事件的强力工具。其优势在于理论上可创造无限计时器,但存在重载实体时重置的局限(玩家退出世界或区块卸载后重新加载会重置计时器)。 -Behavior pack animations are an extremely powerful tool for triggering time-based events. They have the distinct advantage of providing an "infinite" amount of timers, but are restarted upon an entity being reloaded (leaving and rejoining the world or the chunk containing the entity unloading will cause the timer to restart when the entity reloads). +动画在行为包中的运作方式与资源包不同,建议通过官方文档或wiki其他页面了解基本机制。 -Animations function differently in behavior packs than in resource packs. If you are unfamiliar with how they operate, it is recommended to learn more about them by checking out the official documentation or the other pages on this wiki. +### 基础动画计时 -### Simple timers +通过动画控制器或直接执行时间线指令,可以实现精确时序触发: -By triggering animations from an animation controller or directly from the scripts section, you can execute specific events, commands, or molang expressions in a timed-sequence, called a timeline. - -You can set up timelines like this: - - - -```json +::: code-group +```json [动画定义] { "format_version": "1.8.0", "animations": { "animation.command.example_timeline": { "timeline": { - "0.0": "/say this will trigger instantly", - "3.0": "/say this will trigger after 3 seconds" + "0.0": "/say 立即触发", + "3.0": "/say 3秒后触发" }, "animation_length": 3.1 }, "animation.command.example_timeline_2": { "timeline": { - "100": "/say this will trigger after 100 seconds", + "100": "/say 100秒后触发", "0.0": [ - "/say you can trigger multiple events at once", - "/say by using timelines." + "/say 同时触发多个指令", + "/say 通过时间线组实现" ], - "55.55": "/say this will trigger after 55.55 seconds." + "55.55": "/say 55.55秒后触发" }, "animation_length": 100.1 } } } ``` +::: -### Random interval +### 随机间隔实现 -A very useful feature of the timer component is its ability to define a random interval in which the event will be triggered. This functionality can be replicated using animations and a controller. Below is an example of an animation triggered by adding the `minecraft:is_sheared` component to an entity which randomly fires an event between 2 to 7 seconds after activation. Animation and controller version 1.10.0. +通过动画控制器模拟`minecraft:timer`的随机区间功能。示例:实体被剪毛后2-7秒随机触发事件。 - - -```json +::: code-group +```json [动画控制器] "controller.animation.shanewolf.random_interval": { "initial_state": "inactive", "states": { "inactive": { - "transitions": [ - { - "active": "q.is_sheared" - } - ] + "transitions": [{"active": "q.is_sheared"}] }, "active": { "on_entry": [ "v.random_interval = math.random(2, 7);", - "/say random interval started" - ], - "animations": [ - "wiki:animate_interval" - ], - "transitions": [ - { - "inactive": "q.anim_time >= v.random_interval" - } + "/say 随机计时开始" ], + "animations": ["wiki:animate_interval"], + "transitions": [{ + "inactive": "q.anim_time >= v.random_interval" + }], "on_exit": [ "@s wiki:stop_random_interval", - "/say random interval finished" + "/say 随机计时结束" ] } } } ``` +::: - - -```json +::: code-group +```json [动画定义] "animation.shanewolf.random_interval": { "animation_length": 100 } ``` +::: -Explanation: Upon entry into the state beginning the animation, a variable is given a random value between 2 and 7. The animation finishes when the current animation time is greater than or equal to the value of this v. +实现逻辑:进入激活状态时生成2-7秒随机数变量,动画播放时间超过变量值时退出状态。 -**Notes**: -- The animation length can be set to any value greater than the maximum end of the time range (100 is used as a general template) -- math.random(a, b) is used to trigger an event in the range [a, b] -- math.floor(math.random(a, b.99)) may be used to end the timer at integer values (0.99 must be added to b) -- Any events or commands to run when the animation is finished are put inside on_exit +注意事项: +- 动画总时长需大于最大可能值 +- 使用`math.floor(math.random(a, b.99))`可生成整数结果 +- 收尾指令写入on_exit事件 -### Weighted random choice +### 权重选择实现 -Another useful feature of the timer component is its ability to trigger events at a time determined by a weighted list of values. This functionality can also be replicated using animations and a controller. Below is an example of an animation triggered by adding the `minecraft:is_charged` component to an entity which randomly fires an event at either 2, 5, or 9 seconds with weights of 30, 60, and 10, respectively. Animation and controller version 1.10.0. +通过动画控制器模拟权重时间选择功能。示例:带电实体30%概率2秒、60%概率5秒、10%概率9秒触发事件。 - - -```json +::: code-group +```json [动画控制器] "controller.animation.shanewolf.random_choices": { "initial_state": "inactive", "states": { "inactive": { - "transitions": [ - { - "active": "q.is_powered" - } - ] + "transitions": [{"active": "q.is_powered"}] }, "active": { "on_entry": [ "v.random_choices = math.random(0, 100);", - "/say random interval started" - ], - "animations": [ - "wiki:animate_choices" + "/say 随机选择开始" ], + "animations": ["wiki:animate_choices"], "transitions": [ - { - "inactive": "q.anim_time >= 2.0 && v.random_choices < 30" - }, - { - "inactive": "q.anim_time >= 5.0 && v.random_choices < 90" - }, - { - "inactive": "q.anim_time >= 9.0 && v.random_choices <= 100" - } + {"inactive": "q.anim_time >= 2.0 && v.random_choices < 30"}, + {"inactive": "q.anim_time >= 5.0 && v.random_choices < 90"}, + {"inactive": "q.anim_time >= 9.0 && v.random_choices <= 100"} ], "on_exit": [ "@s wiki:stop_random_choices", - "/say random choices finished" + "/say 随机选择结束" ] } } } ``` +::: - +实现逻辑:生成0-100随机数变量,通过多个状态切换条件实现权重分段检查。 -```json -"animation.shanewolf.random_choices": { - "animation_length": 100 -} -``` +注意事项: +- 时间段需从小到大排列 +- 通过权重累加值划分概率区间 +- 按规范处理收尾事件 -Explanation: Upon entry into the state beginning the animation, a variable is given a random value between 0 and 100 (sum of the weights). The transitions are laid out with the list of values ordered from the smallest time to the largest time. This is done so multiple && operators are not required in the latter transitions to define the variable's range (the query for the smallest times return true first and have their weights checked before the others--flipping 2 and 5 would result in 2 mistakenly having a weight of 90 instead of 30). The animation finishes when the current animation time is greater than or equal to a time in the list and the value of the random variable falls within that time's defined weight range. - -**Notes**: -- The animation length can be set to any value greater than the maximum end of the time range (100 is used as a general template) -- For this particular format to work, order the list of valid times from smallest to largest -- To assign a weight to a time in the list, add the weight to the value the randomized variable must be less than in the list's previous entry (e.g. 5 seconds has a weight of 90 - 30 = 60) -- Any events or commands to run when the animation is finished are put inside on_exit - -Hopefully this spread some light on the subject of handling time in Minecraft Bedrock! As shown above, there are many possible ways it can be done, each with their own pros and cons. If you have any other useful methods for creating time-based events, please [contribute to the wiki](/contribute)! +希望本指南能帮助你更好地掌握基岩版的时间管理技巧!如果你有其他巧妙的时间事件实现方法,欢迎[参与wiki编辑](/contribute)! \ No newline at end of file diff --git a/docs/wiki/3-实体/2-巧思案例/village-mechanic.md b/docs/wiki/3-实体/2-巧思案例/village-mechanic.md index 527268c2..08bdd95f 100644 --- a/docs/wiki/3-实体/2-巧思案例/village-mechanic.md +++ b/docs/wiki/3-实体/2-巧思案例/village-mechanic.md @@ -1,6 +1,6 @@ --- -title: Village Mechanic -category: Tutorials +title: 村庄机制 +category: 教程 mentions: - AeroForta - MedicalJewel105 @@ -11,15 +11,18 @@ mentions: - ThomasOrs --- -This article is for anyone who wants to try imitate the village mechanic for their entities +# 村庄机制 -## Navigation Behavior + -First let's start with some basic navigation behavior. +本文适用于想要为自定义实体实现村庄机制的开发者 -BP/entities/custom_villager.json#components +## 导航行为 -```json +首先从基本导航行为开始。 + +::: code-group +```json [BP/entities/custom_villager.json#components] "minecraft:preferred_path":{ "max_fall_blocks":1, "jump_cost":5, @@ -48,12 +51,12 @@ First let's start with some basic navigation behavior. ] } ``` +::: -Allows entity to do random walk. +允许实体进行随机移动。 -BP/entities/custom_villager.json#components - -```json +::: code-group +```json [BP/entities/custom_villager.json#components] "minecraft:behavior.random_stroll":{ "priority":9, "speed_multiplier":0.55, @@ -61,83 +64,83 @@ Allows entity to do random walk. "y_dist":5 } ``` +::: -Make entity return to inside dwelling bound, in this case inside a village border. Requiring minecraft:dweller component that will be explained below. +使实体返回居所范围(在此案例中即村庄边界)。需要下文将解释的`minecraft:dweller`组件。 -BP/entities/custom_villager.json#components - -```json +::: code-group +```json [BP/entities/custom_villager.json#components] "minecraft:behavior.move_towards_dwelling_restriction": { "priority": 4, "speed_multiplier": 1.0 } ``` +::: -Makes entity navigate around a village by creating a path to patrol. Used by Iron Golem. +通过创建巡逻路径让实体在村庄周围移动。铁傀儡使用的机制。 -BP/entities/custom_villager.json#components - -```json +::: code-group +```json [BP/entities/custom_villager.json#components] "minecraft:behavior.move_through_village": { "priority": 3, "speed_multiplier": 0.6, "only_at_night": true } ``` +::: -Allows entity to enter a building and also take shelter when raining. Needs open door capabilities. +允许实体进入建筑物并在下雨时寻找庇护所。需要开门能力。 -BP/entities/custom_villager.json#components - -```json +::: code-group +```json [BP/entities/custom_villager.json#components] "minecraft:behavior.move_indoors":{ "priority":5 } ``` +::: -Makes entity stay indoors while sun is down. +使实体在日落时留在室内。 -BP/entities/custom_villager.json#components - -```json +::: code-group +```json [BP/entities/custom_villager.json#components] "minecraft:behavior.restrict_open_door":{ "priority": 5 } ``` +::: -Use in pair with: +需搭配使用: -BP/entities/custom_villager.json#components - -```json +::: code-group +```json [BP/entities/custom_villager.json#components] "minecraft:annotation.open_door":{ "priority": 5 } ``` +::: -BP/entities/custom_villager.json#components - -```json +::: code-group +```json [BP/entities/custom_villager.json#components] "minecraft:navigation.walk":{ "can_pass_doors":true, "can_open_doors":true } ``` +::: -BP/entities/custom_villager.json#components - -```json +::: code-group +```json [BP/entities/custom_villager.json#components] "minecraft:behavior.open_door":{ "priority":6, "close_door_after":true } ``` +::: -## Main Behavior +## 核心行为 -BP/entities/custom_villager.json#components - -```json +::: code-group +```json [BP/entities/custom_villager.json#components] "minecraft:dweller": { "dwelling_type": "village", "dweller_role": "inhabitant", @@ -149,36 +152,34 @@ Use in pair with: "first_founding_reward": 5 } ``` +::: -- `dweller_role: inhabitant` -Allows entity claim a bed and bell. -`minecraft:behavior.sleep` needed. -- `preferred_profession: farmer` -Optional for `minecraft:behavior.work` -- `can_find_poi` -Add it so entity is able to find point of interest. -Known POI types: +- `dweller_role: inhabitant`\ +允许实体认领床和钟,需搭配`minecraft:behavior.sleep`。 +- `preferred_profession: farmer`\ +为`minecraft:behavior.work`的可选参数 +- `can_find_poi`\ +启用后实体可寻找兴趣点。已知兴趣点类型: ``` -bed -jobsite -meeting_area +bed // 床 +jobsite // 工作站点 +meeting_area // 聚集点 ``` -- `can_migrate` -Defines if entity can migrate from one village to another or not. +- `can_migrate`\ +定义实体是否能在不同村庄间迁移 -### Sleep +### 睡眠行为 -You can find out how to make your entity sleep [here](/entities/sleeping-entities). +可参考[睡眠实体指南](/entities/sleeping-entities)实现实体睡眠 -### Work +### 工作行为 -Requires "dweller_role" set to be "inhabitant" also if "preferred_profession" doesn't exist the entity will try to move to the closest any job site. +需要设置"dweller_role"为"inhabitant",若未设置"preferred_profession"则实体将移动到最近的工作站点。 - - -```json +::: code-group +```json [空值] "minecraft:behavior.work": { "priority": 4, "active_time": 250, @@ -194,12 +195,12 @@ Requires "dweller_role" set to be "inhabitant" also if "preferred_profession" do } } ``` +::: +### 社交行为 -### Gathering - -Allows the entity to gather. -Requires "dweller_role" set to be "inhabitant". +允许实体进行社交活动。 +需要设置"dweller_role"为"inhabitant"。 ```json "minecraft:behavior.mingle": { @@ -212,16 +213,14 @@ Requires "dweller_role" set to be "inhabitant". } ``` +## 日程系统 -### Scheduler +现在将所有机制整合到"minecraft:scheduler"中。 +首先创建简单配置。 +将工作行为放入组件组: -Now you know everything about needed mechanic, let's try to put all of this together in "minecraft:scheduler" -First let's do something simple. -Put work behavior in component group work like this: - - - -```json +::: code-group +```json [空值] "component_groups":{ "work_schedule":{ "minecraft:behavior.work":{ @@ -251,12 +250,12 @@ Put work behavior in component group work like this: } } ``` +::: -Next, make your entity work. +配置工作日程: - - -```json +::: code-group +```json [空值] "minecraft:scheduler":{ "min_delay_secs":0, "max_delay_secs":10, @@ -267,12 +266,12 @@ Next, make your entity work. { "test":"hourly_clock_time", "operator":">=", - "value":0 //Morning + "value":0 // 早晨 }, { "test":"hourly_clock_time", "operator":"<", - "value":12000 //Evening + "value":12000 // 傍晚 } ] }, @@ -298,12 +297,12 @@ Next, make your entity work. ] } ``` +::: -The events section looks something like this: +事件部分配置示例: - - -```json +::: code-group +```json [空值] "events":{ "work":{ "remove":{ @@ -331,27 +330,28 @@ The events section looks something like this: } } ``` +::: -Open your world, spawn entity then put a bed and you should see green particle. +进入游戏生成实体后放置床,应可见绿色粒子效果。 -## Other Behavior +## 其他行为 -All of this is usable by custom entities: -- `minecraft:behavior.move_to_village` -Used by Pillager this may keep the entity to stay in the village. -- `minecraft:behavior.stroll_towards_village` -Used by fox to search a village and go there. -- `minecraft:behavior.inspect_bookshelf` -Used by librarian villager allows an entity to look at and inspect a bookshelf. -- `minecraft:behavior.explore_outskirts` -Allows entity to explore beyond the bounds of village (use schedule and component group to keep the entity return to the village). -- `minecraft:behavior.defend_village_target` -Use this on melee attack. Ranged attack can accidentally shoot any entity with inhabitant dwelling role. +以下行为可供自定义实体使用: +- `minecraft:behavior.move_to_village`\ +劫掠者使用该机制来留在村庄 +- `minecraft:behavior.stroll_towards_village`\ +狐狸使用该机制寻找并前往村庄 +- `minecraft:behavior.inspect_bookshelf`\ +管理员村民用于查看书架 +- `minecraft:behavior.explore_outskirts`\ +允许实体在村庄外探索(需搭配日程系统组件组保证返回) +- `minecraft:behavior.defend_village_target`\ +用于近战攻击。远程攻击可能误伤具有"inhabitant" role的实体 -All of this can be used by custom entities and have relation to villager or village: -| Behavior | Uses | Note | -| ------------------------------------------ | -------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | -| `minecraft:behavior.defend_village_target` | Allows entity to attack other entity that hurt the entity who had "dweller_role": "inhabitant". | Recommended to use only on entities with melee attack. | -| `minecraft:behavior.hide` | Used by villager to hide and stay at defined POI. | Currently, there is no documentation for the POI type that's why I recommend not to change `"poi_type": "bed"`. | -| `minecraft:behavior.move_to_village` | Used by Illager and also witch. Allows entity to travel to a random x,y,z coordinate in a village. | - | -| `"minecraft:behavior.nap"` | Used by Fox to take a nap. | Similar with sleep but offers more flexibility also has built-in wake up system by detecting specific entity. | +可用行为对照表: +| 行为名称 | 用途 | 备注 | +| ----------------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | +| `minecraft:behavior.defend_village_target` | 允许实体攻击伤害村民的敌人 | 建议仅用于近战攻击型实体 | +| `minecraft:behavior.hide` | 村民用于在特定POI隐藏停留 | 当前POI类型文档不完整,建议保持`"poi_type": "bed"` | +| `minecraft:behavior.move_to_village` | 劫掠者和女巫用于在村庄范围内随机移动 | - | +| `minecraft:behavior.nap` | 狐狸用于小憩 | 类似睡眠但更灵活,内置感知特定实体自动唤醒系统 | \ No newline at end of file diff --git a/docs/wiki/3-实体/3-文档/vanilla-usage-components.md b/docs/wiki/3-实体/3-文档/vanilla-usage-components.md index b91888b9..58b613d4 100644 --- a/docs/wiki/3-实体/3-文档/vanilla-usage-components.md +++ b/docs/wiki/3-实体/3-文档/vanilla-usage-components.md @@ -1,11 +1,11 @@ --- -title: Vanilla 可用 Components +title: 所有可用 Components category: Documentation mentions: - MedicalJewel105 --- -# Vanilla 可用 Components +# 所有可用 Components diff --git a/docs/wiki/3-实体/3-文档/vanilla-usage-spawn-rules.md b/docs/wiki/3-实体/3-文档/vanilla-usage-spawn-rules.md index a7cdbf33..ab431d09 100644 --- a/docs/wiki/3-实体/3-文档/vanilla-usage-spawn-rules.md +++ b/docs/wiki/3-实体/3-文档/vanilla-usage-spawn-rules.md @@ -1,11 +1,11 @@ --- -title: Vanilla 可用生成规则(Spawn Rules) +title: 所有可用生成规则(Spawn Rules) category: Documentation mentions: - MedicalJewel105 --- -# Vanilla 可用生成规则(Spawn Rules) +# 所有可用生成规则(Spawn Rules) diff --git a/docs/wiki/3-实体/3-文档/vuc-full.md b/docs/wiki/3-实体/3-文档/vuc-full.md index 9cd638e6..fef775df 100644 --- a/docs/wiki/3-实体/3-文档/vuc-full.md +++ b/docs/wiki/3-实体/3-文档/vuc-full.md @@ -1,12 +1,12 @@ --- -title: Vanilla 可用 Components - 完整 +title: 所有可用 Components - 完整 category: Documentation mentions: - MedicalJewel105 hidden: true --- -# Vanilla 可用 Components - 完整 +# 所有可用 Components - 完整 diff --git a/docs/wiki/3-实体/3-文档/vusr-full.md b/docs/wiki/3-实体/3-文档/vusr-full.md index 24b154b3..d946fca6 100644 --- a/docs/wiki/3-实体/3-文档/vusr-full.md +++ b/docs/wiki/3-实体/3-文档/vusr-full.md @@ -1,12 +1,12 @@ --- -title: Vanilla 可用 Spawn Rules - 完整 +title: 所有可用 Spawn Rules - 完整 category: Documentation mentions: - MedicalJewel105 hidden: true --- -# Vanilla 可用 Spawn Rules - 完整 +# 所有可用 Spawn Rules - 完整 diff --git a/docs/wiki/4-Json-UI/1-基础/json-ui-intro.md b/docs/wiki/4-Json-UI/1-基础/json-ui-intro.md index eb8a3b4d..fccccfef 100644 --- a/docs/wiki/4-Json-UI/1-基础/json-ui-intro.md +++ b/docs/wiki/4-Json-UI/1-基础/json-ui-intro.md @@ -306,11 +306,13 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 ``` ::: +当更改时,派生元素的任何属性都将被完全覆盖。 + ## 数据绑定 -通过 `bindings` 实现数据源与元素的动态关联。 +绑定机制用于将硬编码值与界面元素关联,并在处理元素时使用这些值。以下是一个使用硬编码文本的标签示例: -### 简单绑定 +`text`属性值设定为`#hardtext`。通过`bindings`配置,我们可以获取硬编码变量`#hardtext`的值,使`text`属性能够正确调用。这种配置直接将`#hardtext`的值赋给`text`属性。 ::: code-group ```json [vanilla/ui/example_file.json] @@ -328,18 +330,18 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 ``` ::: -### 重定向绑定 +另一种常见的配置形式如下: ::: code-group ```json [vanilla/ui/example_file.json] { "label": { "type": "label", - "text": "#display_text", + "text": "#text", "bindings": [ { - "binding_name": "#source_data", - "binding_name_override": "#display_text" + "binding_name": "#hardtext", + "binding_name_override": "#text" } ] } @@ -347,18 +349,27 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 ``` ::: -### 跨元素绑定 +此时,`#hardtext`的值会被赋给`#text`绑定属性,进而传递给`text`属性。 + +这种机制在`visible`(可见性)和`enabled`(启用状态)属性中尤为常见。以下是一个组合示例: ::: code-group ```json { - "status_panel": { + "send_button": { "bindings": [ { - "binding_type": "view", - "source_control_name": "my_toggle", - "source_property_name": "#state", - "target_property_name": "#visible" + "binding_name": "#using_touch", + "binding_name_override": "#visible" + } + ] + }, + + "play_button": { + "bindings": [ + { + "binding_name": "#play_button_enabled", + "binding_name_override": "#enabled" } ] } @@ -366,117 +377,70 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 ``` ::: -## 条件渲染 +此处的`#using_touch`和`#play_button_enabled`存储布尔值。当使用触控设备时,`#using_touch`为`true`,否则为`false`。`#play_button_enabled`用于「添加外部服务器」界面,当所有文本字段(服务器名称、IP地址和端口号)均有内容时才会设为`true`。
+因此,`#using_touch`的值会覆盖`#visible`绑定属性(该属性通常通过`property_bag`设置,等同于直接设置`visible`属性),同理`#play_button_enabled`会覆盖`#enabled`的值。 -通过变量和绑定实现动态显示控制。 - -### 变量条件 +当需要根据开关状态显示特定面板时,需使用另一种绑定结构。这种配置需要指定数据源元素、源属性及目标属性: ::: code-group -```json [vanilla/ui/hud_screen.json] +```json { - "hud_actionbar_text/actionbar_message": { - "$atext": "$actionbar_text", - "visible": "(not ($atext = 'hello world'))" - } -} -``` -::: - -### 工厂条件 - -::: code-group -```json [vanilla/ui/hud_screen.json] -{ - "conditional_image": { - "type": "image", - "texture": "textures/ui/Black", - "$atext": "$actionbar_text", - "visible": "($atext = 'show_image')" + "panel": { + ... + "bindings": [ + { + "binding_type": "view", + "source_control_name": "my_toggle", // 源元素名称 + "source_property_name": "#toggle_state", // 需要获取的开关状态属性 + "target_property_name": "#visible" // 待覆盖的目标属性 + } + ] }, - "image_factory": { - "type": "panel", - "factory": { - "name": "hud_actionbar_text_factory", - "control_ids": { - "hud_actionbar_text": "conditional_image@hud.conditional_image" - } - } + "my_toggle": { + ... } } ``` ::: -通过结合操作符系统,可实现复杂的条件逻辑判断,为界面交互提供灵活的控制能力。 +当开关被勾选时,`#toggle_state`会变为`1`或`true`,从而将元素的`visible`属性设为可见。取消勾选时,该值变为`0`或`false`,再次覆盖`visible`属性值。 -::: code-group -```json [vanilla/ui/hud_screen.json] -``` +## 条件性渲染 + +在标准属性体系下,通过屏幕显示状态控制基岩版UI系统具有挑战性。然而变量(variables)和绑定(bindings)在JSON UI中具有特殊地位,因为它们承载着来自基岩引擎的实时数据。通过巧妙的UI技巧组合,开发者可以完全控制UI元素的渲染条件。这些方法分为两大类:基于变量的条件渲染和基于绑定的条件渲染。 + +:::warning ⚠️ 注意 +本示例适用于国际版的受限制的 JSON UI 系统(客户端无法实现脚本控制)
+对中国版来说,不需要这种复杂的黑科技实现HUD元素的可见性控制。
+但是也能因此学习到数据绑定的使用方法,何尝不是一种收获呢? ::: -### 使用绑定的条件渲染 +### 变量条件渲染 -根据上文提到的操作栏示例,你可能会认为标题也使用变量。但实际情况并非如此。标题使用绑定(bindings)来获取数据,如下所示。 +变量可用于实现条件性UI渲染。UI变量是指前缀带`$`的特殊属性,例如`hud_screen.json`中的`$actionbar_text`就承载着引擎数据。观察`hud_actionbar_text`控件可知,该变量用于显示动作栏文本。 ::: code-group ```json [vanilla/ui/hud_screen.json] { ... - "hud_title_text": { - "type": "stack_panel", - "orientation": "vertical", // 垂直排列 - "offset": [ 0, -19 ], // 位置偏移 - "layer": 1, // 渲染层级 - "alpha": "@hud.anim_title_text_alpha_in", // 透明度动画 - "propagate_alpha": true, // 透明度继承 - "controls": [ // 子控件集合 + "hud_actionbar_text": { + "type": "image", + "size": [ "100%c + 12px", "100%c + 5px" ], + "offset": [ 0, "50%-68px" ], + "texture": "textures/ui/hud_tip_text_background", + "alpha": "@hud.anim_actionbar_text_background_alpha_out", + "controls": [ { - "title_frame": { - "type": "panel", // 面板类型 - "size": [ "100%", "100%cm" ], // 尺寸设置 - "controls": [ - { - "title_background": { - "type": "image", // 图像类型 - "size": [ "100%sm + 30px", "100%sm + 6px" ], // 动态尺寸计算 - "texture": "textures/ui/hud_tip_text_background", // 纹理路径 - "alpha": "@hud.anim_title_background_alpha_in" // 背景透明度动画 - } - }, - { - "title": { - "type": "label", // 文本标签类型 - "anchor_from": "top_middle", // 锚点起始位置 - "anchor_to": "top_middle", // 锚点目标位置 - "color": "$title_command_text_color", // 文字颜色变量 - "text": "#text", // 文本内容绑定 - "layer": 1, // 渲染层级 - "localize": false, // 关闭本地化 - "font_size": "extra_large", // 超大字号 - "variables": [ // 条件变量组 - { - "requires": "(not $title_shadow)", // 无阴影条件 - "$show_shadow": false // 关闭阴影显示 - }, - { - "requires": "$title_shadow", // 启用阴影条件 - "$show_shadow": true // 启用阴影显示 - } - ], - "shadow": "$show_shadow", // 阴影状态绑定 - "text_alignment": "center", // 文本居中 - "offset": [ 0, 6 ], // 位置微调 - "bindings": [ // 数据绑定组 - { - "binding_name": "#hud_title_text_string", // 原始绑定名 - "binding_name_override": "#text", // 覆盖目标属性 - "binding_type": "global" // 全局绑定类型 - } - ] - } - } - ] + "actionbar_message": { + "type": "label", + "anchor_from": "center", + "anchor_to": "center", + "color": "$tool_tip_text", + "layer": 1, + "text": "$actionbar_text", + "localize": false, + "alpha": "@hud.anim_actionbar_text_alpha_out" } } ] @@ -486,7 +450,100 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 ``` ::: -我们需要在文本组件中添加另一个绑定对象来控制可见性。注意`#visible`属性会通过绑定直接控制元素可见性。以下示例将不会渲染"hello world"标题,但会显示其他所有标题。可在游戏中输入`/title @s title hello world`观察效果。 +通过`visible`属性可实现基于引擎变量的条件渲染。以下示例复制了`$actionbar_text`变量以便进行修改和比较(原始变量无法直接操作)。新建的`$atext`变量用于控制`visible`属性,其逻辑是"当动作栏文本不等于`hello world`时显示文本标签"。 + +::: code-group +```json [vanilla/ui/hud_screen.json] +{ +... + "hud_actionbar_text": { + "type": "image", + "size": ["100%c + 12px", "100%c + 5px"], + "offset": [0, "50%-68px"], + "texture": "textures/ui/hud_tip_text_background", + "alpha": "@hud.anim_actionbar_text_background_alpha_out", + "controls": [ + { + "actionbar_message": { + "type": "label", + "anchor_from": "center", + "anchor_to": "center", + "color": "$tool_tip_text", + "layer": 1, + "text": "$actionbar_text", + "localize": false, + "alpha": "@hud.anim_actionbar_text_alpha_out", + // 当动作栏文本等于"hello world"时忽略该文本标签 + "$atext": "$actionbar_text", + "visible": "(非 ($atext = 'hello world'))" + } + } + ] + } +... +} +``` +::: + +将此JSON转换为资源包使用的非侵入式UI文件应如下所示: + +::: code-group +```json [vanilla/ui/hud_screen.json] +{ + "hud_actionbar_text/actionbar_message": { + "$atext": "$actionbar_text", + "visible": "(非 ($atext = 'hello world'))" + } +} +``` +::: + +在启用资源包的世界中执行`/title @s actionbar hello world`时,动作栏将不会显示信息。其他动作栏指令仍可正常显示。若需要同时隐藏文本背景,可移除`/actionbar_message`节点。由于背景元素`hud_actionbar_text`被隐藏时,其子元素也会连带隐藏。 + +下面展示更复杂的变量条件渲染示例。此处需要使用动作栏工厂(actionbar factory)。工厂是元素生成器,其中`hud_actionbar_text_factory`等具有硬编码属性。该工厂在每次执行动作栏指令时重置其`control_id`内的元素,并传递`$actionbar_text`等特殊变量,这些数据只能通过工厂获取。 + +::: code-group +```json [vanilla/ui/hud_screen.json] +{ + "black_conditional_image": { + "type": "image", + "texture": "textures/ui/Black", + "size": [16, 16], + "layer": 10, + "$atext": "$actionbar_text", + "visible": "($atext = 'hello world')" + }, + + "black_conditional_image_factory": { + "type": "panel", + "factory": { + "name": "hud_actionbar_text_factory", + "control_ids": { + "hud_actionbar_text": "black_conditional_image@hud.black_conditional_image" + } + } + }, + + "root_panel": { + "modifications": [ + { + "array_name": "controls", + "operation": "insert_front", + "value": { + "black_conditional_image_factory@hud.black_conditional_image_factory": {} + } + } + ] + } +} +``` +::: + +当动作栏文本等于`hello world`时,此示例会在HUD界面显示16x16黑色方块。开发者可为图像添加动画增强表现力。变量条件渲染不仅限于图像和文本,任何UI对象类型均可应用。结合动作栏文本的UI代码可实现高度定制化(至少在`hud_screen.json`中)。`visible`属性支持UI运算符,提供更精细的控制。任何承载引擎数据的变量都支持变量条件渲染。 + +### 绑定条件渲染 + +观察标题系统(title)时,可能误以为其使用变量系统。实际上标题系统采用绑定机制获取数据,如下所示: ::: code-group ```json [vanilla/ui/hud_screen.json] @@ -525,7 +582,76 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 "font_size": "extra_large", "variables": [ { - "requires": "(not $title_shadow)", + "requires": "(非 $title_shadow)", + "$show_shadow": false + }, + { + "requires": "$title_shadow", + "$show_shadow": true + } + ], + "shadow": "$show_shadow", + "text_alignment": "center", + "offset": [ 0, 6 ], + "bindings": [ + { + "binding_name": "#hud_title_text_string", + "binding_name_override": "#text", + "binding_type": "global" + } + ] + } + } + ] + } + } + ] + } +... +} +``` +::: + +通过添加绑定对象控制可见性。`#visible`属性直接反映元素的可见状态。以下示例将隐藏`hello world`标题文本,其他文本正常显示。游戏中可执行`/title @s title hello world`验证效果。 + +::: code-group +```json [vanilla/ui/hud_screen.json] +{ +... + "hud_title_text": { + "type": "stack_panel", + "orientation": "vertical", + "offset": [ 0, -19 ], + "layer": 1, + "alpha": "@hud.anim_title_text_alpha_in", + "propagate_alpha": true, + "controls": [ + { + "title_frame": { + "type": "panel", + "size": [ "100%", "100%cm" ], + "controls": [ + { + "title_background": { + "type": "image", + "size": [ "100%sm + 30px", "100%sm + 6px" ], + "texture": "textures/ui/hud_tip_text_background", + "alpha": "@hud.anim_title_background_alpha_in" + } + }, + { + "title": { + "type": "label", + "anchor_from": "top_middle", + "anchor_to": "top_middle", + "color": "$title_command_text_color", + "text": "#text", + "layer": 1, + "localize": false, + "font_size": "extra_large", + "variables": [ + { + "requires": "(非 $title_shadow)", "$show_shadow": false }, { @@ -543,9 +669,9 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 "binding_type": "global" }, { - "binding_type": "view", // 将此设为视图绑定 - "source_property_name": "(not (#text = 'hello world'))", // 当标题文本不等于"hello world"时触发 - "target_property_name": "#visible" // 根据条件覆盖可见性属性 + "binding_type": "view", // 转换为视图绑定 + "source_property_name": "(非 (#text = 'hello world'))", // 检测标题文本是否不等于"hello world" + "target_property_name": "#visible" // 根据检测结果覆盖可见性属性 } ] } @@ -560,7 +686,7 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 ``` ::: -在资源包中使用非侵入式UI文件修改时,应保持如下格式: +转换为资源包文件时应如下配置: ::: code-group ```json [RP/ui/hud_screen.json] @@ -568,11 +694,11 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 "hud_title_text/title_frame/title": { "modifications": [ { - "array_name": "bindings", // 目标数组名 - "operation": "insert_back", // 末尾插入操作 - "value": { // 新增绑定对象 + "array_name": "bindings", + "operation": "insert_back", + "value": { "binding_type": "view", - "source_property_name": "(not (#text = 'hello world'))", + "source_property_name": "(非 (#text = 'hello world'))", "target_property_name": "#visible" } } @@ -582,24 +708,24 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 ``` ::: -下面是一个更复杂的条件渲染示例。16x16的黑色图片仅在标题文本等于"hello world"时显示。虽然在此案例中不需要使用标题工厂(title factory),但如需使用UI动画则建议采用。 +下方是更复杂的绑定条件渲染示例。当标题文本等于`hello world`时显示16x16黑色图像。虽然不强制要求使用标题工厂,但若涉及UI动画则推荐使用。 ::: code-group ```json [RP/ui/hud_screen.json] { "black_conditional_image": { "type": "image", - "texture": "textures/ui/Black", // 黑色纹理 - "size": [16, 16], // 固定尺寸 - "layer": 10, // 较高渲染层级 + "texture": "textures/ui/Black", + "size": [16, 16], + "layer": 10, "bindings": [ { - "binding_name": "#hud_title_text_string" // 标题文本绑定 + "binding_name": "#hud_title_text_string" }, { "binding_type": "view", - "source_property_name": "(#hud_title_text_string = 'hello world')", // 条件判断 - "target_property_name": "#visible" // 可见性控制 + "source_property_name": "(#hud_title_text_string = 'hello world')", + "target_property_name": "#visible" } ] }, @@ -607,9 +733,9 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 "black_conditional_image_factory": { "type": "panel", "factory": { - "name": "hud_title_text_factory", // 使用标题工厂 + "name": "hud_title_text_factory", "control_ids": { - "hud_title_text": "black_conditional_image@hud.black_conditional_image" // 控件ID映射 + "hud_title_text": "black_conditional_image@hud.black_conditional_image" } } }, @@ -617,10 +743,10 @@ UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名 "root_panel": { "modifications": [ { - "array_name": "controls", // 根面板控件数组 - "operation": "insert_front", // 前置插入 + "array_name": "controls", + "operation": "insert_front", "value": { - "black_conditional_image_factory@hud.black_conditional_image_factory": {} // 工厂实例 + "black_conditional_image_factory@hud.black_conditional_image_factory": {} } } ] diff --git a/docs/wiki/4-Json-UI/2-巧思案例/add-hud-elements.md b/docs/wiki/4-Json-UI/2-巧思案例/add-hud-elements.md index 8ebaabdb..72601368 100644 --- a/docs/wiki/4-Json-UI/2-巧思案例/add-hud-elements.md +++ b/docs/wiki/4-Json-UI/2-巧思案例/add-hud-elements.md @@ -12,6 +12,11 @@ mentions: +:::warning ⚠️ 注意 +本教程仅适用于国际版的受限制的 JSON UI 系统(客户端无法实现脚本控制)
+中国版无需使用此黑科技实现HUD元素新增。 +::: + 在本教程中,你将学习如何向HUD界面添加元素。 ## 概述 diff --git a/docs/wiki/4-Json-UI/2-巧思案例/aseprite-animations.md b/docs/wiki/4-Json-UI/2-巧思案例/aseprite-animations.md index cc7cd70e..5cdda263 100644 --- a/docs/wiki/4-Json-UI/2-巧思案例/aseprite-animations.md +++ b/docs/wiki/4-Json-UI/2-巧思案例/aseprite-animations.md @@ -1,5 +1,5 @@ --- -title: Aseprite动画 +title: 序列帧动画 category: 教程 mentions: - TheDataLioness @@ -9,7 +9,7 @@ mentions: - stirante --- -# Aseprite动画 +# 序列帧动画(Aseprite) diff --git a/docs/wiki/4-Json-UI/2-巧思案例/preserve-title-texts.md b/docs/wiki/4-Json-UI/2-巧思案例/preserve-title-texts.md index a0d71c3e..67cb5f11 100644 --- a/docs/wiki/4-Json-UI/2-巧思案例/preserve-title-texts.md +++ b/docs/wiki/4-Json-UI/2-巧思案例/preserve-title-texts.md @@ -1,5 +1,5 @@ --- -title: 保留标题文本 +title: Title传递HUD元素更新 category: 教程分类 tags: - 中级 @@ -8,26 +8,31 @@ mentions: - SmokeyStack --- -# 保留标题文本 +# 通过 Title 传递 HUD 元素更新 -在本教程中,您将学习如何保存绑定数据并根据含有特定字符串的标题更新界面元素。 +:::warning ⚠️ 注意 +本教程仅适用于国际版的受限制的 JSON UI 系统(客户端无法实现脚本控制)
+中国版无需使用此黑科技实现HUD元素的更新。 +::: + +在本教程中,您将学习如何保存绑定数据并根据含有特定字符串的 Title 更新界面元素。 ## 概述 -标题是向UI系统传递数据的常用方法。当标题包含特定字符串时才更新相关数据元素,而忽略所有不含该字符串的标题数据非常有用。尽管本教程以标题为例,但该方法适用于所有通过绑定传递的数据(如副标题、玩家记分板名称等)。 +Title 是向UI系统传递数据的常用方法。当 Title 包含特定字符串时才更新相关数据元素,而忽略所有不含该字符串的 Title 数据非常有用。尽管本教程以 Title 为例,但该方法适用于所有通过绑定传递的数据(如副 Title 、玩家记分板名称等)。 要保存特定字符串,我们需要组合使用 `visibility_changed` 绑定更新条件和 `source_control_name`,从而仅在包含特定字符串时更新绑定,并将该绑定传递给另一个元素。 -## 标题指令 +## Title 指令 -以下代码创建了一个标签元素,当将其添加到根面板时,可以在屏幕显示包含字符串"update"的标题(显示文本中会移除"update"部分)。后续传入的标题信息只有包含"update"时才会更新显示文本。 +以下代码创建了一个标签元素,当将其添加到根面板时,可以在屏幕显示包含字符串"update"的 Title (显示文本中会移除"update"部分)。后续传入的 Title 信息只有包含"update"时才会更新显示文本。 ::: code-group ```json [RP/ui/hud_screen.json] "preserved_title_display": { - "$update_string": "update", // 标题必须包含此字符串才触发元素更新 + "$update_string": "update", // Title 必须包含此字符串才触发元素更新 "type": "label", "text": "#text", "controls": [ @@ -37,14 +42,14 @@ mentions: "size": [ 0, 0 ], "bindings": [ { - "binding_name": "#hud_title_text_string" // 读取当前标题字符串 + "binding_name": "#hud_title_text_string" // 读取当前 Title 字符串 }, { "binding_name": "#hud_title_text_string", "binding_name_override": "#preserved_text", // 元素可见性变化时更新#preserved_text "binding_condition": "visibility_changed" }, - // 当包含更新字符的标题传入后,元素会短暂可见后立即隐藏 + // 当包含更新字符的 Title 传入后,元素会短暂可见后立即隐藏 { "binding_type": "view", "source_property_name": "(not (#hud_title_text_string = #preserved_text) and not ((#hud_title_text_string - $update_string) = #hud_title_text_string))", @@ -66,13 +71,13 @@ mentions: }, ``` -变量 `$update_string` 定义了触发元素更新的标题必须包含的特定字符串。子元素 `data_control` 用于在标题包含更新字符串时存储标题文本。`data_control` 必须是要传递保留文本元素的子级或同级元素,因为其可见性变化会触发文本保存。该元素的三个绑定分别实现: -1. 首绑定:持续追踪当前标题文本 -2. 次绑定:在元素可见性变化时将当前标题保存至 `#preserved_text` -3. 末绑定:当传入含更新字符串的标题时短暂显示元素后立即隐藏 +变量 `$update_string` 定义了触发元素更新的 Title 必须包含的特定字符串。子元素 `data_control` 用于在 Title 包含更新字符串时存储 Title 文本。`data_control` 必须是要传递保留文本元素的子级或同级元素,因为其可见性变化会触发文本保存。该元素的三个绑定分别实现: +1. 首绑定:持续追踪当前 Title 文本 +2. 次绑定:在元素可见性变化时将当前 Title 保存至 `#preserved_text` +3. 末绑定:当传入含更新字符串的 Title 时短暂显示元素后立即隐藏 在 `data_control` 元素的第三个绑定中,需同时满足两个条件才可见: -1. `not (#hud_title_text_string = #preserved_text)` - 当前标题与保存标题不一致时成立 -2. `not ((#hud_title_text_string - $update_string)` - 当前标题含有更新字符串时成立 +1. `not (#hud_title_text_string = #preserved_text)` - 当前 Title 与保存 Title 不一致时成立 +2. `not ((#hud_title_text_string - $update_string)` - 当前 Title 含有更新字符串时成立 -当含有更新字符串且与已存文本不同的标题传入时,两条件同时触发,元素更新数据后立即重新隐藏自身。 \ No newline at end of file +当含有更新字符串且与已存文本不同的 Title 传入时,两条件同时触发,元素更新数据后立即重新隐藏自身。 \ No newline at end of file diff --git a/docs/wiki/4-Json-UI/3-文档/json-ui-documentation.md b/docs/wiki/4-Json-UI/3-文档/json-ui-documentation.md index ceb888de..92cc91d9 100644 --- a/docs/wiki/4-Json-UI/3-文档/json-ui-documentation.md +++ b/docs/wiki/4-Json-UI/3-文档/json-ui-documentation.md @@ -1,5 +1,5 @@ --- -title: JSON UI Documentation +title: JSON UI 完整文档 category: Documentation nav_order: 1 mentions: @@ -23,43 +23,55 @@ mentions: - Gotemba912 --- -# JSON UI Documentation +# JSON UI 完整文档 -## UI Elements +## UI元素 -### Element Types +### 元素类型 -| Name | Description | Allowed Properties | -| ---------------- | ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| panel | A container, like `
` in HTML | [Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| stack_panel | Similar to `panel` but stacks its children depending on `orientation` property value | [Stack Panel](/json-ui/json-ui-documentation#stack-panel)
[Collection](/json-ui/json-ui-documentation#collection)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| collection_panel | Similar to `stack_panel`, but does not have the `orientation` property | [Collection](/json-ui/json-ui-documentation#collection)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| grid | Grid of elements | [Grid](/json-ui/json-ui-documentation#grid)
[Collection](/json-ui/json-ui-documentation#collection)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| label | Text element | [Text](/json-ui/json-ui-documentation#text)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| image | Sprite element. Draws a texture. | [Sprite](/json-ui/json-ui-documentation#sprite)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| input_panel | A `panel` that accepts input | [Input](/json-ui/json-ui-documentation#input)
[Focus](/json-ui/json-ui-documentation#focus)
[Sound](/json-ui/json-ui-documentation#sound)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| button | A button and it can have 4 states (default, hover, pressed and locked) | [Button](/json-ui/json-ui-documentation#button)
[Input](/json-ui/json-ui-documentation#input)
[Focus](/json-ui/json-ui-documentation#focus)
[Sound](/json-ui/json-ui-documentation#sound)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| toggle | A toggle and it has 2 states (checked or unchecked). Each state has a hover and locked variant | [Toggle](/json-ui/json-ui-documentation#toggle)
[Input](/json-ui/json-ui-documentation#input)
[Focus](/json-ui/json-ui-documentation#focus)
[Sound](/json-ui/json-ui-documentation#sound)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| dropdown | A toggle for dropdown purposes | [Dropdown](/json-ui/json-ui-documentation#dropdown)
[Toggle](/json-ui/json-ui-documentation#toggle)
[Input](/json-ui/json-ui-documentation#input)
[Focus](/json-ui/json-ui-documentation#focus)
[Sound](/json-ui/json-ui-documentation#sound)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| slider | Range input element | [Slider](/json-ui/json-ui-documentation#slider)
[Input](/json-ui/json-ui-documentation#input)
[Focus](/json-ui/json-ui-documentation#focus)
[Sound](/json-ui/json-ui-documentation#sound)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| slider_box | The slider button that you use to change the slider value | [Slider Box](/json-ui/json-ui-documentation#slider-box)
[Input](/json-ui/json-ui-documentation#input)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| edit_box | Text field element. By default it's single-lined | [Text Edit](/json-ui/json-ui-documentation#text-edit)
[Button](/json-ui/json-ui-documentation#button)
[Input](/json-ui/json-ui-documentation#input)
[Focus](/json-ui/json-ui-documentation#focus)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| scroll_view | Creates a scrolling panel element | [Scroll View](/json-ui/json-ui-documentation#scroll-view)
[Input](/json-ui/json-ui-documentation#input)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| scrollbar_track | The scrollbar track | [Input](/json-ui/json-ui-documentation#input)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout) | -| scrollbar_box | The scrollbar "thumb"/button. The draggable scrolling handle. By default is oriented vertically | [Input](/json-ui/json-ui-documentation#input)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout) | -| factory | A element generator | [Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout) | -| screen | Screen element | [Screen](/json-ui/json-ui-documentation#screen) [Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| custom | Special renderer element that is created in the code because it's too complex for JSON UI | [Custom Render](/json-ui/json-ui-documentation#custom-render)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| selection_wheel | | [Selection Wheel](/json-ui/json-ui-documentation#selection-wheel)
[Input](/json-ui/json-ui-documentation#input)
[Focus](/json-ui/json-ui-documentation#focus)
[Sound](/json-ui/json-ui-documentation#sound)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | +| 名称 | 描述 | 允许的属性 | +| ------------------ | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| panel | 容器元素,类似HTML中的`
` | [控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| stack_panel | 类似`panel`,但会根据`orientation`属性值自动堆叠子元素 | [堆叠面板](/json-ui/json-ui-documentation#stack-panel)
[集合](/json-ui/json-ui-documentation#collection)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| collection_panel | 类似`stack_panel`,但没有`orientation`属性 | [集合](/json-ui/json-ui-documentation#collection)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| grid | 网格布局元素 | [网格](/json-ui/json-ui-documentation#grid)
[集合](/json-ui/json-ui-documentation#collection)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| label | 文本元素 | [文本](/json-ui/json-ui-documentation#text)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| image | 图像元素,用于绘制纹理 | [精灵](/json-ui/json-ui-documentation#sprite)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| input_panel | 可接收输入的面板 | [输入](/json-ui/json-ui-documentation#input)
[焦点](/json-ui/json-ui-documentation#focus)
[音效](/json-ui/json-ui-documentation#sound)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| button | 按钮元素,支持四种状态(默认、悬停、按下、锁定) | [按钮](/json-ui/json-ui-documentation#button)
[输入](/json-ui/json-ui-documentation#input)
[焦点](/json-ui/json-ui-documentation#focus)
[音效](/json-ui/json-ui-documentation#sound)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| toggle | 开关元素,包含两种状态(选中/未选中),每种状态有悬停和锁定变体 | [开关](/json-ui/json-ui-documentation#toggle)
[输入](/json-ui/json-ui-documentation#input)
[焦点](/json-ui/json-ui-documentation#focus)
[音效](/json-ui/json-ui-documentation#sound)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| dropdown | 下拉菜单开关 | [下拉菜单](/json-ui/json-ui-documentation#dropdown)
[开关](/json-ui/json-ui-documentation#toggle)
[输入](/json-ui/json-ui-documentation#input)
[焦点](/json-ui/json-ui-documentation#focus)
[音效](/json-ui/json-ui-documentation#sound)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| slider | 范围输入元素 | [滑块](/json-ui/json-ui-documentation#slider)
[输入](/json-ui/json-ui-documentation#input)
[焦点](/json-ui/json-ui-documentation#focus)
[音效](/json-ui/json-ui-documentation#sound)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| slider_box | 用于调整滑块值的拖动按钮 | [滑块按钮](/json-ui/json-ui-documentation#slider-box)
[输入](/json-ui/json-ui-documentation#input)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| edit_box | 文本输入框(默认单行) | [文本编辑](/json-ui/json-ui-documentation#text-edit)
[按钮](/json-ui/json-ui-documentation#button)
[输入](/json-ui/json-ui-documentation#input)
[焦点](/json-ui/json-ui-documentation#focus)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| scroll_view | 创建可滚动面板 | [滚动视图](/json-ui/json-ui-documentation#scroll-view)
[输入](/json-ui/json-ui-documentation#input)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| scrollbar_track | 滚动条轨道 | [输入](/json-ui/json-ui-documentation#input)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout) | +| scrollbar_box | 滚动条"滑块"(可拖动的滚动手柄,默认垂直方向) | [输入](/json-ui/json-ui-documentation#input)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout) | +| factory | 元素生成器 | [控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout) | +| screen | 屏幕元素 | [屏幕](/json-ui/json-ui-documentation#screen)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| custom | 需通过代码创建的复杂渲染元素 | [自定义渲染](/json-ui/json-ui-documentation#custom-render)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| selection_wheel | 选择轮盘 | [选择轮盘](/json-ui/json-ui-documentation#selection-wheel)
[输入](/json-ui/json-ui-documentation#input)
[焦点](/json-ui/json-ui-documentation#focus)
[音效](/json-ui/json-ui-documentation#sound)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | -#### Legacy Element Types (No longer work) +#### 遗留元素类型(已失效) -| Name | Description | Allowed Properties | -| -------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| tab | The way tabs were made before the addition of toggles | [Tab](/json-ui/json-ui-documentation#tab-legacy)
[Button](/json-ui/json-ui-documentation#button)
[Input](/json-ui/json-ui-documentation#input)
[Focus](/json-ui/json-ui-documentation#focus)
[Sound](/json-ui/json-ui-documentation#sound)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| carousel_label | | [Carousel Text](/json-ui/json-ui-documentation#carousel-text-legacy)
[Text](/json-ui/json-ui-documentation#text)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| grid_item | A `panel` but specifically to be an item/child of a grid | [Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | -| scrollbar | | [Input](/json-ui/json-ui-documentation#input)
[Focus](/json-ui/json-ui-documentation#focus)
[Control](/json-ui/json-ui-documentation#control)
[Layout](/json-ui/json-ui-documentation#layout)
[Data Binding](/json-ui/json-ui-documentation#data-binding) | +| 名称 | 描述 | 允许的属性 | +| ---------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| tab | 在引入toggle之前创建标签页的方式 | [标签页(旧版)](/json-ui/json-ui-documentation#tab-legacy)
[按钮](/json-ui/json-ui-documentation#button)
[输入](/json-ui/json-ui-documentation#input)
[焦点](/json-ui/json-ui-documentation#focus)
[音效](/json-ui/json-ui-documentation#sound)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| carousel_label | 轮播文本元素 | [轮播文本(旧版)](/json-ui/json-ui-documentation#carousel-text-legacy)
[文本](/json-ui/json-ui-documentation#text)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| grid_item | 专门作为网格子元素的容器 | [控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | +| scrollbar | 旧版滚动条 | [输入](/json-ui/json-ui-documentation#input)
[焦点](/json-ui/json-ui-documentation#focus)
[控件](/json-ui/json-ui-documentation#control)
[布局](/json-ui/json-ui-documentation#layout)
[数据绑定](/json-ui/json-ui-documentation#data-binding) | + +::: code-group +```json [示例] +// 代码块注释示例 +{ + "panel": { + "type": "stack_panel", + "orientation": "vertical" + } +} +``` +::: ## Properties diff --git a/docs/wiki/commands/block-entities.md b/docs/wiki/commands/block-entities.md new file mode 100644 index 00000000..4890b4a9 --- /dev/null +++ b/docs/wiki/commands/block-entities.md @@ -0,0 +1,173 @@ +--- +title: MBE - Max's Block Entity +category: Techniques +mention: + - BedrockCommands + - zheaEvyline +tags: + - system +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +This method, developed by Reddit user [u/Maxed_Out10](https://www.reddit.com/user/Maxed_Out10/) allows you to create near-perfect entity replications of any Minecraft block using armour stands and some sequential `/playanimation` commands. + +To preserve credits to the creator, the community termed this method as "Max's Block Entity" or MBE for short. + +### Points to Note + +1. This method uses 1 armour stand per block entity. Therefore, too many armour stands (like any entity) can contribute to server lag. +2. Players will still be able to pass through them as well as interact with them if not restricted. +3. While the block entity may appear in one spot, it's actual hitbox will have a slight offset. + +## Video Demonstration + + + +## Setup + +*To be typed in chat:* +1. `/summon armor_stand Grumm` + - It is necessary to name it 'Grumm' to avoid inverted block textures. +2. `/execute as @e [type= armor_stand, name=Grumm, c=1] at @s run tp @s ~~~ 260` + - This will align the MBE to the normal Minecraft block grid. +ㅤ +:::tip +- Crouch & right-click (on mcpe: long press) the armor stand 6 times to place it in Pose 7 + - Doing this negates the need to use the 2nd command in the system. + - **Only use this if you wish to reduce one command from the system.** +::: + +## System + +> Note: adding a delay of 100-200 ticks is recommended. + +mcfunction + +```yaml +/effect @e [type= armor_stand, name=Grumm] invisibility 999999 1 true +/playanimation @e [type= armor_stand, name=Grumm] animation.armor_stand.entertain_pose null 0 "0" align.arms +/playanimation @e [type= armor_stand, name=Grumm] animation.player.move.arms.zombie null 0 "0" size.mini_block +/playanimation @e [type= armor_stand, name=Grumm] animation.ghast.scale null 0 "0" size.full_block +/playanimation @e [type= armor_stand, name=Grumm] animation.fireworks_rocket.move null 0 "0" align.full_block +/execute as @e [type= armor_stand, name=Grumm] at @s run tp ~~~ +``` +![commandBlockChain6](/assets/images/commands/commandBlockChain/6.png) + +### Purpose Of Each Command +1. Hides the armour stand body. +2. Automatically sets the armour stand pose to 7 for arms alignment. Skip this command you prefer to do it manually. +3. __Required command__. Increases size to present as mini-block. +4. *Optional command.* Increases size to present as full-block. +5. *Optional command.* Aligns the full-block size MBE properly. + - Skip 4 & 5 if you do not need full-block size MBE. +6. Locks in place to prevent fall in case block underneath is removed. + +## Rotations & Alignments + +> Note: These rotation commands are to be executed only once through a command block. + + + +```yaml +# Face North +/tp @e [type=armor_stand, name=Grumm, c=1] ~-1.1245 ~0.2260 ~-0.097 81 + +# Face South +/tp @e [type=armor_stand, name=Grumm, c=1] ~1.1245 ~0.2260 ~0.097 260 + +# Face East +/tp @e [type=armor_stand, name=Grumm, c=1] ~0.097 ~0.2260 ~-1.1245 171 + +# Face West +/tp @e [type=armor_stand, name=Grumm, c=1] ~-0.097 ~0.2260 ~1.1245 350 +``` + + + + + + +```yaml +# Face North +/tp @e [type=armor_stand, name=Grumm, c=1] ~-0.417~-0.5 ~-0.035 81 + +# Face South +/tp @e [type=armor_stand, name=Grumm, c=1] ~0.417 ~-0.5 ~0.035 260 + +# Face East +/tp @e [type=armor_stand, name=Grumm, c=1] ~0.035 ~-0.5 ~-0.417 171 + +# Face West +/tp @e [type=armor_stand, name=Grumm, c=1] ~-0.035 ~-0.5 ~0.417 350 +``` + + + + + +```yaml +# Face North +/tp @e [type=armor_stand, name=Grumm, c=1] ~-0.097 ~0.2325 ~1.1245 350 + +# Face South +/tp @e [type=armor_stand, name=Grumm, c=1] ~0.097 ~0.2325 ~-1.1245 171 + +# Face East +/tp @e [type=armor_stand, name=Grumm, c=1] ~-1.1245 ~0.2325 ~-0.097 81 + +# Face West +/tp @e [type=armor_stand, name=Grumm, c=1] ~1.1245 ~0.2325 ~0.097 260 +``` + + + + + +```yaml +# Face North +/tp @e [type=armor_stand, name=Grumm, c=1] ~-0.097 ~0.2325 ~1.1245 350 + +# Face South +/tp @e [type=armor_stand, name=Grumm, c=1] ~0.097 ~0.2325 ~-1.1245 171 + +# Face East +/tp @e [type=armor_stand, name=Grumm, c=1] ~-1.1245 ~0.2325 ~-0.097 81 + +# Face West +/tp @e [type=armor_stand, name=Grumm, c=1] ~1.1245 ~0.2325 ~0.097 260 +``` + + + + + +```yaml +# Face North +/tp @e [type=armor_stand, name=Grumm, c=1] ~-1.1245 ~0.484 ~-0.097 81 + +# Face South +/tp @e [type=armor_stand, name=Grumm, c=1] ~1.1245 ~0.484 ~0.097 260 + +# Face East +/tp @e [type=armor_stand, name=Grumm, c=1] ~0.097 ~0.484 ~-1.1245 171 + +# Face West +/tp @e [type=armor_stand, name=Grumm, c=1] ~-0.097 ~0.484 ~1.1245 350 +``` + + + +## Saving & Loading MBE + +1. To save run: + - `/execute as @e [type=armor_stand, name=Grumm, c=1] at @s run structure save MBE ~~~ ~~~` + +2. To load run: + - `/structure load MBE ` + +> Note: structure name `MBE` can be changed to your preference. diff --git a/docs/wiki/commands/block-states.md b/docs/wiki/commands/block-states.md new file mode 100644 index 00000000..5f562374 --- /dev/null +++ b/docs/wiki/commands/block-states.md @@ -0,0 +1,118 @@ +--- +title: Block States +category: General +mentions: + - BedrockCommands + - zheaEvyline + - SmokeyStack + - ThomasOrs +tags: + - info +--- + +## Introduction + +[Sourced by Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +Block States or Block Properties are additional data that defines how the block appears or behaves. Such as the direction it is facing, it's color, it's variant, whether it is powered or unpowered and so on. + +This is used in a multitude of commands such as `/clone`, `/execute`, `/fill`, `/setblock` and `/testforblock` + +In Bedrock Edition we used Aux values (also known as Metadata) to define a block. However; as of 1.19.70 and beyond this is no longer supported and have been fully replaced with Block States instead. + +example + +```yaml +#Aux Value Example: +/setblock ~ ~ ~ wool 1 +#It's Block State equivalent: +/setblock ~ ~ ~ wool ["color"="orange"] +``` + +- Any command block using aux values will continue to function as it is however block states will need to be adopted when updating them. +- Similarly any commands using aux values in behaviour or function packs with `min_engine_version` 1.19.63 or below will also continue to function however block states must be adopted if the `min_engine_version` is updated to 1.19.70 or above. + +## Block State Examples & Syntax + +Examples + +```yaml +/setblock ~ ~ ~ wool ["color"="white"] +/setblock ~ ~ ~ wheat ["growth"=0] +/setblock ~ ~ ~ wood ["wood_type"="birch","stripped_bit"=true] +/setblock ~ ~ ~ wool [] +``` + +- Block states are enclosed in square brackets ` [ ] ` +- When specifying multiple block states a comma ` , ` is used to separate them. +- Quotation marks ` " " ` are used around strings such as `"birch", "spruce" etc..` +- Integer values `0, 1, 2..` and boolean values `true/false` do not use quotation marks. +- Leaving the brackets blank is also a correct syntax, it will simply default to 0. +- `wool 0` is white wool hence you may simply write it as `wool []` instead of `wool ["color"="white"]` + +### Notes For Beginners + +- **Integers** are whole numbers. They are used to define a block from a 'range' of values. + - Example: Redstone power 1 to 15 + - `["redstone_power"=10]` + +- **Boolean** is a programming term which refers to `true/false` values. You can simply understand it as yes or no questions. + - Is this piston powered? `yes/no` + - Is this button pressed? `yes/no` + - Is this log stripped? `yes/no` + - `["stripped_bit"=true]` + +- **Strings** are unique 'text' inputs. You can simply understand it as multiple choice questions. + - What color is this wool? `"white"`, `"orange"`, `"brown"` etc.. + - What wood type is this log? `"spruce"`, `"birch"`, `"acacia"` etc.. + - `["wood_type"="spruce"]` + + +## Block States List +A list of all the block states currently available within Bedrock can be found at: +https://learn.microsoft.com/en-us/minecraft/creator/reference/content/blockreference/examples/blockstateslist + +Note: In the site block states may be written as one word but make sure to separate them with underscores `_` when typing in commands. + +Example: `buttonPressedBit` → `"button_pressed_bit"` + +## Converting Aux Values to Block States +For your convenience; download any of the excel sheet below to find the full list of block IDs, their aux values and equivalent block states in Bedrock. *Shared by kayla@Mojang* + +Download Sheet 1 + +Note: the above sheet was quickly generated and contains some minor errors. Boolean values `0` should be replaced with `false` and `1` should be replaced with `true` since the game doesn't recognize the syntax otherwise. + +Alternate sheet: *Shared by @ItsRichHeart* + +Download Sheet 2 + +You may also use this [Lookup Table](https://auxval-to-blockstates.netlify.app/) instead not needing to download any files. + +## Known Issue + +Detecting blocks using commands such as `/execute` or `/testforblock` requires __all__ or __none__ of the block states specified else the command returns an error. + +Example; detecting a pressed stone button on ground facing up: + + +```yaml +#✅ Accepted: +/execute if block ~~~ stone_button [“button_pressed_bit”=true,”facing_direction”=1] run say success +/execute if block ~~~ stone_button run say success + +# ❌ Not Accepted: +/execute if block ~~~ stone_button [“button_pressed_bit”=true] run say success +/execute if block ~~~ stone_button [“facing_direction”=1] run say success +``` +Though block states have replaced aux values, we still cannot detect blocks based on specific filters yet like we do with selector arguments. + +### Related Bug Reports +- [MCPE-133360](https://bugs.mojang.com/browse/MCPE-133360) +- [MCPE-168391](https://bugs.mojang.com/browse/MCPE-168391) diff --git a/docs/wiki/commands/damage.md b/docs/wiki/commands/damage.md new file mode 100644 index 00000000..205778db --- /dev/null +++ b/docs/wiki/commands/damage.md @@ -0,0 +1,96 @@ +--- +title: Damage +category: Commands +tags: + - info +mentions: + - BedrockCommands + - cda94581 + - jordanparki7 + - zheaEvyline +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +Introduced in Minecraft Release `1.18.10`, the /damage command deals precise damage to specified entities. With this change, the clunky methods like using `/effect` command to damage entities are rendered obsolete, making maps and other creations more powerful. + +## Syntax + +- There are two ways the damage command can be used: + - `/damage [Cause]` + - `/damage entity ` + +## Arguments + +- Phrases not contained in angle <> or square [] brackets instruct you to type it as-is. +- Phrases contained within brackets are variables, these need to be replaced: + - **` <> `** Angle brackets mean the variable is required. + - **` [] `** Square brackets mean the variable is optional. + +## Variables + +- **` Target `** This is your typical entity selector, such as `@s` , `@e` , or `"cda94581"` . Multiple entities may be selected at a time to deal the damage to multiple targets. + +- **` Amount `** This is a whole number, which specifies the amount of damage to deal to the targets. The minimum value is `0` and the maximum value is `2147483647`, or the signed 32-bit integer limit. + +- **` Cause `** This specifies the "reason" the damage was dealt. This cause will appear in death messages (`X hit the ground too hard for cause: fall`) be used in damage calculation with armor (`the value dealt in Amount may be different depending on the worn armor`), and used in a large variety of other things, such as in Behavior Pack/Add-ons. A full list of all the damage causes can be found [below](/commands/damage#damage-cause-list) + +- **` Damager `** If Cause was something to do with entities `(such as entity_attack)`, this specifies where the damage came from `(the entity that dealt the attack)`. This is limited to only 1 target. An error will be thrown if multiple targets are found from the selector. + +> Note: the ` entity ` is only required when the Cause has to do with another entity `(entity_attack)`. Otherwise, follow the first syntax. + +## Examples + +mcfunction +```yaml +#Deal 4 damage to all players +/damage @a 4 + +#Deal 3 'fire' damage to all entities of type 'sheep' +/damage @e [type=sheep] 3 fire + +#Deal 40 'entity attack' damage from a random player to all entities of type 'sheep' +/damage @a 40 entity_attack entity @r [type=sheep] +``` + +## Damage Cause List + +Listed below are all the 'damage sources' in MCBE for the `/damage` command currently available: +``` +anvil +attack +block_explosion +charging +contact +drowning +entity_attack +entity_explosion +fall +falling_block +fatal +fire +fire_tick +fireworks +fly_into_wall +freezing +lava +lightning +magic +magma +none +override +piston +projectile +sonic_boom +stalactite +stalagmite +starve +suffocation +suicide +temperature +thorns +void +wither +``` diff --git a/docs/wiki/commands/entity-counter.md b/docs/wiki/commands/entity-counter.md new file mode 100644 index 00000000..62acc0f8 --- /dev/null +++ b/docs/wiki/commands/entity-counter.md @@ -0,0 +1,89 @@ +--- +title: Entity Counter +category: Scoreboard Systems +mentions: + - BedrockCommands + - zheaEvyline +nav_order: 3 +tags: + - system +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +This system allows you to track how many players/entities are there on your world and run your desired commands based on the values obtained. + +> Note: you cannot track entities in unloaded chunks though players can still be tracked regardless. + +## Setup + +*To be typed in Chat:* + +`/scoreboard objectives add total dummy` + +If you prefer to have the objective added automatically on world initialisation, follow the process outlined in [On First World Load.](/commands/on-first-world-load) + +## System + +BP/functions/entity_counter.mcfunction + +```yaml +scoreboard players set onlinePlayers total 0 +execute as @e [type=player] run scoreboard players add onlinePlayers total 1 + +#Your Commands Here (examples) +execute if score onlinePlayers total matches 4.. run title @a actionbar Enough players to start game. +execute if score onlinePlayers total matches ..3 run title @a actionbar Not enough players. +``` +![commandBlockChain3](/assets/images/commands/commandBlockChain/3.png) + + +Here we have used a FakePlayer name `onlinePlayers` and targeting `@e [type=player]` to track how many players are currently on the world. However you may use any FakePlayer name and target any entity you might need. Such as `@e [type=creeper]` + +Similarly we're running a `/title` command as an example: +- a) when there are 4 or more players `4..` +- b) when there are 3 players or less `..3` + +You can edit this as well to suit your need. + +## Explanation + +- The first two commands in the system sets the FakePlayer name's score to 0 (here `onlinePlayers`) and from each loaded entity we want to track (here `type=player`) it will add a score to the specified FakePlayer name (here `onlinePlayers`) + +Now based on the values obtained we can use the `/execute if score` command to run our desired commands when certain values are met. +- **` n `** any number n +- **` n.. `** any number n and above +- **` ..n `** any number n and below +- **` n1..n2 `** any number n1 to any number n2. + +## Tick JSON + +If you are using functions instead of command blocks, the ` entity_counter ` function must be added to the ` tick.json ` in order to loop and run it continuously. Multiple files can be added to the ` tick.json ` by placing a comma after each string. Refer to [Functions](/commands/mcfunctions#tick-json) documentation for further info. + +BP/functions/tick.json +```json +{ + "values": [ + "entity_counter" + ] +} +``` + +If using functions, your pack folder structure will be be as follows: + + + +> **Note:** the scoreboard names (in this case: 'total') may end up being used by other people. Appending ` _ ` and a set of randomly generated characters after would be a choice that reduces the probability of collisions. Similar technique can be employed for the ` .mcfunction ` filenames. Ex: +> - ` total_0fe678 ` +> - ` entity_counter_0fe678.mcfunction ` diff --git a/docs/wiki/commands/index.md b/docs/wiki/commands/index.md new file mode 100644 index 00000000..075266c2 --- /dev/null +++ b/docs/wiki/commands/index.md @@ -0,0 +1,14 @@ +--- +title: Commands +categories: + - title: General + color: green + - title: Commands + color: green + - title: On Event Systems + color: blue + - title: Scoreboard Systems + color: blue + - title: Techniques + color: orange +--- diff --git a/docs/wiki/commands/intro-to-command-blocks.md b/docs/wiki/commands/intro-to-command-blocks.md new file mode 100644 index 00000000..879bcb11 --- /dev/null +++ b/docs/wiki/commands/intro-to-command-blocks.md @@ -0,0 +1,141 @@ +--- +title: Intro to Command Blocks +category: General +mentions: + - BedrockCommands + - zheaEvyline + - jordanparki7 +nav_order: 1 +tags: + - info +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +Command Blocks are special blocks in Minecraft. The same commands (cheats) you type in chat can be run automatically using command blocks and it can be reused without needing to type all over again. + +They can only be placed or destroyed by a player with the Operator permission level in gamemode Creative. + +## Obtaining + +1. Open your world settings. +2. Under Cheats, toggle "Activate Cheats" setting ON. +3. Run `/give @s command_block` command in chat. + +## Command Block UI + +![commandBlockUI](/assets/images/commands/commandBlockUI.png) + +## Command Block Types + +![impulseCommandBlock](/assets/images/commands/impulseCommandBlock.png) **Impulse** runs the command __once__ each time it is powered. + +![chainCommandBlock](/assets/images/commands/chainCommandBlock.png) **Chain** runs the command in a sequence, ie. only after the previous command block it is connecting from was run. + +![repeatingCommandBlock](/assets/images/commands/repeatingCommandBlock.png) **Repeat** runs the command every game tick. There are approximately 20 ticks per second. A delay can be applied to adjust how often the command is executed, explained [below](/commands/intro-to-command-blocks#command-block-tick-delay). + +## Command Block Conditions + +**Conditional** command blocks will run the command only if the previous command block it was connecting from had an output that was `true` (successful) +> Conditional command block states are shown by a small indent into the command block's texture, as shown below: +> - ![pasteCommandButton](/assets/images/commands/impulseConditionalCommandBlock.png) Impulse Conditional Command Block +> - ![chainConditionalCommandBlock](/assets/images/commands/chainConditionalCommandBlock.png) Chain Conditional Command Block +> - ![repeatingConditionalCommandBlock](/assets/images/commands/repeatingConditionalCommandBlock.png) Repeating Conditional Command Block + +**Unconditional** command blocks will run the command regardless. Whether the previous command block it was connecting from had an output that was `true` (succesful), `false` (failed) or even if it came with a syntax error the command block will still run the command. + +## Command Block Redstone States + +**Needs Redstone** command block can only be activated with redstone power. Using buttons, levers, redstone torch etc.. + +**Always Active** command block will be activated as soon as you close the command block UI. + +## Command Block Tick Delay + +In this option you may specify how much delay you want there to be before the command block runs the command. + +The ticks refer to Minecraft game ticks. A **tick** is simply a unit of measure for time in games. 1 second in real life is approximately 20 game ticks in Minecraft. + +:::tip +![gametick.png](/assets/images/commands/gametick.png) +::: + +## Command Block Hover Note + +This option allows you to put a hovering text on your command blocks. It's useful for giving short-names for easy identification when working with many command blocks. + +When a command is run, the hover note will be displayed with the output in chat if gamerule `commandblockoutput` is enabled. +![hover_note](/assets/images/commands/hover_note.png) + +## Paste Button + +![pasteCommandButton](/assets/images/commands/pasteCommandButton.png) + +The paste button allows you to paste commands from your clipboard to the 'Command Input' box. + +## Command Block Output + +- Toggle the 'Previous Output' button in the command block UI to see command output and block details. + +- The ` / ` you type before the whole command is not required in a command block but doing so won't cause any errors. + +- A redstone comparator can read command blocks outputs. If output is true, it will send anywhere from 1 to 15 redstone signals depending on the output value. + +- You can check if a command output is `true`/`false` by running it in chat. A red output will be a `false` output or a syntax error. A white output means command was run successfully. + +- You can also tell if a command was `true`/`false` by checking whether action was performed or not. + +- An output with a value of `0` is usually a false output. + +### Disabling Command Messages In Chat +Run in Chat: +- `/gamerule commandblockoutput false` to disable command block messages in chat. +- `/gamerule sendcommandfeedback false` to disable feedback from commands entered in chat. + +## Command Block Placement + +When placing command blocks in a line (arranged to work together) for any system, make sure the consecutive command blocks connect/start from the head of the arrow. + +The arrow/facing direction can be observed from the command block texture. + +**✅ Correct Placement** +![correctCommandBlockPlacement](/assets/images/commands/correctCommandBlockPlacement.png) + +**❌ Incorrect Placement** +![incorrectCommandBlockPlacement](/assets/images/commands/incorrectCommandBlockPlacement.png) + +## Troubleshooting Command Blocks + +- In world settings, under **Cheats**, make sure command blocks have not been disabled. + +- Make sure gamerule `maxcommandchainlength` is **not** set to 0 + +- Make sure there are no unwanted redstone power that is interfering with the command block. It can be from redstone dust, lever, redstone torch etc.. + +- Try switching between Always Active & Needs Redstone. + +- Double check the block type, condition & the command syntax. Check 'Previous Output' after powering it once again. + +- Just like redstone, command blocks must also be in loaded chunks for them to work. You can use a tickingarea to keep them loaded when players are not nearby. Refer to [/tickingarea](https://learn.microsoft.com/en-us/minecraft/creator/documents/tickingareacommand) command documentation for more info. + +If nothing seems to work simply break and place that command block again. + +## What you have learned + +:::tip What you have learned: +- How to obtain a command block in game. +- How the different types of command blocks behave and what they look like. +- What the different command block options are (including conditional, state and delay.) +- How command blocks output data by redstone and chat messages. +- How to properly place command block chains. +- How to resolve 'command block not working' +::: + +To put what you have learned into practice, try making this simple [Entity Counter](/commands/entity-counter) system. +> Note: when setting up command block systems, always the first command will be ![repeatingCommandBlock](/assets/images/commands/repeatingCommandBlock.png) **`Unconditional Always Active`** and the rest will be ![chainCommandBlock](/assets/images/commands/chainCommandBlock.png) **`Unconditional Always Active`** (all 0 ticks delay) *unless specified otherwise.* +> +> ![commandBlockChain4](/assets/images/commands/commandBlockChain/4.png) + +**(Recommended) Read Next: [Understanding Selectors](/commands/selectors)** diff --git a/docs/wiki/commands/mcfunctions.md b/docs/wiki/commands/mcfunctions.md new file mode 100644 index 00000000..ff284772 --- /dev/null +++ b/docs/wiki/commands/mcfunctions.md @@ -0,0 +1,158 @@ +--- +title: Functions +category: General +mentions: + - Bedrock Commands + - cda94581 + - zheaEvyline + - jordanparki7 +nav_order: 3 +tags: + - info +--- +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +Functions are `.mcfunction` files which contain multiple lines of commands. They are run with the `/function` command in-game. + +Functions are created in a **Behavior Pack**, nested within the **functions** folder. A function pack creates a system using solely function files. + +Functions are useful in many ways to reduce the time spent going from command block to command block debugging a system. They also help with packaging systems for use in multiple worlds and provide many functions that can change how everything works. + +## Function Pack Folder Structure + + + +## Notes For Beginners + +mcfunction + +```yaml +#Spawn Effects +effect @a [tag=atSpawn] regeneration 12 255 true +effect @a [tag=atSpawn] saturation 12 255 true +effect @a [tag=atSpawn] weakness 12 255 true +``` +- Each new line in a function file represents a new command. You may start a line with # to add comments. Commands in a function do not need to begin with a slash `/`, however doing so will not cause any errors. + +- All commands in a function are run in the *same tick*. Because of this, a function which causes large changes may cause a sudden lag spike and it is helpful to delegate some commands across multiple ticks, if possible. +Commands in a function are still run in the same order, however. + +- Minecraft can **not** run more than 10,000 lines of commands in one function file. This includes any other function files that are executed inside of the original file. + +- It is not possible to run conditional commands. Those will still need to utilize command blocks in some way, or could utilize the 1.19.50 execute syntax. + +- Running commands with a specified delay in a function would involve using scoreboard timers to incrementally count up every tick (to a certain point), and executing at certain scores along the file. You may refer to [Scoreboard Timers](/commands/scoreboard-timers) system to learn how to set it up. + +## Creating a Function + +1. Locate the `📁 com.mojang` folder and navigate to `📁 development_behavior_packs` + - The development folders are used for quick reloading of packs, as the packs aren't cached to the world files. + +2. Create a folder (of any name) for the function pack. This will be referred to as Behavior Pack or BP. + +3. Create a `📄 manifest.json` file and a `🖼 pack_icon.png` file (optional) within the BP folder. + - A manifest file contains all the information needed to register a pack, while a pack icon displays visually in the pack menu. A pack icon is typically a 128x128 or a 256x256 image, though any power-of-2 resolution will do, they will be upscaled and downscaled accordingly. + + + +BP/manifest.json + +```json +{ + "format_version": 2, + "header": { + "description": "Write Your Pack Description Here", + "name": "Write Your Pack Name Here", + "uuid": "00000000-0000-0000-0000-000000000000", + "version": [ 1, 0, 0 ], + "min_engine_version": [ 1, 19, 73 ] + }, + "modules": [ + { + "description": "§r", + "type": "data", + "uuid": "00000000-0000-0000-0000-000000000000", + "version": [1, 0, 0 ] + } + ] +} +``` + +Note that the uuid field needs to be replaced with an actual uuid, and the two generated must be different from one another. You can generate a uuid at https://uuidgenerator.net/ + + + + +Sample A: + +![pack_icon.png](/assets/images/commands/pack_icon.png) + +Sample B: + +![pack_icon.png](/assets/images/guide/project-setup/pack_icon.png) + + + +4. Create a `📁 functions` folder. Any file within this folder that ends with **.mcfunction** will be registered as a function in-game, which can be run with `/function `. + - Nested functions are allowed, simply list the file path in relation to the functions folder as shown in the function pack folder structure. + +5. Apply the behavior pack in-game and try out the functions. Function file changes can be reflected in the world by running `/reload` or by simply relogging. + +:::tip NOTE +Functions are versioned; therefore, they will run in the version listed in the `📄 manifest.json`, such as: +- `min_engine_version` 1.19.50 or above will adopt the new execute syntax. +- `min_engine_version` 1.19.70 or above will require aux values be replaced with block states. +::: + +## Execution + +Functions can be executed in-game by typing `/function name_of_function`. This will execute all the commands in the function file, all in a single tick. + +Nested functions, for example `BP/functions/lobby/items/1.mcfunction` can be run using the nested folder path, in this case `/function lobby/items/1` + +## tick.json + +The final file within a function is the **tick.json** file. This specifies functions to run server-side on every game tick, (similar to a repeating command block.) It is located in the `BP/functions` folder. By default, functions running in this file execute at origin `0, 0, 0` in the overworld. + +BP/functions/tick.json +```json +{ + "values": [ + "function_1", + "function_2" + ] +} +``` +> Note: functions in this file are run as soon as the world is *initialized*, regardless of whether or not the player has been *loaded*. This may cause unintended behavior if used incorrectly. + +## Sample Function Pack + + + +## Troubleshooting Functions + +Your functions may not appear within the command suggestions when using `/function`. This is normally due to an error with one or more commands in the function. + +Enabling the [Content Log](/guide/troubleshooting#content-log) in creator settings will allow you to see if there are any errors in your function pack, in which function the error is in, at which line and exactly what the syntax error for that command is. + +The list of errors will be generated every time you load a world or run `/reload` to reflect changes after editing files. The list can be viewed on-screen for a few seconds as well as in the content log history in settings. + +![contentLogToggles](/assets/images/commands/contentLogToggles.png) + +![contentLogHistory](/assets/images/commands/contentLogHistory.png) diff --git a/docs/wiki/commands/nbt-commands.md b/docs/wiki/commands/nbt-commands.md new file mode 100644 index 00000000..0d74e725 --- /dev/null +++ b/docs/wiki/commands/nbt-commands.md @@ -0,0 +1,108 @@ +--- +title: NBT Commands +category: General +mentions: + - MedicalJewel105 + - SirLich + - Veka0 + - StuartDA + - Sprunkles137 + - TheItsNameless + - SmokeyStack +--- + +NBT data for the Bedrock edition is minimal. The only values we have access to are: + +1. `CanPlaceOn` +2. `CanDestroy` +3. `KeepOnDeath` +4. `ItemLock`. + +These are used as part of a `/give` or `replaceitem` command and can edit specific properties of the items with said NBT. + +## CanPlaceOn and CanDestroy + +Destroy: `/give @p diamond_pickaxe 1 0 {"minecraft:can_destroy":{"blocks":["planks", "skull"]}}` + +Place on: `/give @p stone 1 0 {"minecraft:can_place_on":{"blocks":["stone"]}}` + +You can add more blocks like this: `["stone", "dirt", "bedrock"]` + +Note: The game interprets mob skulls as blocks that can be destroyed. These two NBT components only function in adventure mode. + +### CanPlaceOn Everything + +This is the code for a block that can be placed on everything in the game: + +**Please, note that if there is at least one invalid block, this won't work!** + + + + +```json +give @p stone 1 0 {"minecraft:can_place_on": {"blocks": ["acacia_button", "acacia_door", "acacia_fence", "acacia_fence_gate", "acacia_hanging_sign", "acacia_log", "acacia_pressure_plate", "acacia_stairs", "acacia_standing_sign", "acacia_trapdoor", "acacia_wall_sign", "activator_rail", "air", "allow", "amethyst_block", "amethyst_cluster", "ancient_debris", "andesite_stairs", "anvil", "azalea", "azalea_leaves", "azalea_leaves_flowered", "bamboo", "bamboo_block", "bamboo_button", "bamboo_door", "bamboo_double_slab", "bamboo_fence", "bamboo_fence_gate", "bamboo_hanging_sign", "bamboo_mosaic", "bamboo_mosaic_double_slab", "bamboo_mosaic_slab", "bamboo_mosaic_stairs", "bamboo_planks", "bamboo_pressure_plate", "bamboo_sapling", "bamboo_slab", "bamboo_stairs", "bamboo_standing_sign", "bamboo_trapdoor", "bamboo_wall_sign", "barrel", "barrier", "basalt", "beacon", "bed", "bedrock", "bee_nest", "beehive", "beetroot", "bell", "big_dripleaf", "birch_button", "birch_door", "birch_fence", "birch_fence_gate", "birch_hanging_sign", "birch_log", "birch_pressure_plate", "birch_stairs", "birch_standing_sign", "birch_trapdoor", "birch_wall_sign", "black_candle", "black_candle_cake", "black_carpet", "black_concrete", "black_glazed_terracotta", "black_shulker_box", "black_wool", "blackstone", "blackstone_double_slab", "blackstone_slab", "blackstone_stairs", "blackstone_wall", "blast_furnace", "blue_candle", "blue_candle_cake", "blue_carpet", "blue_concrete", "blue_glazed_terracotta", "blue_ice", "blue_shulker_box", "blue_wool", "bone_block", "bookshelf", "border_block", "brain_coral", "brewing_stand", "brick_block", "brick_stairs", "brown_candle", "brown_candle_cake", "brown_carpet", "brown_concrete", "brown_glazed_terracotta", "brown_mushroom", "brown_mushroom_block", "brown_shulker_box", "brown_wool", "bubble_column", "bubble_coral", "budding_amethyst", "cactus", "cake", "calcite", "calibrated_sculk_sensor", "camera", "campfire", "candle", "candle_cake", "carpet", "carrots", "cartography_table", "carved_pumpkin", "cauldron", "cave_vines", "cave_vines_body_with_berries", "cave_vines_head_with_berries", "chain", "chain_command_block", "cherry_button", "cherry_door", "cherry_double_slab", "cherry_fence", "cherry_fence_gate", "cherry_hanging_sign", "cherry_leaves", "cherry_log", "cherry_planks", "cherry_pressure_plate", "cherry_sapling", "cherry_slab", "cherry_stairs", "cherry_standing_sign", "cherry_trapdoor", "cherry_wall_sign", "cherry_wood", "chest", "chiseled_bookshelf", "chiseled_deepslate", "chiseled_nether_bricks", "chiseled_polished_blackstone", "chorus_flower", "chorus_plant", "clay", "coal_block", "coal_ore", "cobbled_deepslate", "cobbled_deepslate_double_slab", "cobbled_deepslate_slab", "cobbled_deepslate_stairs", "cobbled_deepslate_wall", "cobblestone", "cobblestone_wall", "cocoa", "command_block", "composter", "concrete", "concretePowder", "conduit", "copper_block", "copper_ore", "coral", "coral_block", "coral_fan", "coral_fan_dead", "coral_fan_hang", "coral_fan_hang2", "coral_fan_hang3", "cracked_deepslate_bricks", "cracked_deepslate_tiles", "cracked_nether_bricks", "cracked_polished_blackstone_bricks", "crafting_table", "crimson_button", "crimson_door", "crimson_double_slab", "crimson_fence", "crimson_fence_gate", "crimson_fungus", "crimson_hanging_sign", "crimson_hyphae", "crimson_nylium", "crimson_planks", "crimson_pressure_plate", "crimson_roots", "crimson_slab", "crimson_stairs", "crimson_standing_sign", "crimson_stem", "crimson_trapdoor", "crimson_wall_sign", "crying_obsidian", "cut_copper", "cut_copper_slab", "cut_copper_stairs", "cyan_candle", "cyan_candle_cake", "cyan_carpet", "cyan_concrete", "cyan_glazed_terracotta", "cyan_shulker_box", "cyan_wool", "dark_oak_button", "dark_oak_door", "dark_oak_fence", "dark_oak_fence_gate", "dark_oak_hanging_sign", "dark_oak_log", "dark_oak_pressure_plate", "dark_oak_stairs", "dark_oak_trapdoor", "dark_prismarine_stairs", "darkoak_standing_sign", "darkoak_wall_sign", "daylight_detector", "daylight_detector_inverted", "dead_brain_coral", "dead_bubble_coral", "dead_fire_coral", "dead_horn_coral", "dead_tube_coral", "deadbush", "decorated_pot", "deepslate", "deepslate_brick_double_slab", "deepslate_brick_slab", "deepslate_brick_stairs", "deepslate_brick_wall", "deepslate_bricks", "deepslate_coal_ore", "deepslate_copper_ore", "deepslate_diamond_ore", "deepslate_emerald_ore", "deepslate_gold_ore", "deepslate_iron_ore", "deepslate_lapis_ore", "deepslate_redstone_ore", "deepslate_tile_double_slab", "deepslate_tile_slab", "deepslate_tile_stairs", "deepslate_tile_wall", "deepslate_tiles", "deny", "detector_rail", "diamond_block", "diamond_ore", "diorite_stairs", "dirt", "dirt_with_roots", "dispenser", "double_cut_copper_slab", "double_plant", "double_stone_slab", "double_stone_slab2", "double_stone_slab3", "double_stone_slab4", "double_wooden_slab", "dragon_egg", "dried_kelp_block", "dripstone_block", "dropper", "emerald_block", "emerald_ore", "enchanting_table", "end_brick_stairs", "end_bricks", "end_gateway", "end_portal", "end_portal_frame", "end_rod", "end_stone", "ender_chest", "exposed_copper", "exposed_cut_copper", "exposed_cut_copper_slab", "exposed_cut_copper_stairs", "exposed_double_cut_copper_slab", "farmland", "fence", "fence_gate", "fire", "fire_coral", "fletching_table", "flower_pot", "flowering_azalea", "flowing_lava", "flowing_water", "frame", "frog_spawn", "frosted_ice", "furnace", "gilded_blackstone", "glass", "glass_pane", "glow_frame", "glow_lichen", "glowingobsidian", "glowstone", "gold_block", "gold_ore", "golden_rail", "granite_stairs", "grass", "grass_path", "gravel", "gray_candle", "gray_candle_cake", "gray_carpet", "gray_concrete", "gray_glazed_terracotta", "gray_shulker_box", "gray_wool", "green_candle", "green_candle_cake", "green_carpet", "green_concrete", "green_glazed_terracotta", "green_shulker_box", "green_wool", "grindstone", "hanging_roots", "hardened_clay", "hay_block", "heavy_weighted_pressure_plate", "honey_block", "honeycomb_block", "hopper", "horn_coral", "ice", "infested_deepslate", "info_update", "info_update2", "invisibleBedrock", "iron_bars", "iron_block", "iron_door", "iron_ore", "iron_trapdoor", "jigsaw", "jukebox", "jungle_button", "jungle_door", "jungle_fence", "jungle_fence_gate", "jungle_hanging_sign", "jungle_log", "jungle_pressure_plate", "jungle_stairs", "jungle_standing_sign", "jungle_trapdoor", "jungle_wall_sign", "kelp", "ladder", "lantern", "lapis_block", "lapis_ore", "large_amethyst_bud", "lava", "lava_cauldron", "leaves", "leaves2", "lectern", "lever", "light_block", "light_blue_candle", "light_blue_candle_cake", "light_blue_carpet", "light_blue_concrete", "light_blue_glazed_terracotta", "light_blue_shulker_box", "light_blue_wool", "light_gray_candle", "light_gray_candle_cake", "light_gray_carpet", "light_gray_concrete", "light_gray_shulker_box", "light_gray_wool", "light_weighted_pressure_plate", "lightning_rod", "lime_candle", "lime_candle_cake", "lime_carpet", "lime_concrete", "lime_glazed_terracotta", "lime_shulker_box", "lime_wool", "lit_blast_furnace", "lit_deepslate_redstone_ore", "lit_furnace", "lit_pumpkin", "lit_redstone_lamp", "lit_redstone_ore", "lit_smoker", "lodestone", "log", "log2", "loom", "magenta_candle", "magenta_candle_cake", "magenta_carpet", "magenta_concrete", "magenta_glazed_terracotta", "magenta_shulker_box", "magenta_wool", "magma", "mangrove_button", "mangrove_door", "mangrove_double_slab", "mangrove_fence", "mangrove_fence_gate", "mangrove_hanging_sign", "mangrove_leaves", "mangrove_log", "mangrove_planks", "mangrove_pressure_plate", "mangrove_propagule", "mangrove_roots", "mangrove_slab", "mangrove_stairs", "mangrove_standing_sign", "mangrove_trapdoor", "mangrove_wall_sign", "mangrove_wood", "medium_amethyst_bud", "melon_block", "melon_stem", "mob_spawner", "monster_egg", "moss_block", "moss_carpet", "mossy_cobblestone", "mossy_cobblestone_stairs", "mossy_stone_brick_stairs", "movingBlock", "mud", "mud_brick_double_slab", "mud_brick_slab", "mud_brick_stairs", "mud_brick_wall", "mud_bricks", "muddy_mangrove_roots", "mycelium", "nether_brick", "nether_brick_fence", "nether_brick_stairs", "nether_gold_ore", "nether_sprouts", "nether_wart", "nether_wart_block", "netherite_block", "netherrack", "netherreactor", "normal_stone_stairs", "noteblock", "oak_fence", "oak_hanging_sign", "oak_log", "oak_stairs", "observer", "obsidian", "ochre_froglight", "orange_candle", "orange_candle_cake", "orange_carpet", "orange_concrete", "orange_glazed_terracotta", "orange_shulker_box", "orange_wool", "oxidized_copper", "oxidized_cut_copper", "oxidized_cut_copper_slab", "oxidized_cut_copper_stairs", "oxidized_double_cut_copper_slab", "packed_ice", "packed_mud", "pearlescent_froglight", "pink_candle", "pink_candle_cake", "pink_carpet", "pink_concrete", "pink_glazed_terracotta", "pink_petals", "pink_shulker_box", "pink_wool", "piston", "pistonArmCollision", "pitcher_crop", "pitcher_plant", "planks", "podzol", "pointed_dripstone", "polished_andesite_stairs", "polished_basalt", "polished_blackstone", "polished_blackstone_brick_double_slab", "polished_blackstone_brick_slab", "polished_blackstone_brick_stairs", "polished_blackstone_brick_wall", "polished_blackstone_bricks", "polished_blackstone_button", "polished_blackstone_double_slab", "polished_blackstone_pressure_plate", "polished_blackstone_slab", "polished_blackstone_stairs", "polished_blackstone_wall", "polished_deepslate", "polished_deepslate_double_slab", "polished_deepslate_slab", "polished_deepslate_stairs", "polished_deepslate_wall", "polished_diorite_stairs", "polished_granite_stairs", "portal", "potatoes", "powder_snow", "powered_comparator", "powered_repeater", "prismarine", "prismarine_bricks_stairs", "prismarine_stairs", "pumpkin", "pumpkin_stem", "purple_candle", "purple_candle_cake", "purple_carpet", "purple_concrete", "purple_glazed_terracotta", "purple_shulker_box", "purple_wool", "purpur_block", "purpur_stairs", "quartz_block", "quartz_bricks", "quartz_ore", "quartz_stairs", "rail", "raw_copper_block", "raw_gold_block", "raw_iron_block", "red_candle", "red_candle_cake", "red_carpet", "red_concrete", "red_flower", "red_glazed_terracotta", "red_mushroom", "red_mushroom_block", "red_nether_brick", "red_nether_brick_stairs", "red_sandstone", "red_sandstone_stairs", "red_shulker_box", "red_wool", "redstone_block", "redstone_lamp", "redstone_ore", "redstone_torch", "redstone_wire", "reeds", "reinforced_deepslate", "repeating_command_block", "reserved6", "respawn_anchor", "sand", "sandstone", "sandstone_stairs", "sapling", "scaffolding", "sculk", "sculk_catalyst", "sculk_sensor", "sculk_shrieker", "sculk_vein", "seaLantern", "sea_pickle", "seagrass", "shroomlight", "shulker_box", "silver_glazed_terracotta", "skull", "slime", "small_amethyst_bud", "small_dripleaf_block", "smithing_table", "smoker", "smooth_basalt", "smooth_quartz_stairs", "smooth_red_sandstone_stairs", "smooth_sandstone_stairs", "smooth_stone", "sniffer_egg", "snow", "snow_layer", "soul_campfire", "soul_fire", "soul_lantern", "soul_sand", "soul_soil", "soul_torch", "sponge", "spore_blossom", "spruce_button", "spruce_door", "spruce_fence", "spruce_fence_gate", "spruce_hanging_sign", "spruce_log", "spruce_pressure_plate", "spruce_stairs", "spruce_standing_sign", "spruce_trapdoor", "spruce_wall_sign", "stained_glass", "stained_glass_pane", "stained_hardened_clay", "standing_banner", "standing_sign", "stickyPistonArmCollision", "sticky_piston", "stone", "stone_brick_stairs", "stone_button", "stone_pressure_plate", "stone_slab", "stone_slab2", "stone_slab3", "stone_slab4", "stone_stairs", "stonebrick", "stonecutter", "stonecutter_block", "stripped_acacia_log", "stripped_bamboo_block", "stripped_birch_log", "stripped_cherry_log", "stripped_cherry_wood", "stripped_crimson_hyphae", "stripped_crimson_stem", "stripped_dark_oak_log", "stripped_jungle_log", "stripped_mangrove_log", "stripped_mangrove_wood", "stripped_oak_log", "stripped_spruce_log", "stripped_warped_hyphae", "stripped_warped_stem", "structure_block", "structure_void", "suspicious_gravel", "suspicious_sand", "sweet_berry_bush", "tallgrass", "target", "tinted_glass", "tnt", "torch", "torchflower", "torchflower_crop", "trapdoor", "trapped_chest", "tripWire", "tripwire_hook", "tube_coral", "tuff", "turtle_egg", "twisting_vines", "undyed_shulker_box", "unlit_redstone_torch", "unpowered_comparator", "unpowered_repeater", "verdant_froglight", "vine", "wall_banner", "wall_sign", "warped_button", "warped_door", "warped_double_slab", "warped_fence", "warped_fence_gate", "warped_fungus", "warped_hanging_sign", "warped_hyphae", "warped_nylium", "warped_planks", "warped_pressure_plate", "warped_roots", "warped_slab", "warped_stairs", "warped_standing_sign", "warped_stem", "warped_trapdoor", "warped_wall_sign", "warped_wart_block", "water", "waterlily", "waxed_copper", "waxed_cut_copper", "waxed_cut_copper_slab", "waxed_cut_copper_stairs", "waxed_double_cut_copper_slab", "waxed_exposed_copper", "waxed_exposed_cut_copper", "waxed_exposed_cut_copper_slab", "waxed_exposed_cut_copper_stairs", "waxed_exposed_double_cut_copper_slab", "waxed_oxidized_copper", "waxed_oxidized_cut_copper", "waxed_oxidized_cut_copper_slab", "waxed_oxidized_cut_copper_stairs", "waxed_oxidized_double_cut_copper_slab", "waxed_weathered_copper", "waxed_weathered_cut_copper", "waxed_weathered_cut_copper_slab", "waxed_weathered_cut_copper_stairs", "waxed_weathered_double_cut_copper_slab", "weathered_copper", "weathered_cut_copper", "weathered_cut_copper_slab", "weathered_cut_copper_stairs", "weathered_double_cut_copper_slab", "web", "weeping_vines", "wheat", "white_candle", "white_candle_cake", "white_carpet", "white_concrete", "white_glazed_terracotta", "white_shulker_box", "white_wool", "wither_rose", "wood", "wooden_button", "wooden_door", "wooden_pressure_plate", "wooden_slab", "wool", "yellow_candle", "yellow_candle_cake", "yellow_carpet", "yellow_concrete", "yellow_flower", "yellow_glazed_terracotta", "yellow_shulker_box", "yellow_wool"]}} +``` + +*Last updated for 1.20.10* + + +## ItemLock + +Lock in any applicable slot in inventory: `/give @p iron_axe 1 100 {"minecraft:item_lock":{ "mode": "lock_in_inventory" }}` + +Lock in a specific slot in inventory: `/give @p apple 1 0 {"minecraft:item_lock":{ "mode": "lock_in_slot" }}` + +These two variations of ItemLock are mutually exclusive. Itemlock works in both adventure and survival. + +### Overriding how ItemLock displays + +The texture to overwrite is `16x16`, and is located in `RP/textures/ui/item_lock_red.png` and `RP/textures/ui/item_lock_yellow.png` + +The following translation keys can be overwritten if you want to change how these components display: + +``` +item.itemLock.cantDrop=:hollow_star: Can't Drop Items can't be: +item.itemLock.cantMove=:solid_star: Can't Move Items can't be: +item.itemLock.hoverText.cantBe.moved=moved +item.itemLock.hoverText.cantBe.dropped=dropped +item.itemLock.hoverText.cantBe.removed=removed +item.itemLock.hoverText.cantBe.craftedWith=crafted with +item.itemLock.keepOnDeath=This item is not lost on death +item.itemLock.popupNotice.cantDrop=:hollow_star: Can't Drop Items can't be: dropped, removed, crafted with +item.itemLock.popupNotice.cantMove=:solid_star: Can't Move Items can't be: moved, dropped, removed, crafted with +``` +If you want to hide description and red/yellow triangle, you can simply do: +`/gamerule showtags false` + +## KeepOnDeath + +Item will remain in an entity's inventory when it dies: `/replaceitem entity @e[type=zombie] slot.weapon.mainhand -1 cooked_beef 1 0 {"minecraft:keep_on_death":{}}` + +For non-player entities, the item will not be present in their inventory after death as they do not respawn. This can be cleared from the entity's inventory using /clear or replaced with /replaceitem. +> Gamerule /keepinventory set to true functions as if all items in a player's inventory had `"minecraft:keep_on_death":{}`. However, the NBT component is most helpful in filtering on specific items that one wishes for a player to remain in his or her inventory instead of all items. + +KeepOnDeath functions identically in both adventure and survival mode. + +## Combining NBT components + +Give all players a bow that locks in a specific inventory slot and is kept on death: `/give @a bow 1 0 {"minecraft:item_lock":{ "mode": "lock_in_slot" }, "minecraft:keep_on_death":{}}` + +Give self a stone shovel that can only dig up gravel and sand, and locks in inventory: `/give @s stone_shovel 1 0 {"minecraft:can_destroy":{"blocks":["dirt", "sand"]},"minecraft:item_lock":{ "mode": "lock_in_inventory" }}` + +## Additional Notes + +Assigning specific blocks and items with specific data values using `"minecraft:can_place_on"` and `"minecraft:can_destroy"` will return an error stating the NBT "could not be updated, which seems to be an unintended bug in this case. + +`/give @s cobblestone 64 0 {"minecraft:can_place_on":{"blocks":["stained_glass:2"]}}` + +`/give @a wooden_axe 16 0 {"minecraft:can_destroy":{"blocks":["wool:5"]}}` + +Similarly to the issue above, specifying commands that generally do not make sense will also return a "could not be updated" error. Some examples include: + +`/give @a diamond 10 0 {"minecraft:can_place_on":{"blocks":["dirt"]}}` + +(cannot place items on blocks) + +## Giving in trade/Loot-tables + +It is currently not possible to set NBT via loot tables or trade tables. If you want to sell NBT-powered items, you will need to use a workaround of some kind or another, such as cloning chests containing items with pre-existing NBT. diff --git a/docs/wiki/commands/new-execute.md b/docs/wiki/commands/new-execute.md new file mode 100644 index 00000000..aed1178e --- /dev/null +++ b/docs/wiki/commands/new-execute.md @@ -0,0 +1,247 @@ +--- +title: New Execute +category: Commands +tags: + - easy +mentions: + - JaylyDev + - Sprunkles137 + - Hatchibombotar + - TheItsNameless + - SmokeyStack + - zheaEvyline +--- + +## Introduction + +With the release of 1.19.50, the `/execute` command was given a syntax overhaul. While the syntax is now more verbose and longer to write, it allows much finer control over the contextual components of commands and adds support for conditions to commands, superseding the use of commands like `/testfor`, `/testforblock`, and `/testforblocks`. + +Before we dive into the syntax and how to write it, we need to understand how the old `/execute` command worked, and what changed and why. This will make explaining the concepts found in the syntax easier. + +## Understanding Execution Context + +For both beginners to commands and those well versed in how old `/execute` behaved, it may be a good idea to review the concept of a command's **execution context**. + +In short, these are the parameters that affects how a command runs. Who the command will run as, also known as its executor; where the command will run, and in which dimension; and the rotation applied to the command are all parameters that can be changed. + +Every command has this context applied to it, and this context changes depending on how the command runs. Commands fired from command blocks do not have an executor, and the position is set to that command block; commands ran from chat define the executor as the player, and it runs at the player's position. + +## Execute, and Why it Changed + +The `/execute` command executes a command on behalf of one or more entities. The old syntax used to be this: + +``` +/execute +/execute detect +``` + +You specified a target to execute as, then the command's context would change to run as that target, and at that target. Any position changes were then always relative to that target. + +While this is useful in most cases, it also forces the fact that a command's target and its position are always tied together (unless you were to manually insert world coordinates in place of ``). It is also not very malleable in regards to making conditional statements, as you have to execute as an entity every time. + +Back in the Summer of 2017 during the Update Aquatic's development, the developers of Minecraft: Java Edition were getting feedback from the community on how they can improve the `/execute` command's syntax, and the basic concept that was conceived is this: `/execute` takes an unlimited number of **subcommands** that manipulate certain aspects of the command in the order you specify, then a "run" subcommand is placed at the end to fire a command. + +This allows for much greater control for what `/execute` can do to a command, and allows splitting up the executor and the command's position. + +## New Syntax + +Now, let us review the new `/execute` syntax. They are as follows: + +### `/execute as` + +Changes the executor of the command, or what the target selector `@s` will select. + +``` +/execute as -> execute +``` + +This does not change the position, rotation, or dimension context of the command. + +If multiple targets are specified then a command is ran once for each target, where `@s` selects each entity in turn. + +### `/execute at` + +Changes where the command runs, setting the command's position, rotation, and dimension context to the entity. + +``` +/execute at -> execute +``` + +This does not change the executor of the command, so `@s` will remain as whoever was targeted last. + +If multiple targets are specified then a command is ran once for each target, setting the position, rotation, and dimension context to each target. + +### `/execute in` + +Sets the dimension in which the command should run. + +``` +/execute in -> execute +``` + +Currently accepted values are `overworld`, `nether`, and `the_end`. + +This change in dimension will respect that dimension's scale; going from the Overworld to The Nether will apply a scale of x0.125 to the position, and vice versa will apply a x8 scale to the position. + +### `/execute positioned` + +Directly sets the position context of the command. + +``` +/execute positioned -> execute +``` + +Sets the position of the command to specific values. [Relative and local coordinates](/commands/relative-coordinates) are based around the current position of the command. + +``` +/execute positioned as -> execute +``` + +Sets the position of the command to a target's location. This is similar to how `/execute at` works, but it only sets the command's position and not its rotation or dimension. + +If multiple targets are specified then a command is ran once for each target, setting the position context to the target's position. + +### `/execute align` + +Aligns the current position of the command to the block grid. + +``` +/execute align -> execute +``` + +Aligning a position will floor it. This subcommand accepts any non-repeating combination of the letters "x", "y", and "z", and will floor the position along each axis specified. + +### `/execute anchored` + +Sets the anchor of the command to the executor's feet or eyes. Changing the anchor will affect the position where local coordinates will start at. + +``` +/execute anchored (eyes|feet) -> execute +``` + +The default anchor when executing at a target is their feet. + +When the anchor is set to `eyes`, the command's local position is offset by some amount corresponding to the "eye height" of the current executor. + +This offset should only apply to local coordinates, but it currently affects relative coordinates due to a bug: [MCPE-162681](https://bugs.mojang.com/browse/MCPE-162681). + +### `/execute rotated` + +Directly sets the rotation context of the command. + +``` +/execute rotated -> execute +``` + +Sets the rotation of the command to specific values. Relative and local coordinates are based around the current rotation of the command. This defaults to 0 for both pitch and yaw, unless the rotation was changed prior. + +``` +/execute rotated as -> execute +``` + +Sets the rotation of the command to a target's rotation. + +If multiple targets are specified then a command is ran once for each target, setting the rotation context to the target's rotation. + +### `/execute facing` + +Sets the rotation of the command to face some position. This rotation is calculated based on the current position of the command. + +``` +/execute facing -> execute +``` + +Sets the rotation to face a block position. Relative and local coordinates are based around the current position of the command. + +``` +/execute facing entity (eyes|feet) -> execute +``` + +Sets the rotation to face a target's position. Setting the anchor to `feet` will aim the rotation to face where they are currently standing, while setting the anchor to `eyes` will aim the command up at the "eye position" of that target (see [`/execute anchored`](/commands/new-execute#execute-anchored)). + +If multiple targets are specified then a command is ran once for each target, setting the rotation context to face that target. + +### `/execute (if|unless)` + +Prevents running a command based on a condition. If the condition is true then the command will continue, or stop otherwise. + +`/execute unless` acts as the opposite, testing if the condition is false in order to continue. + +``` +/execute if entity -> execute +``` + +Acts like `/testfor`. Returns true if the targets exist. + +``` +/execute if block -> execute +``` + +Acts like `/testforblock`. Returns true if the block at the specified location exists. + +A data value or block state may additionally be specified, otherwise it ignores block states (acts as if it were set to `-1`). + +``` +/execute if blocks (all|masked) -> execute +``` + +Acts like `/testforblocks`. It constructs a volume between the beginning and end positions, and returns true if the volume at the destination matches the original volume. + +The parameter `all` tests that all blocks must match, while `masked` will ignore air blocks. + +``` +/execute if score matches -> execute +``` + +Tests if a specified score is a certain value. This uses the integer range syntax. + +``` +/execute if score (=|<|<=|>|>=) -> execute +``` + +Tests if a specified score matches some logical comparison to another score. Operators are equals (`=`), greater than (`>`), greater than or equal to (`>=`), less than (`<`), and less than or equal to (`<=`). + +### `/execute run` + +``` +/execute run +``` + +Runs a command using all of the currently applied context modifications. This subcommand always goes last in one `/execute` command. + +This subcommand is not always required however; an `/execute` command ending with an `if` or `unless` subcommand is valid too, and will return the success of the test it performed. + +## Examples and Upgrading Old Commands + +Since subcommands can be chained limitlessly, there really is a nearly infinite combination of arguments for an `/execute` command and they cannot all be listed. Instead, listed here are some common examples of commands. + +The old functionality of `/execute` can be replicated with `as at @s`. If you need a positional offset relative to the entity, add `positioned`. If you want to detect if a block is present, add `if block`. Here are some equivalents: + +``` +# Teleport with an offset +/execute @p ~ ~1.62 ~ teleport @s ^ ^ ^3 + +/execute as @p at @s positioned ~ ~1.62 ~ run teleport @s ^ ^ ^3 +``` + +``` +# Chaining multiple '/execute's +/execute @e[type=sheep] ~ ~ ~ execute @e[type=item,r=5] ~ ~ ~ detect ~ ~-1 ~ stone 0 kill @s + +/execute at @e[type=sheep] as @e[type=item,r=5] at @s if block ~ ~-1 ~ stone 0 run kill @s +``` + +(Note that we do not use `as @e[type=sheep] at @s` because we do not need to execute as the sheep; only the position here is required.) + +Now for some examples of things that were not possible to do in one command, or were more difficult to perform before the new syntax was introduced. + +``` +# Testing a fake player's score +/execute if score game_settings var matches 3.. run say [Game] Difficulty set to Hard. + +# Comparing if two scores are equal +/execute as @a if score @s x = @s y run say My X is equal to my Y. + +# Test for an entity without targeting it +/execute as @a at @s if entity @e[type=armor_stand,r=10] run gamemode survival @s +``` diff --git a/docs/wiki/commands/on-first-join.md b/docs/wiki/commands/on-first-join.md new file mode 100644 index 00000000..a5004375 --- /dev/null +++ b/docs/wiki/commands/on-first-join.md @@ -0,0 +1,73 @@ +--- +title: On First Join +category: On Event Systems +mentions: + - BedrockCommands + - zheaEvyline + - SmokeyStack +nav_order: 1 +tags: + - system +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +This system will run your desired commands on the event that a player joins the world for the first time. + + + +## System +BP/functions/on_first_join.mcfunction + +```yaml +#Your Commands Here (examples) +give @a [tag=!joined] stone_pickaxe +give @a [tag=!joined] bread 16 1 +tag @a [tag=!joined] add joined +``` + +![commandBlockChain3](/assets/images/commands/commandBlockChain/3.png) + + +Here we have used 2 `give` commands as example but you can use any command you prefer and as many as you require. + +Just make sure to follow the given order and properly add the selector argument ` tag=!joined ` as shown for your desired commands. + +## Explanation + +When the player joins the world for the first time, they will not have the joined tag. + +Once we run our desired commands for players without the tag, they will be given the tag immediately and the commands will not repeat for them again unless we remove their tag with: +`tag remove joined` + +## Tick JSON + +If you are using functions instead of command blocks, the ` on_first_join ` function must be added to the ` tick.json ` in order to loop and run it continuously. Multiple files can be added to the ` tick.json ` by placing a comma after each string. Refer to [Functions](/commands/mcfunctions#tick-json) documentation for further info. + +BP/functions/tick.json +```json +{ + "values": [ + "on_first_join" + ] +} +``` + +If using functions, your pack folder structure will be be as follows: + + + +> **Note:** the tag names (in this case: 'joined') may end up being used by other people. Appending ` _ ` and a set of randomly generated characters after would be a choice that reduces the probability of collisions. Similar technique can be employed for the ` .mcfunction ` filenames. Ex: +> - ` joined_0fe678 ` +> - ` on_first_join_0fe678.mcfunction ` diff --git a/docs/wiki/commands/on-first-world-load.md b/docs/wiki/commands/on-first-world-load.md new file mode 100644 index 00000000..a7b79a8e --- /dev/null +++ b/docs/wiki/commands/on-first-world-load.md @@ -0,0 +1,78 @@ +--- +title: On First World Load +category: On Event Systems +mentions: + - BedrockCommands + - zheaEvyline + - SmokeyStack + - cda94581 +nav_order: 6 +tags: + - system +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +This system will run your desired commands on the event that the world is loaded for the first time. +> **Note:** a [Function](/commands/mcfunctions) Pack is required to achieve this system since it is the `tick.json` file which allows us to run commands as soon as the world is initialised. + + +## Tick Json + +BP/functions/tick.json +```json +{ + "values": [ + "initialise" + ] +} +``` + +## System + +BP/functions/initialise.mcfunction +```yaml +scoreboard objectives add world dummy +scoreboard players add initialised world 0 + + +#Your Commands Here (example) +execute if score initialised world matches 0 run say New world created! + + +scoreboard players set initialised world 1 +``` + +Here we have used an `execute - say` command as an example but you can use any command you prefer and as many as you require. + +Just make sure to follow the given order and properly use the `execute if score` command as shown to run the commands you need. + +## Explanation + +- **` initialised=0 `** this means the world has just initialised and we are yet to run the initlisation commands. +- **` initialised=1 `** this means the world has been initialised and we have already run the initialisation commands. + +An objective of the name `world` is added for us to save scores to it so that we can track whether the world has been initialised or not. This also allows us to structure our commands to only execute at world initialisation. + +Following the creation of the objective, a score of `0` is added to the FakePlayer name `initialised`. This will register it to the objective and enable us to use the `execute if score` command structure to run our desired commands. + +Finally the score for `initialised` is set to 1 after all the commands are run in order to prevent it from executing more than once. + +## Folder Structure + + + +> **Note:** the scoreboard names (in this case: 'world') may end up being used by other people. Appending ` _ ` and a set of randomly generated characters after would be a choice that reduces the probability of collisions. Similar technique can be employed for the ` .mcfunction ` filenames. Ex: +> - ` world_0fe678 ` +> - ` initialise_0fe678.mcfunction ` diff --git a/docs/wiki/commands/on-player-death.md b/docs/wiki/commands/on-player-death.md new file mode 100644 index 00000000..e9e6b9c2 --- /dev/null +++ b/docs/wiki/commands/on-player-death.md @@ -0,0 +1,95 @@ +--- +title: On Player Death +category: On Event Systems +mentions: + - BedrockCommands + - zheaEvyline +nav_order: 4 +tags: + - system +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +This system will run your desired commands on the event that a player dies. + +## Setup + +*To be typed in Chat:* + +`/scoreboard objectives add alive dummy` + +If you prefer to have the objective added automatically on world initialisation, follow the process outlined in [On First World Load.](/commands/on-first-world-load) + +## System + +BP/functions/on_player_death.mcfunction + +```yaml +scoreboard players set @a [scores={alive=!2}] alive 0 +scoreboard players set @e [type=player] alive 1 + + +#Your Commands Here (example) +execute as @a [scores={alive=0}] run say I died + + +scoreboard players set @a [scores={alive=0}] alive 2 +``` + +![commandBlockChain4](/assets/images/commands/commandBlockChain/4.png) + + +Here we have used an `/execute - say` command as an example but you can use any command you prefer and as many as you require. + +Just make sure to follow the given order and properly add the selector argument ` scores={alive=0} ` as shown for your desired commands. + +## Explanation + +- **` alive=0 `** this means player is dead. +- **` alive=1 `** this means player is alive. +- **` alive=2 `** this means player is dead and we have run our desired commands on/from them. + + +- **` @a `** selector will target all players alive/dead so we use it to mark everyone as 0 'dead.' + - Note: we will ignore 2 or it will end up making the commands execute on dead players again. We only want our commands to execute once. + + +- **` @e `** selector on the other hand will only target players who are alive, so we can use this to mark all alive players 1 'alive.' + + +- Now that dead players are 0 and alive players are 1 we can use this knowledge to run our desired commands on the dead players. + - Keep in mind we need to set their score to 2 after or otherwise the commands will keep executing till they respawn. + + +## Tick JSON + +If you are using functions instead of command blocks, the ` on_player_death ` function must be added to the ` tick.json ` in order to loop and run it continuously. Multiple files can be added to the ` tick.json ` by placing a comma after each string. Refer to [Functions](/commands/mcfunctions#tick-json) documentation for further info. + +BP/functions/tick.json +```json +{ + "values": [ + "on_player_death" + ] +} +``` + +If using functions, your pack folder structure will be be as follows: + + + +> **Note:** the scoreboard names (in this case: 'alive') may end up being used by other people. Appending ` _ ` and a set of randomly generated characters after would be a choice that reduces the probability of collisions. Similar technique can be employed for the ` .mcfunction ` filenames. Ex: +> - ` alive_0fe678 ` +> - ` on_player_death_0fe678.mcfunction ` diff --git a/docs/wiki/commands/on-player-join.md b/docs/wiki/commands/on-player-join.md new file mode 100644 index 00000000..4eef48b7 --- /dev/null +++ b/docs/wiki/commands/on-player-join.md @@ -0,0 +1,86 @@ +--- +title: On Player Join +category: On Event Systems +mentions: + - BedrockCommands + - zheaEvyline +nav_order: 2 +tags: + - system +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +This system will run your desired commands on the event that a players joins the world. + +## Setup + +*To be typed in Chat:* + +`/scoreboard objectives add joined dummy` + +If you prefer to have the objective added automatically on world initialisation, follow the process outlined in [On First World Load.](/commands/on-first-world-load) + +## System + +BP/functions/on_player_join.mcfunction + +```yaml +scoreboard players add @a joined 0 + + +#Your Commands Here (example) +tp @a[scores={joined=0}] 0 65 0 + + +scoreboard players reset * joined +scoreboard players set @a joined 1 +``` + +![commandBlockChain4](/assets/images/commands/commandBlockChain/4.png) + + +Here we have used a `tp` command as an example but you can use any command you prefer and as many as you require. + +Just make sure to follow the given order and properly add the selector argument ` scores={joined=0} ` as shown for your desired commands. + +## Explanation + +When the player joins, a 0 is added to their objective, this allows us to run commands from them using the 'scores' selector argument. + +Immediately after the commands are run, we reset all the scores on the objective using wildcard **` * `** and only players who stayed online will have their score set to 1. + +And this way, since our commands only target players with the score 0, the commands won't repeat again for the players who stayed unless they leave and rejoin or if we run: +`/scoreboard players set joined 0` + +## Tick JSON + +If you are using functions instead of command blocks, the ` on_player_join ` function must be added to the ` tick.json ` in order to loop and run it continuously. Multiple files can be added to the ` tick.json ` by placing a comma after each string. Refer to [Functions](/commands/mcfunctions#tick-json) documentation for further info. + +BP/functions/tick.json +```json +{ + "values": [ + "on_player_join" + ] +} +``` + +If using functions, your pack folder structure will be be as follows: + + + +> **Note:** the scoreboard names (in this case: 'joined') may end up being used by other people. Appending ` _ ` and a set of randomly generated characters after would be a choice that reduces the probability of collisions. Similar technique can be employed for the ` .mcfunction ` filenames. Ex: +> - ` joined_0fe678 ` +> - ` on_player_join_0fe678.mcfunction ` diff --git a/docs/wiki/commands/on-player-leave.md b/docs/wiki/commands/on-player-leave.md new file mode 100644 index 00000000..e42272cb --- /dev/null +++ b/docs/wiki/commands/on-player-leave.md @@ -0,0 +1,107 @@ +--- +title: On Player Leave +category: On Event Systems +mentions: + - BedrockCommands + - zheaEvyline +nav_order: 3 +tags: + - system +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +This system will run your desired commands on the event that a player leaves the world. + +> **Note:** you cannot execute commands on the *players* that leave using selectors. However; you may use the [On Player Join](/commands/on-player-join) system to execute when they join back. + +## Setup + +*To be typed in Chat:* + +`/scoreboard objectives add total dummy` + +If you prefer to have the objective added automatically on world initialisation, follow the process outlined in [On First World Load.](/commands/on-first-world-load) + +## System + +BP/functions/on_player_leave.mcfunction + +```yaml +scoreboard players reset new total +execute as @a run scoreboard players add new total 1 +scoreboard players operation new total -= old total + + +#Your Commands Here (example) +execute if score new total matches ..-1 run say a player has left the world + + +scoreboard players reset old total +execute as @a run scoreboard players add old total 1 +``` + +![commandBlockChain6](/assets/images/commands/commandBlockChain/6.png) + +Here we have used a **`/say`** command as an example but you can use any command you prefer and as many as you require. + +Just make sure to follow the given order and properly use the `/execute if score` command as shown to run the commands you need. + +## Explanation + +- **` new `** this FakePlayer name means the total number of players on the world in the current game tick. +- **` old `** this FakePlayer name means the total number of players that were on the world in the previous game tick but also saves the values to be used in the *next* game tick. + +These values are obtained using the [Entity Counter](/commands/entity-counter) system. It may be beneficial to refer to that doc for better understanding this one. + +By subtracting 'old' total from 'new' total we will be able to identify if player count has: +- decreased ` ..-1 ` +- increased ` 1.. ` +- or if it's unchanged ` 0 ` + +If it has decreased; we know that 1 or more players have left the game. +With this knowledge we can run our desired commands from 'new' if it's score is -1 or less. +- ie, if there were 10 players and someone leaves: + - that is ` new - old ` + - which is ` 9 - 10 = -1 ` + - hence we will detect by ` ..-1 ` + +- The 'new' total value is obtained first, subtraction is performed after that to run your desired commands and lastly the 'old' total value is obtained to be used in the next game tick. + +:::tip +All commands involved in a command-block-chain or function will only run in a sequence one after the other but it all still happens in the same tick regardless of the number of commands involved. We are able to achieve this system due to the fact that commands run along the end of a game tick after all events such as player log in, log out, death etc.. occur. + +![gametick](/assets/images/commands/gametick.png) +::: + +## Tick JSON + +If you are using functions instead of command blocks, the ` on_player_leave ` function must be added to the ` tick.json ` in order to loop and run it continuously. Multiple files can be added to the ` tick.json ` by placing a comma after each string. Refer to [Functions](/commands/mcfunctions#tick-json) documentation for further info. + +BP/functions/tick.json +```json +{ + "values": [ + "on_player_leave" + ] +} +``` + +If using functions, your pack folder structure will be be as follows: + + + +> **Note:** the scoreboard names (in this case: 'total') may end up being used by other people. Appending ` _ ` and a set of randomly generated characters after would be a choice that reduces the probability of collisions. Similar technique can be employed for the ` .mcfunction ` filenames. Ex: +> - ` total_0fe678 ` +> - ` on_player_leave_0fe678.mcfunction ` diff --git a/docs/wiki/commands/on-player-respawn.md b/docs/wiki/commands/on-player-respawn.md new file mode 100644 index 00000000..b447cd49 --- /dev/null +++ b/docs/wiki/commands/on-player-respawn.md @@ -0,0 +1,86 @@ +--- +title: On Player Respawn +category: On Event Systems +mentions: + - BedrockCommands + - zheaEvyline +nav_order: 5 +tags: + - system +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +This system will run your desired commands on the event that a player respawns from death state. + +## Setup + +*To be typed in Chat:* + +`/scoreboard objectives add respawn dummy` + +If you prefer to have the objective added automatically on world initialisation, follow the process outlined in [On First World Load.](/commands/on-first-world-load) + +## System + +on_player_respawn.mcfunction + +```yaml +#Your Commands Here (example) +execute as @e [scores={respawn=1}] run say I died and respawned. + + +scoreboard players set @a respawn 1 +scoreboard players set @e [type=player] respawn 0 +``` +![commandBlockChain3](/assets/images/commands/commandBlockChain/3.png) + + +Here we have used an `/execute - say` command as an example but you can use any command you prefer and as many as you require. + +Just make sure to follow the given order and properly use the selector argument ` @e [scores={respawn=1}] ` as shown for your desired commands. + +## Explanation + +- **` respawn=0 `** this means the player is alive or had already respawned. +- **` respawn=1 `** this means the player died and is now respawning, ie. respawned *just now*, in the current gametick. +- **` @a `** selector will target all players alive/dead so we use it to mark everyone as 1 'respawning' +- **` @e `** selector on the other hand will only target players who are alive, so we can use this to mark all alive players 0 'respawned' + +Now that *respawning* players are 1 and *respawned* players are 0 we can use this knowledge to run our desired commands on the players respawning. + +In the system, your desired commands must come before the other 2 commands because players change from death state to alive state along the start of the gametick before commands are run. + +Hence; if we were to put them at the end then the other 2 commands would set respawning players score to 0 first and then the commands you want to run won't be able to select those players as our selector argument is ` @e [scores={respawn=1}] ` not 0. Using 0 would not work as then it would repeat endlessly even on players who have already respawned. + +## Tick JSON + +If you are using functions instead of command blocks, the ` on_player_respawn ` function must be added to the ` tick.json ` in order to loop and run it continuously. Multiple files can be added to the ` tick.json ` by placing a comma after each string. Refer to [Functions](/commands/mcfunctions#tick-json) documentation for further info. + +BP/functions/tick.json +```json +{ + "values": [ + "on_player_respawn" + ] +} +``` + +If using functions, your pack folder structure will be be as follows: + + + +> **Note:** the scoreboard names (in this case: 'respawn') may end up being used by other people. Appending ` _ ` and a set of randomly generated characters after would be a choice that reduces the probability of collisions. Similar technique can be employed for the ` .mcfunction ` filenames. Ex: +> - ` respawn_0fe678 ` +> - ` on_player_respawn_0fe678.mcfunction ` diff --git a/docs/wiki/commands/playsound.md b/docs/wiki/commands/playsound.md new file mode 100644 index 00000000..4bf3ff1b --- /dev/null +++ b/docs/wiki/commands/playsound.md @@ -0,0 +1,79 @@ +--- +title: Playsound +category: Commands +mentions: + - BedrockCommands + - zheaEvyline + - jordanparki7 +tags: + - info +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +You can use the `/playsound` command to play sound effects to players present anywhere in the world whenever you like. + +## Syntax + +`/playsound [player] [position] [volume] [pitch] [minimumVolume]` + +## Definitions + +### Sound + +- It is the sound effect you wish to play. +- You can find the list of sound IDs currently available at: + - https://www.digminecraft.com/lists/sound_list_pe.php + +### Player + +- This is an optional argument. +- It refers to your typical target selectors (whom you want to play the sound to) ` @a `, ` @r `, ` @p `, ` Technoblade `, etc.. + +### Position + +- This is an optional argument. +- It refers to the `x y z` position from where the sound will be played, ie. the center of the playsound radius. + +### Volume + +- This is an optional argument. +- It determines the size of the sphere in which the sound effect can be heard. + - ` 0.0 ` is the minimum size. +- Sound & audible sphere size increases as `volume` value is increased. + - Playaound volume of `1` is equal to an audible sphere of radius 16 blocks. + - Similarly; volume of `4` would be equal to 64 blocks. + +### Pitch + +- This is an optional aegument. +- It determines the pitch for the sound effect. +- It can be a value between ` 0.0 ` and ` 256.0 ` + - The higher the value, the higher the pitch. + - Values less than or equal to `0.0` makes the sound inaudible. + +> Note: pitch affects the speed at which the audio is played. For example, a pitch of `0.5` would mean the audio is played at ` 0.5× ` speed. + +### Minimum Volume + +- This is an optional argument. +- It determines the minimum volume at which the sound will be heard outside of the audible sphere. +- It can be a value between ` 0.0 ` and ` 1.0 ` + +## Examples + +mcfunction +```yaml +#Play a random explosion sound effect to closest player. +/playsound random.explode @p + +#Play a random orb sound effect to all players at their relative position with a volume of 10000 +/execute as @a at @s playsound random.orb @s ~ ~ ~ 10000 +``` + +Note: since the playsound command is positonal, it is helpful to use an execute command structure as shown in the second example to prevent the sound effect from cutting off in special cases such as playing a sound effect following a `/tp` command. You may increase volume when covering large distances to reduce failures. + + +**(Recommended) Read Next: [Sounds](/concepts/sounds)** diff --git a/docs/wiki/commands/relative-coordinates.md b/docs/wiki/commands/relative-coordinates.md new file mode 100644 index 00000000..ea907923 --- /dev/null +++ b/docs/wiki/commands/relative-coordinates.md @@ -0,0 +1,46 @@ +--- +title: Coordinate System +category: General +mentions: + - MedicalJewel105 + - Sprunkles137 + - 7dev7urandom + - Hatchibombotar + - TheItsNameless +--- + +## The Coordinate System + +Minecraft stores the locations of blocks and entities in the world using a system of three-dimensional coordinates, each representing a value in a one-dimensional axis. They are stored in the format of X, then Y, and lastly Z. Whether you are placing structures and blocks, or teleporting and summoning entities, you can, and are sometimes required to, put in coordinates. They don't need to always be real values however; you can substitute world coordinates for relative values, either based in world space or local space. + +![image](https://user-images.githubusercontent.com/64864915/134789891-85644dd7-e30f-4e02-966c-df2bf17a7879.png) + +_You may already be familiar with coordinates if you've enabled the Show Coordinates world option!_ + +## Relative Coordinates (~) + +Relative coordinates are represented using tildes in place of real coordinates, and represent a position that is relative to the world coordinates its located at. You may insert numbers after a tilde to add an offset to the current position. These can be mixed with world coordinates, but cannot be mixed with local coordinates. + +Examples: + - `~ ~ ~`: Current position with no changes. + - `~5 ~-2 ~`: Current position with a 5-block X offset and a negative 2-block Y offset. + +### Rotations + +Relative coordinates can also be used in the context of rotations, where they represent a rotation that is relative to the current rotation it inherits from. These may also accept numbers after the tilde to add an offset to the current rotation. + +Example: `~90 ~` will add 90° to the current yaw (y-rotation) value. + +## Local Coordinates (^) + +Local coordinates are similar to relative coordinates, but represent a position in local space, where the axes are based off of rotation. They take the form `^left ^up ^forward`; you can think of this as `~x ~y ~z` if both your yaw and pitch rotations are 0 (facing straight ahead, due south). + +Like relative coordinates, you can insert numbers to produce an offset of the current position, in local space. If there is no entity to copy rotation from, the x- and y-rotations are assumed to be 0. + +Examples: + - `^10 ^ ^`: Current position with a 10-block offset to the left. + - `^ ^1.5 ^1`: Current position with a 1.5-block offset upward and a 1-block offset forward. + +## Additional Notes + +- The player's eye level is 1.62 blocks above their feet. (~ ~1.62 ~) \ No newline at end of file diff --git a/docs/wiki/commands/scoreboard-operations.md b/docs/wiki/commands/scoreboard-operations.md new file mode 100644 index 00000000..78de179a --- /dev/null +++ b/docs/wiki/commands/scoreboard-operations.md @@ -0,0 +1,135 @@ +--- +title: Scoreboard Operations +category: General +mentions: + - Sprunkles137 + - Luthorius + - MedicalJewel105 + - Hatchibombotar +--- + +Scoreboards can be used to perform complex operations, similar to [Molang](/concepts/molang). Operations come in two flavors: mathematical, and logical. + +## Overview +Operations are performed using the `/scoreboard players operation` command. The full syntax is laid out below: +``` +/scoreboard players operation +``` +The command consists of two score holders: The target score, and the source score. The target score is the value being operated on, and the source score is the value affecting the operation. The result of the operation is written into the target score, and the source score's value is not touched, save for [one operation](/commands/scoreboard-operations#swap-operator). + +## Mathematical Operators +Mathematical operators use arithmetic to affect the target score. There are five mathematical operations available: addition, subtraction, multiplication, floor division, and floor modulo division. + +For each of the following examples below, assume that score holder `A var` equals 25, and `B var` equals 10. + +### Addition +Operator: **+=** + +This operation adds the target score and source scores together, then stores the sum into the target score. +``` +/scoreboard players operation A var += B var +``` +`A = A + B`, and as such `25 + 10 = 35`. + +### Subtraction +Operator: **-=** + +This operation subtracts the target score by the source score, then stores the difference into the target score. +``` +/scoreboard players operation A var -= B var +``` +`A = A - B`, and as such `25 - 10 = 15`. + +### Multiplication +Operator: **\*=** + +This operation multiplies the target score by the source score, then stores the product into the target score. +``` +/scoreboard players operation A var *= B var +``` +`A = A * B`, and as such `25 * 10 = 250`. + +### Floored Division +Operator: **/=** + +This operation divides the target score by the source score, then stores the quotient into the target score. Because score values can only be integers, the value is floored, or rounded down. +``` +/scoreboard players operation A var /= B var +``` +`A = floor(A / B)`, and as such `floor(25 / 10) = 2`. + +### Floored Modulo Division +Operator: **%=** + +This operation also divides the target score by the source score, but instead returns the remainder after the division into the target score. This is also floored. +``` +/scoreboard players operation A var %= B var +``` +`A = floor(mod(A, B))`, and as such `floor(mod(25, 10)) = 5`. + +## Logical Operators +Logical operations use logic gates and assignments to affect the target score. There are four logical operations available: assignment, less than, greater than, and swap. + +Similar to the above, assume that score holder `A var` equals 25, and `B var` equals 10. + +### Assignment Operator +Operator: **=** + +This operation sets the target score equal to the source score. +``` +/scoreboard players operation A var = B var +``` +`A = B`, and as such the result is `10`. + +### Minimum Operator +Operator: **<** + +This operation returns the smallest of the input scores, and stores it into the target score. +``` +/scoreboard players operation A var < B var +``` +`A = min(A, B)`, and as such `min(25, 10) = 10`. + +### Maximum Operator +Operator: **>** + +This operation returns the largest of the input scores, and stores it into the target score. +``` +/scoreboard players operation A var > B var +``` +`A = max(A, B)`, and as such `max(25, 10) = 25`. + +### Swap Operator +Operator: **><** + +This operation swaps the target score and source scores with each other. This is the only operation that affects the source score. +``` +/scoreboard players operation A var >< B var +``` +The above command would swap the values of A and B e.g. + +Before: A = 10; B = 25; + +After: A = 25; B = 10; + +This can be seen as three operations: `temp = A; A = B; B = temp;`, and as such `A var = 10` and `B var = 25`. + +## Useful Creations + +#### Check If Values are Equal + +If you want to check in scoreboard, whether one value equals another value, you can copy first value to temporary value, subtract the other and compare temporary value to zero. Given values A and B: + + + +``` +scoreboard objectives add temp dummy +scoreboard players operation @e temp = @s A +scoreboard players operation @e temp -= @s B +execute @e[scores={temp=0}] ~~~ say A equals B +scoreboard objectives remove temp +``` + +#### Scoreboard Initialization + +If you want to initialize a scoreboard value to 0, but only if it doesn't exists, you can use `scoreboard players add 0`. It will set the value to 0, if it doesn't exist on the entity and do nothing, if it already exist. diff --git a/docs/wiki/commands/scoreboard-timers.md b/docs/wiki/commands/scoreboard-timers.md new file mode 100644 index 00000000..02c27938 --- /dev/null +++ b/docs/wiki/commands/scoreboard-timers.md @@ -0,0 +1,200 @@ +--- +title: Scoreboard Timers +category: Scoreboard Systems +mentions: + - BedrockCommands + - zheaEvyline +nav_order: 5 +tags: + - system +--- + +## Introduction + +[Sourced By Bedrock Commands Community Discord](https://discord.gg/SYstTYx5G5) + +This system allows you to run your desired commands at specific intervals with any amount of delay that you wish to add. + +- **Some Examples:** + - Sending a message in chat every 2 hours. + - Running a 'lag clear' function every 10 minutes. + - Effecting players with 'speed' every 30 seconds. + + This system is especially useful when you need to set up multiple timers on your world. When working with command blocks, you may use the [Tick Delay](/commands/intro-to-command-blocks#command-block-tick-delay) option to delay the time taken for your commands to run. However, when working with functions you will need to use a system like this. + +It is recommended to use this system while working with command blocks, as well if you wish to run all your timers in sync with one another, ie. with the same start time. + +## Setup + +*To be typed in chat:* + + +```yaml +scoreboard objectives add ticks dummy +scoreboard objectives add events dummy +``` + +Once you have created these two objectives, you will need to define the interval for each repeating event you need on your world in the `ticks` objective. + +To do that, first you must know that **1 second is approximately 20 game ticks in Minecraft**. Based on this knowledge, you will need to do some basic calculations to obtain the ticks equivalent for each interval you want to define. + + +```yaml +# 2h = 20(t) × 60(s) × 60(m) × 2(h) = 144000t +scoreboard players set 2h ticks 144000 + +#10m = 20(t) × 60(s) × 10(m) = 12000t +scoreboard players set 10m ticks 12000 + +#30s = 20(t) × 30(s) = 600t +scoreboard players set 30s ticks 600 +``` +We will now use this scoreboard data to make our timers function. + +## System + +mcfunction + +```yaml +scoreboard players add timer ticks 1 +scoreboard players operation * events = timer ticks + +#Chat Message (every 2h) +scoreboard players operation chatMessage events %= 2h ticks +execute if score chatMessage events matches 0 run say Technoblade never dies! + +#Lag Clear (every 10m) +scoreboard players operation lagClear events %= 10m ticks +execute if score lagClear events matches 0 run function clear_lag + +#Speed Effect (every 30s) +scoreboard players operation speedEffect events %= 30s ticks +execute if score speedEffect events matches 0 run effect @a speed 10 2 true +``` +![commandBlockChain8](/assets/images/commands/commandBlockChain/8.png) + +Here we have taken 3 examples to give you an idea on how to do it, but you can add any timer you need and as many as you require. + +Just make sure to follow the given order and properly use the `/execute if score` command as shown to run the commands you need. + +## Explanation + +- **` events `** on this objective we label all the repeating events we want on our world. + - `chatMessage` + - `lagClear` + - `speedEffect` +- **` ticks `** on this objective we define all the intervals for our events and also run our scoreboard timer. + - ` 2h` interval (static score 144000) + - `10m` interval (static score 12000) + - `30s` interval (static score 600) + - `timer` clock (variable score n+1) + + +- **Command 1:** this command adds +1 score every tick to FakePlayer name `timer` indicating a tick has passed in the game. This is basically our scoreboard timer/clock which we will use for all the repeating events on our world. + + +- **Command 2:** here we copy `timer` score to all our events using the ` * ` wildcard selector. This will allow us to perform operations to determine if the interval has been reached to run the commands for that particular event. Example: + - If `timer` score is 1200 that means 1200 game ticks have passed. + - And this command makes it so all our events FakePlayer names: `chatMessage`, `lagClear`, `speedEffect` scores are also 1200. + + +- **Command 3:** we will use the ` %= ` modulo operation to check if our event score is divisible by it's corresponding interval. A number is said to be divisible when the remainder is 0. + - Chat Message: `1200/144000` Q=0, R=1200, *hence interval not reached.* + - Lag Clear: `1200/12000` Q=0, R=1200, *hence interval not reached.* + - Speed Effect: `1200/600` Q=2, R=0, *hence interval has reached and event commands can be executed.* +Here we can note that the first 2 events are yet to happen but the 3rd event is happening for the second time. +:::tip +In Minecraft; scoreboard division is only calculated up to whole numbers and decimal values are ignored. +![longDivision](/assets/images/commands/longDivision.png) +::: + + +- **Command 4:** the remainder value obtained from the calculation is applied to the corresponding event FakePlayer name. Based on this knowledge we can run our command if it's score is equal to 0. + +The rest of the commands are identical in structure and only the event labels and interval values are changed. + +## Defining Events With Limited Intervals + +To limit how many times an event occurs, you will need to create a new objective called `intervals` and define how many times the event should occur like so: + + +```yaml +scoreboard objectives set chatMessage intervals 5 +scoreboard objectives set speedEffect intervals 10 +``` + +Once you have done that, modify your system from above like so: + +mcfunction + +```yaml +scoreboard players add timer ticks 1 +scoreboard players operation * events = timer ticks + +#Chat Message (every 10m) +scoreboard players operation chatMessage events %= 2h ticks +execute if score chatMessage events matches 0 if score chatMessage intervals matches 1.. run say Technoblade never dies! +execute if score chatMessage events matches 0 if score chatMessage intervals matches 1.. run scoreboard players remove chatMessage intervals 1 + +#Speed Effect (every 30s) +scoreboard players operation speedEffect events %= 30s ticks +execute if score speedEffect events matches 0 if score speedEffect intervals matches 1.. run effect @a speed 10 2 true +execute if score speedEffect events matches 0 if score speedEffect intervals matches 1.. run scoreboard players remove speedEffect intervals 1 +``` +![commandBlockChain8](/assets/images/commands/commandBlockChain/8.png) + +## Executing Commands During Timeframe + +To run commands during the timeframe between intervals for a particular system you may do something like this: +mcfunction + +```yaml +#Speed Effect (every 30s) + Particle (every tick) +scoreboard players operation speedEffect events %= 30s ticks +execute if score speedEffect intervals matches 1.. as @a at @s run particle minecraft:shulker_bullet ~~~ +execute if score speedEffect events matches 0 if score speedEffect intervals matches 1.. run effect @a speed 10 2 true +execute if score speedEffect events matches 0 if score speedEffect intervals matches 1.. run scoreboard players remove speedEffect intervals 1 +``` +As shown in line 3; to run commands while the timer is running, all you need to do is remove the "if score" testing if the interval has been reached. And instead, only test if *any* interval is left, to run our commands. + +Let's say we had set the intervals for this event to 10, then that means players would also have particle trails for 300 seconds since `10*30s=300s` + +## Entity Timers + +In some cases such as an entity despawn event you will need to run timers for each entity individually rather than a synchronised timer which could cause the event to trigger too soon. In such cases an Async Timer can be helpful. + +Let's say we want to: +- kill all entities named "station" 5 minutes after they've been summoned. +- play a shulker particle around them during that timeframe. +- play a flame particle around them in the first 10 seconds. +- play a pling sound to nearby players when the timer reaches half way. +- stop the timer if a passive mob is nearby. +- loop the timer if a hostile mob is nearby. + +mcfunction + +```yaml +#Clock +scoreboard players add @e [name=station, scores={ticks=0..}] ticks 1 + +#Executing Commands while timer is running +execute as @e [name=station, scores={ticks=0..}] at @s run particle minecraft:shulker_bullet ~~~ + +#Executing commands within a timeframe +execute as @e [name=station, scores={ticks=0..200}] at @s run particle minecraft:basic_flame_particle ~~~ + +#Executing commands at specific intervals +execute as @e [name=station, scores={ticks=3600}] at @s run playsound note.pling @a [r=10] + +#Stopping the timer +execute as @e [name=station] at @s if entity @e [family=pacified, r=10, c=1] run scoreboard players set @s ticks -1 + +#Looping the timer +execute as @e [name=station, scores={ticks=6000}] at @s if entity @e [family=monster, r=10, c=1] run scoreboard players set @s ticks 0 + +#End +kill @e [name=station, scores={ticks=6000}] +``` +![commandBlockChain7](/assets/images/commands/commandBlockChain/7.png) + +As shown; setting the score to 0 when it completes the timeframe will loop the timer and setting the score to -1 will stop/disable it. You can still set the score to 0 to start the timer again. diff --git a/docs/wiki/commands/selectors.md b/docs/wiki/commands/selectors.md new file mode 100644 index 00000000..e3c348db --- /dev/null +++ b/docs/wiki/commands/selectors.md @@ -0,0 +1,217 @@ +--- +title: Understanding Selectors +category: General +mentions: + - Science-geek42 + - Brougud + - MedicalJewel105 + - SmokeyStack + - Sprunkles137 + - Hatchibombotar +--- + +Target selectors are used in commands to target who you want to execute a command on without explicitly setting a target, such as a player's name. A target selector is comprised of a selector variable, and optionally a list of selector arguments. + +## Selector Variables + +The selector variable defines the broad list of entities to select. There are six selector variables to choose from: +- `@a` - Target all players +- `@p` - Target the nearest player +- `@r` - Target a random player +- `@e` - Target all entities +- `@s` - Target the executor +- `@initiator` - Target the player interacting with an NPC + +## Selector Arguments + +Selector arguments can narrow down a list of target candidates to those who meet certain conditions. In order to use selector arguments, you must first have a selector variable. To start with selector arguments you must add square brackets `[]` to the end of the chosen target selector like this: `kill @e[]`. Multiple selector arguments can be used by separating them with commas. + +### Type +Limits the selection of targets by their identifier. Negating the argument selects entities without that identifier. This argument cannot be repeated unless negated, since a given entity can only have one identifier. This argument can be used with the selector `@r` to select entities randomly. + +- `type=`—Include only entities with the given identifier. +- `type=!`—Exclude any entities with the given identifier. + +Examples: + +Affect all pigs with levitation: +- `/effect @e[type=pig] levitation` + +Kill all entities that are not arrows and snowballs: +- `/kill @e[type=!arrow,type=!snowball]` + +### Count +Limits the number of selected entities, following selector sorting rules. + +The selectors `@a`, `@p`, and `@e` sort by increasing distance, while `@r` sorts randomly. For the variables `@p` and `@r`, this argument defaults to 1. Negating this argument reverses the sorting order; random sorting cannot be negated. + +- `c=`—Select up to `` entities. + +Examples: + +Clear stone from the closest five players: +- `/clear @a[c=5] stone` + +Damage the furthest two skeletons: +- `/damage @e[type=skeleton,c=-2] 2` + +### Position +Changes the position a selector starts its search at. It also modifies where the distance and volume arguments are positioned. Leaving any undefined defaults to the command's current position. + +[Relative coordinates](/commands/relative-coordinates#relative-coordinates) can be used to define a relative offset from the command's position. + +- `x=`, `y=`, and `z=`—Defines a position for the target selector. + +Examples: + +Teleport the closest player to (140, 64, -200) ten blocks up: +- `/teleport @p[x=140, y=64, z=-200] ~ ~10 ~` + +### Distance +Limits the selection of targets by their spherical distance from the selector. This selects entities by their feet. + +- `rm=` and `r=`—Selects entities between the minimum and maximum number of blocks away, inclusive and respectively. + +Examples: + +Kill all chickens between two and six blocks away: +- `/kill @e[type=chicken, rm=2, r=6]` + +Enchant the held item with Sharpness for all players within one block of (0, 100, 0): +- `/enchant @a[x=0, y=100, z=0, r=1] sharpness` + +### Volume +Limits the selection of targets to those inside of a cuboid volume aligned to the block grid. There are three arguments, each determining the size of the box along their respective axes. If at least one argument is defined, any remaining arguments left undefined are assumed to be 0. This selects entities by their feet. + +The general formula for calculating the volume between two positions can be viewed as: `dx = x2 - x1; dy = y2 - y1; dz = z2 - z1`. + +- `dx=`, `dy=`, and `dz=`—Selects entities inside the given bounding box. + +Examples: + +List all entities within a 12x30x2 box: +- `/say @e[dx=12, dz=30, dy=2]` + +Add the "lobby" tag to all players between (-400, 0, -350) and (-150, 256, 50): +- `/tag @a[x=-400, y=0, z=-350, dx=250, dy=256, dz=400] add lobby` + +### Scores +Limits the selection of targets by their score value. This argument is represented as an object, with key-value pairs for a scoreboard objective and a value. The value can represent a range of numbers, using the range syntax. The value of a score can be negated to test if the entity does not have a score value within that range. + +- `scores={=}`—Selects entities whose score under the given objective matches the given value. + +The range syntax works as follows: +- `N..` is any number greater than or equal to N. +- `..N` is any number less than or equal to N. +- `N..M` is any number between N and M, inclusive. + +Examples: + +Set the "points" score for all players with a "points" score of ten to 0: +- `/scoreboard players set @p[scores={points=10}] points 0` + +Add the "start" tag to armor stands with both a "started" score of one, and a "timer" score of 20 or less: +- `/tag @e[type=armor_stand, scores={started=1, timer=..20}] add start` + +### Name +Limits the selection of targets by name. Negating the argument selects entities whose name does not match. + +- `name=`—Include only entities with the given name. +- `name=!`—Exclude any entities with the given name. + +Examples: + +List all zombies named Shadow: +- `/say @e[type=zombie, name=Shadow]` + +Give one level to players both not named Steve and not named Alex: +- `/xp 1L @a[name=!Steve, name=!Alex]` + +### Tag +Limits the selection of targets by their tags. This argument can be repeated to test for multiple tags, and all filters must pass for an entity to be selected. Negating this argument selects entities without that tag. + +- `tag=`—Include only entities with the given tag. +- `tag=!`—Exclude any entities with the given tag. + +Examples: + +Kill all mobs with the tag "marked", and without the tag "exempt": +- `/kill @e[tag=marked, tag=!exempt]` + +### Family +Limits the selection of targets by type family. This argument can be repeated to test for multiple families, and all filters must pass for an entity to be selected. Negating this argument selects entities whose type family does not match. + +- `family=`—Include only entities with the given type family. +- `family=!`—Exclude any entities with the given type family. + +Examples: + +Affect all entities in the "monster" family with Regeneration: +- `/effect @e[family=monster] regeneration` + +### Rotation +Limits the selection of targets by their rotation. There are two types of rotation: x-rotation, which is vertical rotation around the x-axis; and y-rotation, which is horizontal rotation around the y-axis. X-rotation ranges between -90 and 90 (180° total), going from looking up to down; and y-rotation ranges between -180 and 180 (360° total), starting and ending at North, wrapping around clockwise. + +- `rxm=` and `rx=`—Selects entities whose x-rotation is between the minimum and maximum values, inclusive and respectively. +- `rym=` and `ry=`—Selects entities whose y-rotation is between the minimum and maximum values, inclusive and respectively. + +Examples: + +Affect all players looking at or above the horizon with Blindness for one second: +- `/effect @a[rx=0] blindness 1` (0 or less) + +Damage all players facing generally south: +- `/damage @a[rym=-45, ry=45] 1` + +### Level +Limits the selection of targets by experience levels. Only players can have EXP, so this filters out non-player targets. + +- `lm=` and `l=`—Selects players whose EXP levels are between the minimum and maximum values specified, inclusive and respectively. + +Examples: + +Give all players who have between three and eight levels a diamond: +- `/give @a[lm=3, l=8] diamond` + +### Game mode +Limits the selection of targets by game mode. Only players can use game mode, so this filters out non-player targets. Negating the argument selects targets whose game mode does not match. + +- `m=`—Selects players by their game mode. + +Possible values include: +* `0`, `s`, or `survival` for Survival mode +* `1`, `c`, or `creative` for Creative mode +* `2`, `a`, or `adventure` for Adventure mode +* `spectator` for Spectator mode +* `d` or `default` for the default game mode + +Examples: + +List all players in Creative mode: +- `/say @a[m=creative]` + +Set the game mode to Creative mode for players both not in Survival mode, and not in Adventure mode: +- `/gamemode creative @a[m=!survival, m=!adventure]` + +### Items +Limits the selection of targets by what items they have in their inventory. This argument is represented as an object, or an array of objects, with up to one each of the following parameters: + +- `item=`—The identifier of the item to test for, and the only required argument. This can accept custom identifiers too. +- `quantity=`—The amount of the item to test for. Accepts a [range](/commands/selectors#scores) for a value. This argument can also be negated. +- `data=`—The data value of the item to test for. Defaults to -1. **Currently not functional:** [MCPE-151920](https://bugs.mojang.com/browse/MCPE-151920) +- `location=`—The slot the item should be located in. Accepts the same arguments as the slotType argument in the `/replaceitem` command. +- `slot=`—The index of the slot used in the "location" argument, and can only be used with "location". Accepts a range for a value. This argument can be negated. + +Examples: + +Checks for players who have a netherite sword in their inventory: +- `/testfor @a[hasitem={item=netherite_sword}]` + +Clears 2 apples for players that have four or more apples: +- `/clear @a[hasitem={item=apple,quantity=4..}] apple 2` + +Checks for players who have two sticks and two diamonds: +- `/testfor @a[hasitem=[{item=diamond,quantity=2},{item=stick,quantity=2}]]` + +Checks for players who doesn't have a stick: +- `/testfor @a[hasitem=[{item=stick,quantity=0}]` diff --git a/docs/wiki/commands/tellraw.md b/docs/wiki/commands/tellraw.md new file mode 100644 index 00000000..25618f30 --- /dev/null +++ b/docs/wiki/commands/tellraw.md @@ -0,0 +1,132 @@ +--- +title: Tellraw +category: Commands +mentions: + - SirLich + - Dreamedc2015 + - MedicalJewel105 + - Luthorius + - Fabrimat + - Sprunkles137 + - ThomasOrs + - zheaEvyline + - SmokeyStack +--- + +tellraw sends a JSON message to selected or all players being useful for sending plain messages to players ingame + +**The titleraw command follows the same theme** + +![](/assets/images/documentation/tellrawshow.png) + + +## Format + +this is how the tell raw command is formatted + +``` +tellraw +``` + +- ` `: The target is expressed as a playername or player groups such as `@a` `@r` `@s` `@p` +- ``: This is a json schema that tells how the message is structured or constructed. expressed with for example: + `{"rawtext":[{"text":""}]}` + + +## Examples + +This sends the words in the last set of quotes + + + +```json +/tellraw @a {"rawtext":[{"text":"Hello"}]} +``` + + +## Escaping Characters + +To use quotations in a tellraw message place a backslash to the left side of the quotation mark. + + + +```json +/tellraw @a {"rawtext":[{"text":"Quote me: \"I am here\"."}]} +``` + + +## Line breaks + +To insert a line break use `\n` + + + +```json +/tellraw @a { "rawtext": [ { "text":"I am line one\nI am line two" } ] } +``` + + +## Displaying entities / player + +You can use the following to use selector to display names. + + + +```json +/tellraw @a {"rawtext": [{"text": "§6The winner is: §a"}, {"selector": "@a[r=5,c=1]"}]} +``` + + +## Displaying scores + +You can use the following to use selector to display names. + + + +```json +/tellraw @a {"rawtext": [{"text": "§6The winner is: §a"}, {"selector": "@a[r=5,c=1]"}, {"text": "§6With a score of: "}, {"score":{"name": "@s","objective": "value"}}]} +``` + + +## Translate text + +To have a language dependant text you can use the translate component and [translation keys](/concepts/text-and-translations). please note you will need relevant information in each of the desired .lang files for this to work. + + +RP/texts/en_US.lang + +``` +example.langcode.1=I am line one +``` + +RP/texts/de_DE.lang + +``` +example.langcode.1=Ich bin Zeile eins +``` + + +The command: + + + +```json +/tellraw @a { "rawtext": [ { "translate": "example.langcode.1" } ] } +``` + + +## Translate text with selectors/scores + +language files: + + + +``` +example.langcode.2=The winner is: %s. With a score of %s +``` + + + +```json +/tellraw @a {"rawtext":[{"translate":"example.langcode.2","with":{"rawtext":[{"selector":"@a[r=5,c=1]"},{"text":"§6With a score of: "},{"score":{"name":"@s","objective":"value"}}]}}]} +``` diff --git a/docs/wiki/concepts/contents.md b/docs/wiki/concepts/contents.md new file mode 100644 index 00000000..cbcc54cf --- /dev/null +++ b/docs/wiki/concepts/contents.md @@ -0,0 +1,84 @@ +--- +title: contents.json +mentions: + - MedicalJewel105 + - Osaxely + - SirLich + - solvedDev + - Joelant05 + - Jorginhor + - TheItsNameless +--- + +`contents.json` is a file that is _probably_ used for the game to process the pack files more easily. It is _probably_ intended for marketplace content creators and Mojang, it is not required to have this file in the pack for the pack to work properly. + +You will find there some instructions about the usage of this file. + +## Structure of the file + +`contents.json` is located at the root of the add-on directory. It contains a list of the files that are included in the pack. +Example: + +RP/contents.json + +```json +{ + "content": [ + { + "path": "texts/en_US.lang" + }, + { + "path": "contents.json" + }, + { + "path": "manifest.json" + }, + { + "path": "animations/my_animation.animation.json" + }, + { + "path": "animation_controllers/my_ac.ac.json" + }, + { + "path": "entity/my_entity.entity.json" + }, + { + "path": "textures/textures_list.json" + }, + { + "path": "textures/blocks/my_block.png" + } + ] +} +``` + + + +## Automatizing the process + +The `contents.json` file can be generated automatically by the game itself, it is very recommended to decrease the risks of making mistakes. However, the file must be prepared first. Create a new empty file called `contents.json` in the root directory of your add-on, and add empty brackets. + +BP|RP/contents.json + +```json +{} +``` + +The file content will be automatically written next time the game is launched. + +## Additional information + +- The automatic process can be achieved no matter what is the location of the pack (Development folders or normal folders). +- Do not make multiple `contents.json` for subpacks, the file at the root of the pack is sufficient. +- This file is not required for the addon to work properly. diff --git a/docs/wiki/concepts/emojis.md b/docs/wiki/concepts/emojis.md new file mode 100644 index 00000000..f14870e9 --- /dev/null +++ b/docs/wiki/concepts/emojis.md @@ -0,0 +1,289 @@ +--- +title: Emojis & Symbols +mentions: + - SirLich + - Joelant05 + - sovledDev + - stirante + - Dreamedc2015 + - MedicalJewel105 + - JaylyDev + - RealBashy21 + - ColinTimBarndt + - Citicx + - TheItsNameless + - ThomasOrs +--- + +:::warning +Modifying texture of vanilla emojis and symbols on this page are incompatible with Nintendo Switch platform! +::: + +Minecraft has a bunch of hard-coded [Private Use Unicode symbols](https://en.wikipedia.org/wiki/Private_Use_Areas) that it automatically converts to Emoji-like symbols. +These can be used anywhere where normal letters can - signs, books, item names, chat, etc. + +Below you can find platform specific Emoji's, as well as general symbols. Copy/paste the "box" character under the Letter colum directly into Minecraft. + +There will be instructions for creating custom emoji at the bottom. + +### HUD + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ----------------- | ------------------------ | ------- | ------------------------------------------------- | +| Food |  | U+E100 | ![](/assets/images/concepts/emojis/hud/food.png) | +| Armor |  | U+E101 | ![](/assets/images/concepts/emojis/hud/armor.png) | +| Heart |  | U+E10C | ![](/assets/images/concepts/emojis/hud/heart.png) | + + +### Items & Blocks + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| -------------- | ------------------------ | ------- | ------------------------------------------------------------ | +| Wooden Pickaxe |  | U+E108 | ![](/assets/images/concepts/emojis/items/wooden_pickaxe.png) | +| Wooden Sword |  | U+E109 | ![](/assets/images/concepts/emojis/items/wooden_sword.png) | +| Crafting Table |  | U+E10A | ![](/assets/images/concepts/emojis/items/crafting_table.png) | +| Furnace |  | U+E10B | ![](/assets/images/concepts/emojis/items/furnace.png) | + + +### Marketplace + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ---------------- | ------------------------ | ------- | ------------------------------------------------------------ | +| Minecoin |  | U+E102 | ![](/assets/images/concepts/emojis/marketplace/minecoin.png) | +| Token |  | U+E105 | ![](/assets/images/concepts/emojis/marketplace/token.png) | + + +### Inventory + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ---------------- | ------------------------ | ------- | ------------------------------------------------------------------ | +| Craft Toggle On |  | U+E0A0 | ![](/assets/images/concepts/emojis/inventory/craft_toggle_on.png) | +| Craft Toggle Off |  | U+E0A1 | ![](/assets/images/concepts/emojis/inventory/craft_toggle_off.png) | + + +### New Touch + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ----------------- | ------------------------ | ------- | ---------------------------------------------------------- | +| Jump |  | U+E014 | ![](/assets/images/concepts/emojis/new_touch/jump.png) | +| Attack |  | U+E015 | ![](/assets/images/concepts/emojis/new_touch/attack.png) | +| Joy Stick |  | U+E016 | ![](/assets/images/concepts/emojis/new_touch/joystick.png) | +| Place |  | U+E018 | ![](/assets/images/concepts/emojis/new_touch/place.png) | +| Sneak |  | U+E019 | ![](/assets/images/concepts/emojis/new_touch/sneak.png) | +| Sprint |  | U+E01A | ![](/assets/images/concepts/emojis/new_touch/sprint.png) | +| Fly Up |  | U+E01B | ![](/assets/images/concepts/emojis/new_touch/fly_up.png) | +| Fly Down |  | U+E01C | ![](/assets/images/concepts/emojis/new_touch/fly_down.png) | +| Dismount |  | U+E01D | ![](/assets/images/concepts/emojis/new_touch/dismount.png) | + + +### Touch + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ----------------- | ------------------------ | ------- | ------------------------------------------------------------- | +| Jump |  | U+E084 | ![](/assets/images/concepts/emojis/touch/jump.png) | +| Crouch |  | U+E085 | ![](/assets/images/concepts/emojis/touch/crouch.png) | +| Fly Up |  | U+E086 | ![](/assets/images/concepts/emojis/touch/fly_up.png) | +| Fly Down |  | U+E087 | ![](/assets/images/concepts/emojis/touch/fly_down.png) | +| Stop Flying |  | U+E088 | ![](/assets/images/concepts/emojis/touch/stop_flying.png) | +| Left Arrow |  | U+E081 | ![](/assets/images/concepts/emojis/touch/left_arrow.png) | +| Right Arrow |  | U+E083 | ![](/assets/images/concepts/emojis/touch/right_arrow.png) | +| Up Arrow |  | U+E080 | ![](/assets/images/concepts/emojis/touch/up_arrow.png) | +| Down Arrow |  | U+E082 | ![](/assets/images/concepts/emojis/touch/down_arrow.png) | +| Small Jump |  | U+E059 | ![](/assets/images/concepts/emojis/touch/smalljump.png) | +| Small Crouch |  | U+E05A | ![](/assets/images/concepts/emojis/touch/smallcrouch.png) | +| Small Fly Up |  | U+E05C | ![](/assets/images/concepts/emojis/touch/smallflyup.png) | +| Small Fly Down |  | U+E05D | ![](/assets/images/concepts/emojis/touch/smallflydown.png) | +| Small Left Arrow |  | U+E056 | ![](/assets/images/concepts/emojis/touch/smallleftarrow.png) | +| Small Right Arrow |  | U+E058 | ![](/assets/images/concepts/emojis/touch/smallrightarrow.png) | +| Small Up Arrow |  | U+E055 | ![](/assets/images/concepts/emojis/touch/smalluparrow.png) | +| Small Down Arrow |  | U+E057 | ![](/assets/images/concepts/emojis/touch/smalldownarrow.png) | +| Small Inventory |  | U+E05B | ![](/assets/images/concepts/emojis/touch/smallinventory.png) | + + +### Keyboard & Mouse + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ------------------ | ------------------------ | ------- | ------------------------------------------------------------------- | +| Left Click |  | U+E060 | ![](/assets/images/concepts/emojis/keyboard/left_click.png) | +| Right Click |  | U+E061 | ![](/assets/images/concepts/emojis/keyboard/right_click.png) | +| Middle Click |  | U+E062 | ![](/assets/images/concepts/emojis/keyboard/middle_click.png) | +| Small Left Click |  | U+E070 | ![](/assets/images/concepts/emojis/keyboard/small_left_click.png) | +| Small Right Click |  | U+E071 | ![](/assets/images/concepts/emojis/keyboard/small_right_click.png) | +| Small Middle Click |  | U+E072 | ![](/assets/images/concepts/emojis/keyboard/small_middle_click.png) | +| Small Mouse |  | U+E073 | ![](/assets/images/concepts/emojis/keyboard/small_mouse.png) | + + +### Xbox + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ------------------ | ------------------------ | ------- | ---------------------------------------------------------- | +| Y |  | U+E003 | ![](/assets/images/concepts/emojis/xbox/y_button.png) | +| B |  | U+E001 | ![](/assets/images/concepts/emojis/xbox/b_button.png) | +| A |  | U+E000 | ![](/assets/images/concepts/emojis/xbox/a_button.png) | +| X |  | U+E002 | ![](/assets/images/concepts/emojis/xbox/x_button.png) | +| Back |  | U+E008 | ![](/assets/images/concepts/emojis/xbox/back.png) | +| Start |  | U+E009 | ![](/assets/images/concepts/emojis/xbox/start.png) | +| LB (Left Bumper) |  | U+E004 | ![](/assets/images/concepts/emojis/xbox/left_bumper.png) | +| RB (Right Bumper) |  | U+E005 | ![](/assets/images/concepts/emojis/xbox/right_bumper.png) | +| LT (Left Trigger) |  | U+E006 | ![](/assets/images/concepts/emojis/xbox/left_trigger.png) | +| RT (Right Trigger) |  | U+E007 | ![](/assets/images/concepts/emojis/xbox/right_trigger.png) | +| LS (Left Stick) |  | U+E00A | ![](/assets/images/concepts/emojis/xbox/left_stick.png) | +| RS (Right Stick) |  | U+E00B | ![](/assets/images/concepts/emojis/xbox/right_stick.png) | +| D-pad Up |  | U+E00C | ![](/assets/images/concepts/emojis/xbox/dpad_up.png) | +| D-pad Right |  | U+E00F | ![](/assets/images/concepts/emojis/xbox/dpad_right.png) | +| D-pad Down |  | U+E00E | ![](/assets/images/concepts/emojis/xbox/dpad_down.png) | +| D-pad Left |  | U+E00D | ![](/assets/images/concepts/emojis/xbox/dpad_left.png) | + + +### Nintendo Switch + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ------------------ | ------------------------ | ------- | ------------------------------------------------------------ | +| X |  | U+E042 | ![](/assets/images/concepts/emojis/switch/x_button.png) | +| A |  | U+E040 | ![](/assets/images/concepts/emojis/switch/a_button.png) | +| B |  | U+E041 | ![](/assets/images/concepts/emojis/switch/b_button.png) | +| Y |  | U+E043 | ![](/assets/images/concepts/emojis/switch/y_button.png) | +| + |  | U+E049 | ![](/assets/images/concepts/emojis/switch/plus.png) | +| - |  | U+E048 | ![](/assets/images/concepts/emojis/switch/minus.png) | +| L (Left Bumper) |  | U+E044 | ![](/assets/images/concepts/emojis/switch/left_bumper.png) | +| R (Right Bumper) |  | U+E045 | ![](/assets/images/concepts/emojis/switch/right_bumper.png) | +| ZL (Left Trigger) |  | U+E046 | ![](/assets/images/concepts/emojis/switch/left_trigger.png) | +| RL (Right Trigger) |  | U+E047 | ![](/assets/images/concepts/emojis/switch/right_trigger.png) | +| L (Left Stick) |  | U+E04A | ![](/assets/images/concepts/emojis/switch/left_stick.png) | +| R (Right Stick) |  | U+E04B | ![](/assets/images/concepts/emojis/switch/right_stick.png) | +| D-pad Up |  | U+E04C | ![](/assets/images/concepts/emojis/switch/dpad_up.png) | +| D-pad Right |  | U+E04F | ![](/assets/images/concepts/emojis/switch/dpad_right.png) | +| D-pad Down |  | U+E04E | ![](/assets/images/concepts/emojis/switch/dpad_down.png) | +| D-pad Left |  | U+E04D | ![](/assets/images/concepts/emojis/switch/dpad_left.png) | + + +### PlayStation (4/5) + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ------------------ | ------------------------ | ------- | ----------------------------------------------------------------- | +| Triangle |  | U+E023 | ![](/assets/images/concepts/emojis/playstation/triangle.png) | +| Circle |  | U+E021 | ![](/assets/images/concepts/emojis/playstation/circle.png) | +| Cross |  | U+E020 | ![](/assets/images/concepts/emojis/playstation/cross.png) | +| Square |  | U+E022 | ![](/assets/images/concepts/emojis/playstation/square.png) | +| Options/Share |  | U+E029 | ![](/assets/images/concepts/emojis/playstation/options_share.png) | +| Touch Pad |  | U+E028 | ![](/assets/images/concepts/emojis/playstation/touch_pad.png) | +| L1 (Left Bumper) |  | U+E024 | ![](/assets/images/concepts/emojis/playstation/left_bumper.png) | +| R1 (Right Bumper) |  | U+E025 | ![](/assets/images/concepts/emojis/playstation/right_bumper.png) | +| L2 (Left Trigger) |  | U+E026 | ![](/assets/images/concepts/emojis/playstation/left_trigger.png) | +| R2 (Right Trigger) |  | U+E027 | ![](/assets/images/concepts/emojis/playstation/right_trigger.png) | +| L3 (Left Stick) |  | U+E02A | ![](/assets/images/concepts/emojis/playstation/left_stick.png) | +| R3 (Right Stick) |  | U+E02B | ![](/assets/images/concepts/emojis/playstation/right_stick.png) | +| D-pad Up |  | U+E02C | ![](/assets/images/concepts/emojis/playstation/dpad_up.png) | +| D-pad Right |  | U+E02F | ![](/assets/images/concepts/emojis/playstation/dpad_right.png) | +| D-pad Down |  | U+E02E | ![](/assets/images/concepts/emojis/playstation/dpad_down.png) | +| D-pad Left |  | U+E02D | ![](/assets/images/concepts/emojis/playstation/dpad_left.png) | + + +### Oculus (Rift/Rift S) + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ------------------ | ------------------------ | ------- | ------------------------------------------------------------ | +| 0 |  | U+E0E0 | ![](/assets/images/concepts/emojis/oculus/0_button.png) | +| B |  | U+E0E2 | ![](/assets/images/concepts/emojis/oculus/b_button.png) | +| A |  | U+E0E1 | ![](/assets/images/concepts/emojis/oculus/a_button.png) | +| Y |  | U+E0EA | ![](/assets/images/concepts/emojis/oculus/y_button.png) | +| X |  | U+E0E9 | ![](/assets/images/concepts/emojis/oculus/x_button.png) | +| LG (Left Grip) |  | U+E0E3 | ![](/assets/images/concepts/emojis/oculus/left_grip.png) | +| RG (Right Grip) |  | U+E0E4 | ![](/assets/images/concepts/emojis/oculus/right_grip.png) | +| LT (Left Trigger) |  | U+E0E7 | ![](/assets/images/concepts/emojis/oculus/left_trigger.png) | +| RT (Right Trigger) |  | U+E0E8 | ![](/assets/images/concepts/emojis/oculus/right_trigger.png) | +| LS (Left Stick) |  | U+E0E5 | ![](/assets/images/concepts/emojis/oculus/left_stick.png) | +| RS (Right Stick) |  | U+E0E6 | ![](/assets/images/concepts/emojis/oculus/right_stick.png) | + + +### Windows MR (Mixed Reality) + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ------------------------- | ------------------------ | ------- | --------------------------------------------------------------------------- | +| Menu |  | U+E0C2 | ![](/assets/images/concepts/emojis/windowsMR/menu.png) | +| Windows |  | U+E0CD | ![](/assets/images/concepts/emojis/windowsMR/windows.png) | +| Left Touchpad |  | U+E0C5 | ![](/assets/images/concepts/emojis/windowsMR/left_touchpad.png) | +| Left Horizontal Touchpad |  | U+E0C6 | ![](/assets/images/concepts/emojis/windowsMR/left_touchpad_horizontal.png) | +| Left Vertical Touchpad |  | U+E0C7 | ![](/assets/images/concepts/emojis/windowsMR/left_touchpad_vertical.png) | +| Right Touchpad |  | U+E0C8 | ![](/assets/images/concepts/emojis/windowsMR/right_touchpad.png) | +| Right Horizontal Touchpad |  | U+E0C9 | ![](/assets/images/concepts/emojis/windowsMR/right_touchpad_horizontal.png) | +| Right Vertical Touchpad |  | U+E0CA | ![](/assets/images/concepts/emojis/windowsMR/right_touchpad_vertical.png) | +| LT (Left Trigger) |  | U+E0CB | ![](/assets/images/concepts/emojis/windowsMR/left_trigger.png) | +| RT (Right Trigger) |  | U+E0CC | ![](/assets/images/concepts/emojis/windowsMR/right_trigger.png) | +| LG (Left Grab) |  | U+E0C0 | ![](/assets/images/concepts/emojis/windowsMR/left_grab.png) | +| RG (Right Grab) |  | U+E0C1 | ![](/assets/images/concepts/emojis/windowsMR/right_grab.png) | +| LS (Left Stick) |  | U+E0C3 | ![](/assets/images/concepts/emojis/windowsMR/left_stick.png) | +| RS (Right Stick) |  | U+E0C4 | ![](/assets/images/concepts/emojis/windowsMR/right_stick.png) | + + +### Other + +| Name | Letter (Copy/Paste This) | Unicode | Image | +| ---------------- | ------------------------ | ------- | -------------------------------------------------------------- | +| Crosshair |  | U+E017 | ![](/assets/images/concepts/emojis/other/crosshair.png) | +| Agent |  | U+E103 | ![](/assets/images/concepts/emojis/other/agent.png) | +| Immersive Reader |  | U+E104 | ![](/assets/images/concepts/emojis/other/immersive_reader.png) | +| Hollow Star |  | U+E106 | ![](/assets/images/concepts/emojis/other/hollow_star.png) | +| Solid Star |  | U+E107 | ![](/assets/images/concepts/emojis/other/solid_star.png) | + + +## Custom Emoji + +::: warning +This method is not officially supported. Use with caution on the Marketplace! +::: + +To make a custom emoji, we use a very similar method to the pre-built emoji, except instead of using the Microsoft sprite-sheets, we overwrite them with our own! Some _character-slots_ are already used up with the emoji above, but there are blank slots we can use. + +Please note that the following files have been annotated with slot information: If you use them directly, existing Emoji will have numbers added on top of them. If you need the original sprite-sheets, you can get them from the Vanilla Resources on your system (not included in the Vanilla Resource Pack downloads). + +To get started, you should download the sprite-sheets, and move them into the fonts folder. + +Two sprite-sheets are provided for each glyph-target: One that accurately reflects vanilla, and a second version which has been annotated with hex information, for easily finding the correct character. + +### RP/font/glyph_E0.png + +![](/assets/images/concepts/emojis/custom/annotated/glyph_E0.png) +![](/assets/images/concepts/emojis/custom/glyph_E0.png) + +### RP/font/glyph_E1.png + +![](/assets/images/concepts/emojis/custom/annotated/glyph_E1.png) +![](/assets/images/concepts/emojis/custom/glyph_E1.png) + +Your filepath should look like this: + + + +### Finding the correct hex. + +Once you have emojis inside the `glyph_E0.png` or `glyph_E1.png` you need to find your character "code" so it can be converted. + +The first two characters are always `0x`. + +The next two characters are either `E0` or `E1`, depending on which file you added emojis to. + +The next two characters are the position inside the image like ``, where each character is a number in hexadecimal numeral system. You can find this number by referencing the images above. For example, the top-right square in `E0` is `0F`, and the bottom right is `FF`. + +So after you are done, it might look like `0xE102` (`0x` + `E1` + `02`). + +Copy this code into the following field, and press Convert. The symbol on the right-hand side can be copy/pasted into MC. + +
+
+ + +Convert +
+
+ +### Glyph Separation Space + +Sometimes, it appears that if you put 2 glyphs near to each other, there will be a couple of empty pixels between them. The only fix for it is to scale the glyph itself. diff --git a/docs/wiki/concepts/index.md b/docs/wiki/concepts/index.md new file mode 100644 index 00000000..ec28707f --- /dev/null +++ b/docs/wiki/concepts/index.md @@ -0,0 +1,3 @@ +--- +title: Concepts +--- diff --git a/docs/wiki/concepts/molang.md b/docs/wiki/concepts/molang.md new file mode 100644 index 00000000..d41fee76 --- /dev/null +++ b/docs/wiki/concepts/molang.md @@ -0,0 +1,47 @@ +--- +title: Molang +tags: + - intermediate +mentions: + - yanasakana + - TheDoctor15 + - MedicalJewel105 + - DoubleShotgun + - Luthorius + - TheItsNameless +--- + +## Introduction +Pretty much everything evaluates to a number; if something doesn't evaluate to a number, you can use an `operator` to make it into one. You can basically just think of Molang as one big math equation. + +An equation evaluates to `true` when any number except `0` is returned. When I reference `returning`, I'm talking about the output of an equation. There is also a `return` statement, but I don't usually use it, and will therefore not be talking about it. + +## Accessing Values +There are three main ways to access and use values in Molang (queries, variables and temp variables) + +- **Queries** are read only values returned by the game. You cannot set these values, only read them. (`query.example_query` | `q.example_query`) + +- **Variables** are read and write values that you can manipulate, these can be set and read through Molang. (`variable.example_variable` | `v.example_variable`) + - There are also hard-coded variables which act practically the same way as queries, but can only be used in certain situations. + +- **Temp. Variables** are practically the same as variables, except they only exist in the current scope. (`temp.example_temp` | `t.example_temp`) + - A "scope" can refer to the current `for_each` or `loop` *or* just the current expression, if it's not used within either + +## Handling values + +- **Logical Operators** can be used to convert non-numbers into 1s or 0s. These include: `==`, `!=`, `<`, `>`, `<=`, `>=`. + - Example.) "`q.get_equipped_item_name == 'stick'`" Will evaluate to `1`/`true` when holding a stick + + - There is also a *second* set of *Logical Operators* which can be used to 'group' values into `and/or` statements, often used in cases where you need *multiple* things to evaluate to `true` or just *one out of many*. `&&` represents an `and` statement, and `||` represents an `or` statement. + - Example.) "`q.is_sneaking && q.is_using_item`" Will evaluate to `1`/`true` when sneaking *and* using an item + - Example.) "`q.is_sneaking || q.is_jumping`" // Evaluates to `1`/`true` when either jumping *or* sneaking + +- **Parentheses**, `( )`, are also a major help when grouping values or performing math operations. + - Example.) "`q.is_sneaking && (q.get_equipped_item_name == "stick" || q.get_equipped_item_name == "diamond")`" Will evaluate to `1`/`true` when sneaking *and* holding either a stick *or* a diamond + +- **Conditional Operators** can be used as `if/else` statements. + - A *binary* conditional operator refers to just using `?`. When this is used, it'll output your value or `0` depending on whether the given input value is `true`. + - Example.) "`q.is_sneaking ? 5`" Will output a `5` when sneaking, otherwise returning a `0` + - A *trinary* conditional operator refers to using `?` and `:`. When this is used, it'll output one of the two given values depending on whether your given input value is `true`. + - Example.) "`q.is_sneaking ? 10 : 3`" Will output a `10` when sneaking, otherwise returning a `3` + diff --git a/docs/wiki/concepts/namespaces.md b/docs/wiki/concepts/namespaces.md new file mode 100644 index 00000000..f2b7ac92 --- /dev/null +++ b/docs/wiki/concepts/namespaces.md @@ -0,0 +1,51 @@ +--- +title: Namespaces +mentions: + - SirLich + - MedicalJewel105 +--- + +Namespaces are identifiers that mark content ownership. You can think of them as folders. Namespaces are helpful because they keep naming conflicts from happening. + +Namespaces in addon creation can essentially be thought of as "the part to the left of the colon". For example, `minecraft` is the namespace of `minecraft:zombie`. The general form is `namespace:name`. + +As a concrete example of why namespaces are helpful, let's imagine you create a new Mob. You name it `minecraft:shark`, not aware that you should create your own namespace for custom content. Next year, Mojang decides to add sharks into the game! Now there is a naming conflict since there are two definitions of `minecraft:shark`. Your addon will break. + +If you had instead used `your_namespace:shark`, the naming conflict wouldn't have happened. + +## Picking a namespace + +A suitable namespace is unique to you. Something like `mob` or `cars` or `content` or `custom` would be a **bad** namespace since another developer might come up with the same namespace as you. + +A suitable namespace is short. You will be writing your namespace a **LOT**, so the shorter, the better. `george_carlin_the_comedian` would be a lousy namespace for this reason. + +For personal projects, I recommend a convenient version of your player name, and for commercial projects, I recommend a suitable version of the company name. + +Some good examples: + +- `gcarlin` +- `sirlich` +- `cubeworld` +- `bworks` + +**DO NOT USE** `minecraft` or `minecon` as a namespace unless editing a vanilla file. Not only is it a terrible idea, but Minecraft reserves these, and it won't even work. + +## Where to use namespaces? + +In short, you should use namespaces as often as you can. + +For starters, you should use a namespace when adding custom entities to the game. + +`sirlich:shark` is much better than `shark`. + +It would be best if you also used namespaces for components and events. Just like Mojang uses `minecraft:pig_saddled` you should use `namespace:my_mob_event`, and `namespace:my_component_group`. + +It would be best if you also used namespaces in animation controllers, render controllers, and animations. + +For example: `controller.animation.namespace.entity_name.action` is better than `controller.animation.my_action`. + +## Where NOT to use namespaces. + +The actual file structure does not need namespaces. + +`animations/namespace/my_entity/animation` is more confusing than `animations/my_entity/animation`. diff --git a/docs/wiki/concepts/overwriting-assets.md b/docs/wiki/concepts/overwriting-assets.md new file mode 100644 index 00000000..2ce034fd --- /dev/null +++ b/docs/wiki/concepts/overwriting-assets.md @@ -0,0 +1,120 @@ +--- +title: Overwriting Assets +tags: + - intermediate +mentions: + - SirLich + - MedicalJewel105 + - Luthorius + - SmokeyStack +--- + +## Addon Layering + +The addon system is built layer by layer, where each pack is added _on top_ of the ones before it. Even if you only have a single pack added, there is an implicit _vanilla_ pack which is always added. When you add custom content, this content will have full access to all vanilla files. + +### Accessing Vanilla Files + +This layered structure is very useful, because it allows us to access the files inside of vanilla, without copy/pasting them into our addon. For example you can access `blocks/stone.png` without moving it into your addon! Just set it as the texture for your custom entity - it will work out of the box. This is particularly useful for things like models, or render controllers, or sounds. + +If the vanilla assets change, for example if [JAPPA](https://twitter.com/JasperBoerstra?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor) updates the stone texture, your addon will also receive the update, since you are relying on the actual dynamic, vanilla resources. + +You should try to use this system of layering as often as you can. If you don't *need* to copy/paste something into your addon, don't. + +:::warning +It is never OK to make an addon inside of a copy of the vanilla resource/behavior pack. This will make the download for your addon incredibly huge, and will reduce performance. Always begin with a blank addon, then copy/paste the files you want to overwrite. +::: + +## Overwriting Assets + +Pack Layering also allows us to overwrite vanilla assets, by _overwriting_ them with a file that shares the same path, or the same identifier. Our new file will replace the one being used in vanilla, allowing us to change textures, sounds, entity behavior, etc. + +:::warning +Different resources have different methods of overwriting, so be careful to use the right method for each type! +::: + +### Overwriting by Path + +Assets that are referenced by _path_, and do _not have an identifier_ can be overwritten by simply placing a new asset into the same path. The following can be overwritten in this way: + +- Functions +- Loot tables +- Textures +- Sounds +- Trade Tables + +When you overwrite these files, the overwriting is absolute: The new asset will fully replace the old asset. + +:::tip +**Example**: If you would like to replace the redstone ore texture, simply place a new file at `textures/blocks/redstone_ore.png`. +::: + +### Overwriting by Identifier + +Many assets are defined not by their name, but by their identifier! To overwrite these assets, simply create a new file that shares the same identifier, regardless of file-path. The following can be overwritten in this way: + +- BP Entities +- RP Entities +- Animations +- Models +- Animation Controllers +- Spawn Rules +- Recipes +- Particles +- Render Controllers + +When you overwrite these files, the overwriting is absolute: The new asset will fully replace the old asset. + +:::tip +**Example**: If you would like to make Ghasts have higher health, simply create a new BP entity with the `minecraft:ghast` identifier, and all the behaviors required to make the ghast function. + +Remember, entity files do not merge together, so you will first need to copy/paste the entire BP Ghast file, and _then_ edit the health. Simply creating a `minecraft:ghast` with a high health component inside will not work. +::: + +### Overwriting via Reference File + +Many assets can also be registered into some kind of "registration system" file. These files are interesting, because unlike the other asset types, they are _merged together_ instead of _overwritten_. This means that when you define these files, you do not need to copy from the vanilla resources. You can simply start with a blank file, and then overwrite the specific definitions you want. + +The following files work in this way: + +- All UI files +- [All language files](/concepts/text-and-translations) +- `item_textures.json` +- `flipbook_textures.json` +- `terrain_textures.json` +- `sounds.json` +- `music_definitions.json` +- `sound_definitions.json` + +:::tip +**Example:** Lets say you want to override the `sugar` texture, using the reference files. You can do so by creating a new `item_textures.json`, with the following contents: + + + +```json +{ + "resource_pack_name": "vanilla", + "texture_data": { + "sugar": { + "textures": "textures/path/to/my/sugar" + } + } +} +``` + +This _definition_ will be merged with the vanilla `item_textures.json`, and will override the short-name `sugar`. When the vanilla item accesses this short-name, it will get a reference to your custom texture path, instead of the actual texture path to sugar. +::: + +## Overwriting Dangers + +Since addons mostly _overwrite_ each other rather than _merge_, it can be very difficult to get two incompatible addons to work together. For example, if you try to combine two addons that overwrite the creeper behavior (for example, one makes them very fast, and one makes them very large) the addon you have applied _second_ will overwrite the first. + +This is mostly a problem with `player.json` (in either the RP or the BP), since this file is often used for gameplay purposes. + +## Things that Cannot be Overwritten + +Not everything can be overwritten, the following is a list of things that cannot be overwritten using any of the described methods: + +- Vanilla items (Not all) +- Vanilla blocks +- Vanilla fogs (create a fog with another namespace and change it everywhere it is used) diff --git a/docs/wiki/concepts/shaders.md b/docs/wiki/concepts/shaders.md new file mode 100644 index 00000000..d60322e1 --- /dev/null +++ b/docs/wiki/concepts/shaders.md @@ -0,0 +1,161 @@ +--- +title: Shaders +mentions: + - SirLich + - Dreamedc2015 + - yanasakana + - MedicalJewel + - SIsilicon +--- + +:::warning +The shaders on this page are incompatible with [Render Dragon](https://help.minecraft.net/hc/en-us/articles/360052771272-About-the-1-16-200-Update-for-Windows-10-). That means that they will not work on Windows and Console devices past 1.16.200, nor other devices past 1.18.30! +::: + +## Overview + +Shaders are divided into 2 folders: `glsl` and `hlsl`. For shaders to work on every device, +you need to code shaders in both languages. For testing on Windows, `hlsl` is enough. +When rewriting shaders from one language to another, there are few things to change, +like HLSL `float3` is `vec3` in GLSL. Mapping between those languages can be found [here](https://anteru.net/blog/2016/mapping-between-HLSL-and-GLSL/) + +## Materials + +Vertex, fragments, and sometimes geometry shaders are combined with some options +as materials and are required for custom shaders. To create new material, +you need to create a file, which matches the name of the .material file in the vanilla resource pack. +For example: `materials/particles.material`. Materials support inheritance by adding parent +material after a colon. For example: `entity_alpha:entity_base` + +### Common material definition fields + +| **Field name** | **Description** | **Example value** | **Notes** | +| ---------------- | --------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| `vertexShader` | Path to the shader relative to hlsl/glsl folder | | For HLSL shader, `.hlsl` suffix is added. | +| `fragmentShader` | Path to the shader relative to hlsl/glsl folder | | For HLSL shader, `.hlsl` suffix is added. | +| `vertexFields` | An array of fields passed to vertex shader | | It's better to copy this field from vanilla material. | +| `variants` | An array of objects, which define variants of the material | | It's better to copy this field from vanilla material. | +| `+defines` | An array of `#define` directives to add to the shader source | | Useful for reusing shader, but changing some minor setting. | +| `+states` | An array of states to enable | `["Blending", "DisableAlphaWrite", "DisableDepthWrite"]` | For OpenGL implementation, this is equivalent to [glEnable](https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glEnable.xml) call. | +| `-defines` | An array of `#defines` directives to remove from inherited `+defines` | | | +| `+samplerStates` | An array of objects, defining how texture at certain index is treated | `{ "samplerIndex": 0, "textureFilter": "Point" }` | `textureFilter` specifies how to sample the texture and `textureWrap` specifies the behavior, when accessing outside of the texture dimensions. | +| `msaaSupport` | Multisample anti-aliasing support | `Both` | | +| `blendSrc` | Specifies how the color source blending factors are computed | `One` | For OpenGL implementation, this is equivalent to [glBlendFunc](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBlendFunc.xhtml) call. | +| `blendDst` | Specifies how the color destination blending factors are computed | `One` | For OpenGL implementation, this is equivalent to [glBlendFunc](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBlendFunc.xhtml) call. | + +Example: + + + +```json +{ + "materials": { + "version": "1.0.0", + "particle_debug": { + "vertexShader": "shaders/particle_generic.vertex", + "fragmentShader": "shaders/particle_debug.fragment", + + "vertexFields": [ + { "field": "Position" }, + { "field": "Color" }, + { "field": "UV0" } + ], + + "+samplerStates": [ + { + "samplerIndex": 0, + "textureFilter": "Point" + } + ], + + "msaaSupport": "Both" + } + } +} +``` + +For all the details about material files and possible field values, check [material file JSON schema](https://github.com/stirante/bedrock-shader-schema/blob/master/materials.schema.json). + +## Troubleshooting + +### Shader doesn’t change + +Every time there is a change in the shader, you need to restart Minecraft to recompile the shader completely. + +### Compilation error + +When there is a shader compilation error, a line number is usually specified where the error occurred. You need to check a few lines above the one set in error because Minecraft adds `#define` directives before compilation. + +### Couldn’t find constant buffer named: $Globals + +I couldn’t accurately find the actual cause of this error, but it seems to be somehow connected to global variables. Removing them (initializing them in the `main` function or changing them to `#define` directives) seems to fix the problem. + +## Tips and tricks + +### Passing variables to the shader + +You can pass variables to the shader from a particle or an entity by changing entity color. +Input color is clamped to `<0.0, 1.0>`. To pass more significant values, you need to divide by max value (or at least some considerable number). + +### Using time in shader + +`TIME` variable is a number of seconds as `float` and is global for all shaders. For time-based on particle lifetime, you need to pass this: + + + +```json +"minecraft:particle_appearance_tinting": { + "color": ["variable.particle_age/variable.particle_lifetime", 0, 0, 1] +} +``` + +Then in the shader, use `PSInput.color.r` as time, where `0.0` is particle birth and `1.0` is particle death. + +### Camera direction towards the entity + +For entity shaders, you can make the shader dependent on the camera direction towards the entity. + +- Add to `PS_Input` in vertex and fragment shader new field + + + +``` +float3 viewDir: POSITION; +``` + +- After that, add to vertex shader this line + + + +``` +PSInput.viewDir = normalize((mul(WORLD, mul(BONES[VSInput.boneId], float4(VSInput.position, 1)))).xyz); +``` + +- In the fragment shader, use `PSInput.viewDir` to make changes depending on camera rotation + +### Debugging values + +The easiest way to debug a value is to turn it into color and render it like this. + + + +``` +PSOutput.color = float4(PSInput.uv, 0., 1.); +``` + +This should create a red-green gradient, showing that the values of `uv` are between `<0, 0>` and `<1, 1>`. + +You can use the debug shader I wrote [based on this shader](http://mew.cx/drawtext/drawtext). +Right now, this shader will display values of the color passed to the shader. To display another value, change line 70 in hlsl shader to + + + +``` +int ascii = getFloatCharacter( cellIndex, ); +``` + +GLSL version of debugging shader may crash Minecraft, use only for debugging. + +[Download debug shader](http://files.stirante.com/debugShader.zip) + +![](/assets/images/knowledge/shaders/debugShader.gif) diff --git a/docs/wiki/concepts/sounds.md b/docs/wiki/concepts/sounds.md new file mode 100644 index 00000000..90c7711f --- /dev/null +++ b/docs/wiki/concepts/sounds.md @@ -0,0 +1,331 @@ +--- +title: Sounds +tags: + - intermediate +mentions: + - SirLich + - solvedDev + - Joelant05 + - aexer0e + - MedicalJewel105 + - Justash01 + - DasEtwas + - TheItsNameless + - ThomasOrs +--- + +In bedrock, we can add custom sounds without overwriting any vanilla sounds. This is done by adding files to the resource pack. + +:::tip +The best way to learn about sounds is by downloading and playing around with the default resource pack. +::: + +### Folder Structure + +There are two main files that we edit when we want to add sounds. Note how `sound_definition` is nested inside `sounds`. + +Sound files themselves are added inside of the `sounds` folder, and can be any of the following formats. + + + +## sound_definitions.json + +`sound_definitions.json` is where we define new sound short-names. This should be thought of as typing a `short-name` or `id` to a physical sound path. Here is an example, `sound_definitions.json`, that adds a new trumpet sound called `example.toot`: + +RP/sounds/sound_definitions.json + +```json +{ + "format_version": "1.14.0", + "sound_definitions": { + "example.toot": { + "category": "neutral", + "sounds": ["sounds/trumpet"] + } + } +} +``` + +Sounds added in this way can be triggered using `/playsound`. Please note that `playsound` does not auto-correct, so you will need to be careful in your typing. + +:::warning +New files referenced by file path, such as sounds, DO need a complete client restart to load. This means that if sounds don't work, you should restart your entire MC client rather than just reloading the world. +::: + +### /playsound volume notes + +The game will clamp the sound volume to at most 1.0 before multiplying it with the sound definition's volume. + +For `/playsound`, the maximum hearable range of a sound is given by `min(max_distance, max(volume * 16, 16))`. +If `"max_distance"`is not given in the sound's definition, it is equivalent to `playsound_volume * 16`. + +Approximate sound attenuation by distance. The actual graph might not be linear. + +![](/assets/images/concepts/sounds/sound_graph.png) + +Shown above is the approximate sound attenuation factor by distance **for playing sounds with a volume parameter greater than or equal to 1**. Notice how the playsound `` limits the sound's audible range. +The axis `distance` is the distance of the sound listener (player) to the sound source. The corresponding `volume` axis' value is the factor for the playsound volume capped to 1, multiplied by the sound definition's volume to get the final volume of the sound you hear. As an expression this could be written as: `final_volume = min(playsound_volume, 1) * graph_volume * sound_definition_volume`. + +**Note:** Attenuation by distance of the hearable sound's volume is not affected by the volume parameter given in the command. + +For example, `mob.ghast.affectionate_scream` sets `"min_distance": 100.0`, but can only be heard from at most 16 blocks away when using `/playsound` with volume 1 to play it. Specifying a greater volume value increases the audible range. When using a large enough volume to hear the sound farther away, the sound will get quieter only after a distance of more than 100.0. + +To make a sound which can be heard far away but also drops in volume continuously over distance, one can add e.g. `"volume": 0.01`and use large `` values in the playsound command. The high value for the `/playsound` volume will produce a large audible range (e.g. a volume of 4 is 64 blocks as calculated above), while the low volume will prevent the played sound from capping at 1.0 too soon. + +### Top Level Keys + +In the example above, I showed two `top-level` fields: `category` and `sounds`. Sounds will be discussed in further detail below, but the other `top-level` keys will be discussed here: + +#### Categories + +Categories are used internally by the engine to decide how each sound is played. We can utilize different channels to get other effects. + +| Category | Note | +| -------- | ----------------------------------------------- | +| weather | | +| block | | +| bucket | | +| bottle | | +| ui | Sounds in this category will ignore range limit | +| player | | +| hostile | | +| music | | +| record | | +| neutral | | + +#### min_distance + +The distance from the sound source after which sound volume is attenuated. Default value: 0.0. It must be a float (eg. 1.0), or the property will be ignored. + +#### max_distance + +The distance from the sound source after which the sound volume is the quietest (if in range). It must be a float (eg. 1.0), or the property will be ignored. + +### Sound definitions + +In the example above, I showed `sounds` as simply a list with a single path. This is good for simple sounds but does not have much power. For starts, I can add multiple sounds to the list. These sounds will be randomized when played: + +RP/sounds/sound_definitions.json + +```json +{ + "format_version": "1.14.0", + "sound_definitions": { + "example.toot": { + "category": "neutral", + "sounds": [ + "sounds/trumpet", + "sounds/trumpet2", + "sounds/trumpet3" + ] + } + } +} +``` + +Additionally, we can define each sound as an object instead of a string. This allows us finer control and unlocks some new settings. The string/object style can be mixed and matched. + +#### name + +The path to the file, such as: `"sounds/music/game/creative/creative1"` + +#### stream + +Limits the sound only to be played a limited number of instances at a time. Will cause the game to not load the entire sound data into memory while playing, but rather in smaller parts while playing, thus using less memory. Good for improving performance on sound heavy worlds. + +#### volume + +How loud the sound should play, from `0.0` to `1.0`. Sounds cannot be made more audible than initially encoded. Set to `1.0` by default. +Sounds in custom resource packs can have working values greater than 1.0. + +#### load_on_low_memory + +Forces the loading of the sound even when nearing low memory. "load_on_low_memory" is now deprecated as of 1.16.0 + +#### pitch + +The pitch of the sound (how low/high it sounds). Should be a positive value. For example, `2.3` will let the sound play 2.3 times as quickly and thus at higher pitch. Set to `1.0` by default. + +#### is3D + +`true` makes the sound directional. Set to `true` for all sounds by default. Ignored for `music` and `ui` sounds. Only sounds with `false` will play stereo sound. + +#### interruptible + +Set to `true` by default. + +### weight + +If there is more than one sound in the list, the sound to be played is chosen randomly. `"weight"` (integer value like 5) will give the relative chance that this sound is chosen from the list. For example, if there are two sounds in the list, one with `"weight": 10` and the other with `"weight": 2`, the first will be played approximately 5 times more likely than the second (accurately: `10 / (10 + 2) = 83.3%` chance vs. `2 / (10 + 2) = 16.7%` chance) . Set to `1` by default. + +### Example + +Here is a more realistic example containing these options: + +RP/sounds/sound_definitions.json#sound_definitions + +```json +"block.beehive.drip": { + "category": "block", + "max_distance": 8, + "sounds": [ + { + "name": "sounds/block/beehive/drip1", + "load_on_low_memory": true + }, + "sounds/block/beehive/drip2", + "sounds/block/beehive/drip3", + "sounds/block/beehive/drip4" + ] +} +``` + +## sounds.json + +If we want our sounds to run automatically, we can add them into the `sounds.json` file. This will tie the sound definitions directly to game events and cause them to play without needing to trigger with `/playsound`. + +Sounds can be added into various categories: + +| Category | Note | +| ----------------------- | -------------------------------------------------------------------------------- | +| individual_event_sounds | Contains sounds like beacon activation, chest-close, or explode | +| block_sounds | Contains hit, step, and break sounds for blocks | +| entity_sounds | Contains death, ambient, hurt, etc. sounds for entities (Including custom ones!) | +| interactive_sounds | WIP | + +### Adding Entity Sounds + +I assume that sounds can be added in other categories, but I personally only have experience adding sounds into the `entities` category. Entity sounds are automatically played at various points in the entities life-cycle. + +Common events: + +| Events | Note | +| ---------- | -------------------------------------------------------- | +| ambient | Played randomly, such as grunts, clucks, or ghast noises | +| hurt | Played when damaged | +| death | Played when it dies | +| step | Played when the entity moves along the ground | +| fall.big | For hitting the ground from a high height | +| fall.small | For hitting the ground from a low height | +| splash | For splashing in the water | +| attack | For melee attacking | +| shoot | For shooting projectiles | + +There are also many sound events, which _most likely_ trigger automatically, but which I don't have details for, such as: + +| Unknown Categories | +| ------------------ | +| breathe | +| splash | +| swim | +| ambient.in.water | +| death.in.water | +| jump | +| eat | +| hurt.in.water | +| mad | +| stare | +| sniff | +| sleep | +| spit | +| warn | +| scream | + +### Example + +RP/sounds.json + +```json +{ + "entity_sounds": { + "entities": { + "wiki:elephant": { + "volume": 1, + "pitch": [0.9, 1.0], + "events": { + "step": { + "sound": "elephant.step", + "volume": 0.18, + "pitch": 1.1 + }, + "ambient": { + "sound": "elephant.trumpet", + "volume": 0.11, + "pitch": 0.9 + } + } + } + } + } +} +``` + +## Adding sounds to Animations + +Sounds played in animations function based off of `short-name` definitions in the RP entity file. + +This example shows playing a wing-flap sound, synced with an animation. + +RP/entities/dragon.json#minecraft:client_entity/description + +```json +"sound_effects": { + "wing_flap": "wiki.dragon.wing_flap" //where wiki.dragon.roar is a sound defined in sound_definitions +} +``` + +RP/animations/dragon.json#animations/animation.dragon.flying + +```json +"sound_effects": { + "3.16": { + "effect": "wing_flap" + } +} +``` + +## Adding sounds to Animation Controllers + +You can play sounds within animation controllers in a similar way that animations can be. + +This example shows playing an explosion sound, synced using an animation controller. + +RP/entities/custom_tnt.json#minecraft:client_entity/description + +```json +"sound_effects": { + "explosion": "wiki.custom_tnt.explosion" //where wiki.custom_tnt.explosion is a sound defined in sound_definitions just like animation sounds. +} +``` + +RP/animation_controllers/custom_tnt.animation_controllers.json#controller.animation.custom_tnt + +```json +"states":{ + "default":{ + "transitions":[ + { + "explode_state":"q.mark_variant == 1" + } + ] + }, + "explode_state":{ + "sound_effects":[ + { + "effect":"explosion" + } + ], + "transitions":[ + { + "default":"q.mark_variant == 0" + } + ] + } +} +``` diff --git a/docs/wiki/concepts/subpacks.md b/docs/wiki/concepts/subpacks.md new file mode 100644 index 00000000..9cbd3d73 --- /dev/null +++ b/docs/wiki/concepts/subpacks.md @@ -0,0 +1,95 @@ +--- +title: Subpacks +mentions: + - SirLich + - solvedDev + - Joelant05 + - ChilRx + - SmokeyStack + - MedicalJewel105 + - TheItsNameless +--- + +## What are Subpacks? + +Subpacks allow you to select between different addon 'configurations'. + +They are intended for texture resolutions to load on different memory capacities, but can also be used to create file variations in behavior and resource packs. These variations can be selected by clicking the gear icon and adjusting the slider. + +## How do Subpacks work? + +Files placed in you subpack folder will override files placed in your main addon folder, if the subpack is selected. For example, if your addon contains both `RP/textures/entities/ghost.png` and `RP/subpacks/pack_1/textures/ghost.png`, the second image file will replace the first, if subpack `pack_1` is selected. + +For more information about how files override each other, please see our page on [overriding vanilla assets](/concepts/overwriting-assets). + +## Creating Subpacks + +- To start adding a subpack you need to create a `subpacks` folder inside the root of your `BP`/`RP`. +- Then inside the `subpacks` folder add a folder for each subpack you want to have + e.g. + + + +- Inside each of these folders you can add the content of each subpack. + This can be anything that normally goes in your behavior or resource pack. + e.g. + + + +## Manifest Part + +To register the subpacks in the manifest you need to add `subpacks` and this contains an array of subpacks. + +Example: + +RP/manifest.json + +```json +{ + "format_version": 2, + "header": { + "name": "Pack Name", + "description": "Pack Description", + "uuid": "2fc2dd6f-86cb-4370-af70-21490a1ae471", + "version": [1, 0, 0], + "min_engine_version": [1, 13, 0] + }, + "modules": [ + { + "type": "resources", + "uuid": "f6821b4a-1854-44fc-a8a4-0c2847ffda46", + "version": [1, 0, 0] + } + ], + "subpacks": [ + { + "folder_name": "subpack_1", + "name": "First Subpack", + "memory_tier": 0 + }, + { + "folder_name": "subpack_2", + "name": "Second Subpack", + "memory_tier": 1 + } + ] +} +``` + +- `name` - name that will show when selecting subpacks. + +- `memory_tier`- amount of RAM that device must have to enable this subpack. 1 memory tier = 0.25 GB. + +- `folder_name` - name of the folder to be used for this subpack, for example in the examples above this would be `subpack_1` or `subpack_2`. + +## Known Things + +If you add only one subpack, there will be 2 options at the subpacks selection section, however second resolution (no subpack actually) does **not** make content in the root folder override subpacks. diff --git a/docs/wiki/concepts/text-and-translations.md b/docs/wiki/concepts/text-and-translations.md new file mode 100644 index 00000000..1e905453 --- /dev/null +++ b/docs/wiki/concepts/text-and-translations.md @@ -0,0 +1,156 @@ +--- +title: Text and Localization +mentions: + - ThijsHankelMC + - SirLich + - aexer0e + - MedicalJewel105 + - Luthorius + - Fabrimat + - TheDoctor15 + - Hatchibombotar + - ChibiMango + - SmokeyStack + - Sprunkles +--- + +Minecraft is a game with fully localized text in languages all over the world. To achieve this, Minecraft employs a system where internal **translation keys** are assigned values on a per-language basis. Minecraft will generate translation keys for custom entities, items, and blocks, and it is up to us to assign them a localized name in our resource pack. + +## Language Files + +### File Location + +Language files typically go within the resource pack in the "texts" folder as files with the `.lang` file extension. These files can be placed in the behavior pack, but the only translatable text it can change is the pack manifest's name and description. + + + +Minecraft supports 29 languages currently, as described in [§ Vanilla Languages](/concepts/text-and-translations#vanilla-languages). + +### Format + +The format for a language file is rather straightforward. Translations are supplied as key-value pairs separated by an equals sign (`=`), the key being a translation key and the value being a string. Values cannot contain newline characters. + +```toml +wiki.example_translation.line_1=The first line! +wiki.example_translation.line_2=Some more information following the first line. +``` + +Comments may be added with two pound signs (`##`), either as line comments or in-line comments. All text after the pound signs are a comment until the next line. + +:::warning +Trailing spaces are not trimmed for in-line comments. If you want to indent a comment, use the Tab character. +::: + +```toml +## Translator note: I thought this would be funny to put here. +item.flint_and_steel.name=Flint and Steve ##[sic] +``` + +A translation can contain substitutions in place of text. Substitutions can either be ordered (`%1`, `%2`, etc.) or not ordered (`%s`). Vanilla translations have their values filled in by the game, while players can manually set the substitutions' values with commands that use the raw JSON text format, like with [`/tellraw`](/commands/tellraw). + +```toml +commands.op.success=Opped: %s +immersive_reader.book_page_header=Page %1 of %2 +``` + +### Usage + +Localization can be done just about anywhere text can be used, including (but not limited to): + +- Pack name and description +- Entity, item, or block names +- Pages in a book +- Lines on a sign +- `/tellraw` and `/titleraw` commands +- Text in dialogue + +Some text cannot be translated however, such as for an item renamed in an anvil. + +## Localization + +:::tip +It is good practice create a copy of your language file for each major language your pack supports. For example, to support full English one should create both an `en_US.lang` and an `en_GB.lang` file, to cover English in both the United States and Great Britain countries, respectively. +::: + +When editing language files one must also add a `languages.json` file in the `texts` folder containing an array with each of the languages you plan to change. This lets Minecraft know that it should apply localization for these languages. + +RP/texts/languages.json + +```json +[ + "en_US", + "en_GB", + "fr_FR" +] +``` + +### Custom Languages + +With a global resource pack, custom languages may be introduced through the `languages.json` and `language_names.json` files. Once the pack is applied globally the language can be changed in the "Language" tab of the in-game settings. + +For the following examples, lets assume that we have 2 fully functional language files, one named `xx_XX.lang`, and another named `yy_YY.lang`. + +RP/texts/languages.json + +```json +[ + "xx_XX", + "yy_YY" +] +``` + +`language_names.json` is an array as well, but this time to define the names to display for the languages. + +RP/texts/language_names.json + +```json +[ + [ "xx_XX", "New Language (Custom Language #1)" ], + [ "yy_YY", "Wiki-Speak (Custom Language #2)" ] +] +``` + +:::warning + Whenever using a custom language, make sure to unequip the language before you disable the Resource Pack which it is stored in, or else Minecraft will crash. +::: + +### Vanilla Languages + +The following is a table of the 29 languages Minecraft supports by default. + +| File ID | Language | Country | +| ---------- | --------------------- | -------------- | +| id_ID | Indonesian | Indonesia | +| da_DK | Danish | Denmark | +| de_DE | German | Germany | +| en_GB | English | Great Britain | +| en_US | English | North America | +| es_ES | Spanish | Spain | +| es_MX | Mexican Spanish | Mexico | +| fr_CA | Canadian French | Canada | +| fr_FR | French | France | +| it_IT | Italian | Italy | +| hu_HU | Hungarian | Hungary | +| nl_NL | Dutch | Netherlands | +| nb_NO | Bokmål | Norway | +| pl_PL | Polish | Poland | +| pt_BR | Brazilian Portuguese | Brazil | +| pt_PT | Portuguese | Portugal | +| sk_SK | Slovak | Slovakia | +| fi_FI | Finnish | Finland | +| sv_SE | Swedish | Sweden | +| tr_TR | Turkish | Turkey | +| cs_CZ | Czech | Czech Republic | +| el_GR | Greek | Greece | +| bg_BG | Bulgarian | Bulgaria | +| ru_RU | Russian | Russia | +| uk_UA | Ukrainian | Ukraine | +| ja_JP | Japanese | Japan | +| zh_CN | Chinese (Simplified) | China | +| zh_TW | Chinese (Traditional) | Taiwan | +| ko_KR | Korean | Korea | diff --git a/docs/wiki/concepts/textures-list.md b/docs/wiki/concepts/textures-list.md new file mode 100644 index 00000000..a726a03c --- /dev/null +++ b/docs/wiki/concepts/textures-list.md @@ -0,0 +1,43 @@ +--- +title: textures_list.json +mentions: + - SirLich + - solvedDev + - Joelant05 + - AFoxyToast + - TheItsNameless +--- + +## General Overview + +The `textures_list` file is Minecraft's way of *caching* each texture so that it can retrieve it faster than looking through each image in your textures folder. This is especially important when you have an abundance of textures, where Minecraft could potentially mess up and swap textures or even not load them at all. Minecraft tends to throw a content log _warning_ if you don't have the textures listed in the file. You can ignore it if you have a small amount, but it is recommended that you list the textures anyway. + +## What textures can be used in the file? + +Any texture! Any textures can and _should_ be used in the textures_list.json file for best practice and performance. + +## File Structure + +The structure is simple. The file itself is in `RP/textures` and is named `textures_list.json`. The file includes the file path to every texture you want in the file: + +RP/textures/textures_list.json + +```json +[ + "textures/blocks/foo", + "textures/blocks/bar", + + "textures/items/foo", + "textures/items/bar", + + "textures/models/foo", + "textures/models/bar", + + "textures/entity/foo", + "textures/entity/bar" +] +``` + +## Automating + +If you have a lot of textures, this could obviously be tedious to go and list all the texture paths. In this case you can start to use [Regolith](https://bedrock-oss.github.io/regolith/) with its wonderful filters. diff --git a/docs/wiki/documentation/advanced-molang.md b/docs/wiki/documentation/advanced-molang.md new file mode 100644 index 00000000..e67b0187 --- /dev/null +++ b/docs/wiki/documentation/advanced-molang.md @@ -0,0 +1,70 @@ +--- +title: Advanced Molang +toc_max_level: 2 +mentions: + - Ciosciaa + - TheItsNameless +--- + +## Values + +- All expressions in Molang return a value for the sake of checks against equality. Most expressions return `0`. Notably, assignments return the value assigned and loops return the resolved value of the looping statements, if one would exist. +- All values in Molang are effectively single-precision floats. +- `this` is used to refer to the field's current value as it accumulated during evaluation. It is only observed to be usable in animations, but it may be usable elsewhere. As an example, if the accumulated transformations on the `x` `scale` of a bone would yield `62`, a final animation with a `x` `scale` of `-this` would resolve to `-62`, unsetting the prior transformations. This is used in vanilla animations in a number of places. Outside of animation contexts, `this` appears to always resolve to `0`. + +### Booleans + +- Booleans are usable in Molang. `true` resolves to `1`, and `false` resolves to `0`. + +### Numbers + +- You can use leading `0`s in front of numbers, for example, to line them up better in your code. +- Numbers can use exponential notation, such as `2.5e2`, which would be equal to 250. `e` can be suffixed with `+` or `-` to direct the power. +- Numbers may be suffixed with a single `f`, often used to denote a floating point value. This can be found across vanilla code, but it is not believed to have any functionality. + +### Strings + +- Strings use `\` (`\\` in escaped JSON) as some sort of escape or perhaps something else. It is unknown what functionality this has. It is known that the subsequent 2 characters are handed off to their own sub-parser, which does not exit correctly on a closing `'`; this means the Molang string `"v.type = '\\x';"` is invalid. `'`, which is normally disallowed on its own as it would represent the end of the string, is allowed in the 2 characters following a `\`. +- String values are (mostly) incremental as they are represented against floats. It is possible to compare 2 individual character strings using equality or comparison operators or even to effectively "adjust" the contents of a single-character string. Multi-character behavior of such is unknown. + +## Operators + +The complete precedence list, from first to last evaluated: + +1. `()` and `[]` +2. `->` +3. `!` and `-` (unary negation) +4. `*` and `/` +5. `+` and `-` (binary subtraction) +6. `<`, `<=`, `>`, and `>=` +7. `==` and `!=` +8. `&&` +9. `||` +10. `?` and `? :` +11. `??` +12. `=` +13. `return` + +- Operators are considered from left to right for all operators except the conditionals. +- Multiple `->` cannot be used in the same statement. +- Logical operators short-circuit. + +## Statements + +- Assignments return the value assigned. You can therefore chain assignments if you need separate variables to work with from a single value, such as with `v.iterator_x = (v.iterator_z = math.random_integer(16, 32));`. +- The last statement inside a brace scope does not need to end with a `;`. +- Brace scopes can be used anywhere an expression can be used. `v.spawn_point ?? {v.target = false;};`, for example, would set `v.target` to `false` if `v.spawn_point` were not defined. + +## Collections + +- Entity iterables (such as the result of `q.get_nearby_entities`) are their own "type". They are not compatible with subscripts. +- Arrays, likewise, are not compatible with entity iterable operations, such as `q.count`. +- The result of array subscripts cannot directly be an argument to `+`, `-`, `*`, or `/` but may still be used directly as function parameters (even math functions) or with other operators. + +## Evaluation + +- `initialize` and `pre_animation` are lazily concatenated. Molang strings in these arrays must be syntactically valid independently, but the basic concatenation of all independent strings must also be a valid Molang input. + +## Limits + +- Molang showed no reasonable limits to any language functionality, aside from numeric size. Loop counts, string lengths, Molang input length, collection size, etc., were observed to hold in very unreasonable situations. \ No newline at end of file diff --git a/docs/wiki/documentation/creative-categories.md b/docs/wiki/documentation/creative-categories.md new file mode 100644 index 00000000..e95c0d8e --- /dev/null +++ b/docs/wiki/documentation/creative-categories.md @@ -0,0 +1,180 @@ +--- +title: Menu Categories +mentions: + - Warhead51707 + - yanasakana + - SirLich + - SmokeyStack + - MedicalJewel105 + - Chikorita-Lover + - MiemieMethod + - retr0cube + - TheItsNameless + - QuazChick +--- + +Menu categories determine where items and blocks appear inside of the creative inventory and recipe book. + +- A `category` can be defined to place the item under a tab (such as construction). Click [here](#list-of-categories) for a list of valid categories. + +- A `group` specifies which expandable group the item is placed into. If you use a custom value, a new expandable group won't be created, however items with the group will be placed next to each other in the creative inventory. Click [here](#list-of-groups) for a list of expandable groups. + +- You can also set `is_hidden_in_commands` to true to remove this block/item from commands, such as `/give` and `/setblock`. + +If `menu_category` is omitted, the item will only be accessible through commands and won't appear in the creative inventory or recipe book. + +**NOTE:** The menu category of custom spawn eggs cannot be modified. You must instead create a custom item with the `minecraft:entity_placer` component. + + + +```json +"menu_category": { + "category": "construction", // Tab the item is placed under + "group": "itemGroup.name.door", // Optional - Group the item is placed into + "is_hidden_in_commands": false // Optional - default is false (item is usable in commands) +} +``` + +:::danger HIDDEN ITEMS INACCESSIBLE IN COMMANDS ([MCPE-177866](https://bugs.mojang.com/browse/MCPE-177866)) +Currently, setting the category to "none" in a custom item (not block) prevents the item from being used in commands, overriding the "is_hidden_in_commands" option. This issue doesn't affect blocks. +::: + +## Block Example + +BP/blocks/balsa_wood.json + +```json +{ + "format_version": "1.20.50", + "minecraft:block": { + "description": { + "identifier": "wiki:balsa_wood", + "menu_category": { + "category": "nature", + "group": "itemGroup.name.wood" // Placed into an expandable group + } + } + } +} +``` + +## Item Example + +BP/items/dagger.json + +```json +{ + "format_version": "1.20.50", + "minecraft:item": { + "description": { + "identifier": "wiki:dagger", + "menu_category": { + "category": "equipment", + "is_hidden_in_commands": true // Item cannot be used in commands + } + } + } +} +``` + +## List of Categories + +_For use with `menu_category` parameter, `category`._ + +| Category | Description | +| ------------ | -------------------------------------------------------- | +| construction | Added to the "Contruction" tab. | +| equipment | Added to the "Equipment" tab. | +| items | Added to the "Items" tab. | +| nature | Added to the "Nature" tab. | +| none | Not added to a tab and only accessible through commands. | + +## List of Groups + +_For use with the `menu_category` parameter, `group`._ + + +| Creative Categories: | +| --------------------------------- | +| itemGroup.name.anvil | +| itemGroup.name.arrow | +| itemGroup.name.axe | +| itemGroup.name.banner | +| itemGroup.name.banner_pattern | +| itemGroup.name.bed | +| itemGroup.name.boat | +| itemGroup.name.boots | +| itemGroup.name.buttons | +| itemGroup.name.candles | +| itemGroup.name.chalkboard | +| itemGroup.name.chest | +| itemGroup.name.chestboat | +| itemGroup.name.chestplate | +| itemGroup.name.concrete | +| itemGroup.name.concretePowder | +| itemGroup.name.cookedFood | +| itemGroup.name.copper | +| itemGroup.name.coral | +| itemGroup.name.coral_decorations | +| itemGroup.name.crop | +| itemGroup.name.door | +| itemGroup.name.dye | +| itemGroup.name.enchantedBook | +| itemGroup.name.fence | +| itemGroup.name.fenceGate | +| itemGroup.name.firework | +| itemGroup.name.fireworkStars | +| itemGroup.name.flower | +| itemGroup.name.glass | +| itemGroup.name.glassPane | +| itemGroup.name.glazedTerracotta | +| itemGroup.name.goatHorn | +| itemGroup.name.grass | +| itemGroup.name.hanging_sign | +| itemGroup.name.helmet | +| itemGroup.name.hoe | +| itemGroup.name.horseArmor | +| itemGroup.name.leaves | +| itemGroup.name.leggings | +| itemGroup.name.lingeringPotion | +| itemGroup.name.log | +| itemGroup.name.minecart | +| itemGroup.name.miscFood | +| itemGroup.name.mobEgg | +| itemGroup.name.monsterStoneEgg | +| itemGroup.name.mushroom | +| itemGroup.name.netherWartBlock | +| itemGroup.name.ore | +| itemGroup.name.permission | +| itemGroup.name.pickaxe | +| itemGroup.name.planks | +| itemGroup.name.potion | +| itemGroup.name.potterySherds | +| itemGroup.name.pressurePlate | +| itemGroup.name.rail | +| itemGroup.name.rawFood | +| itemGroup.name.record | +| itemGroup.name.sandstone | +| itemGroup.name.sapling | +| itemGroup.name.sculk | +| itemGroup.name.seed | +| itemGroup.name.shovel | +| itemGroup.name.shulkerBox | +| itemGroup.name.sign | +| itemGroup.name.skull | +| itemGroup.name.slab | +| itemGroup.name.smithing_templates | +| itemGroup.name.splashPotion | +| itemGroup.name.stainedClay | +| itemGroup.name.stairs | +| itemGroup.name.stone | +| itemGroup.name.stoneBrick | +| itemGroup.name.sword | +| itemGroup.name.trapdoor | +| itemGroup.name.walls | +| itemGroup.name.wood | +| itemGroup.name.wool | +| itemGroup.name.woolCarpet | + +*Last updated for 1.20.10* + diff --git a/docs/wiki/documentation/file-types.md b/docs/wiki/documentation/file-types.md new file mode 100644 index 00000000..0e465bdb --- /dev/null +++ b/docs/wiki/documentation/file-types.md @@ -0,0 +1,106 @@ +--- +title: File Types +max_toc_level : 3 +mentions: + - Ciosciaa + - SirLich +--- + +A number of file types exist for *Minecraft*, all for importing content. All *Minecraft* files are ZIP archives renamed to use a `mc…` extension. These archives can currently be divided into three sets: + +- **Levels (`mcworld` and `mcproject`)**: level data and associated resources for worlds and projects +- **Assets (`mcpack` and `mctemplate`)**: cosmetics or supporting assets for worlds +- **Composites (`mcaddon` and `mceditoraddon)`**: used to import up to one world or project and any number of asset types + +All file types for Minecraft can be opened as any file, launching Minecraft and importing the content. When packages are imported, they are automatically unpacked into their constituent files and directories. If it was not already open, most file types will launch Minecraft in normal mode; `mcproject` and `mceditoraddon` will instead launch Minecraft into Editor mode. + +# Levels +Levels represent save data and resources for regular worlds and Editor projects. All levels, regardless of mode, are imported to `minecraftWorlds` in the `com.mojang` directory. + +Importing an exact duplicate of an existing saved level will create a duplicate saved level. Composite archives will only import one level if multiple are included, including across nested composite archives. + +## Worlds +`mcworld` +Archive encapsulating an individual world + +World archives can be created a few different ways: +- Zipping the *contents* of a world directory and renaming the extension from `zip` to `mcworld` +- Using the "Export World" button on the Game settings screen for a world +- In Editor mode, exporting the world from the File → Export as → Playable world menu option. The world will be saved to the `projectbackups` directory in the `com.mojang` folder. +- In Editor mode, running the `/project export world` command. The world will be saved to the `projectbackups` directory in the `com.mojang` folder. + +Importing a world package while *Minecraft* is launched in Editor mode will import the world as a project. The imported world will then be inaccessible outside Editor mode and will need to be re-exported as a world for playing. Editor extension packs bundled in a world archive will be retained on import outside Editor mode. + +## Projects +`mcproject` +Archive encapsulating an individual Editor project + +Project archives can be created two different ways: +- Zipping the *contents* of a project directory and renaming the extension from `zip` to `mcproject`. +- Using the "Export Project" button on the Game settings screen for a world +- In Editor mode, running the `/project export project` command. The world will be saved to the `projectbackups` directory in the `com.mojang` folder. + +If *Minecraft* is not open, launching a `mcproject` file will open Editor mode. Importing a `mcproject` will fail if *Minecraft* is open but not in Editor mode. + +# Assets +Asset archives represent a singular instance of a number of non-level contents: + +- Behavior packs +- Resource packs +- Skin packs +- World templates + +All asset archives include a manifest describing their contents. An asset archive will fail to import if its manifest UUID and version exactly matches an existing asset archive of the same type. Note that behavior and resource packs share the same UUID/version space. Behavior and resource packs self-contained within a world, project, or template will not count as duplicates for the sake of importing. + +Both asset extensions, `mcpack` and `mctemplate`, appear to functionally behave the same. It's best practice to use `mcpack` for behavior, resource, and skin packs and `mctemplate` for world templates to make it more clear what's being installed. Any number of asset archives may be included in a composite archive. + +## Packs +`mcpack` +Package representing an individual behavior pack, resource pack, skin pack, or world template. It's recommended only to use `mctemplate` for behavior packs, resource packs, or skin packs. + +Packs are only created manually, by zipping the contents of a behavior pack, resource pack, or skin pack directory and renaming the extension from `zip` to `mcpack`. Behavior and resource packs are installed globally and do not conflict with matching behavior or resource packs installed in worlds, projects, or templates. + +### Behavior Packs +Behavior packs are attached to servers to change or extend gameplay. Behavior packs are installed to the `behavior_packs` directory in the `com.mojang` folder. + +Development behavior packs must be placed in the `development_behavior_packs` directory under `com.mojang` manually. + +### Resource Packs +Resource packs are attached to clients to affect sounds, visuals, etc. Resource packs are installed to the `resource_packs` directory in the `com.mojang` folder. + +Development resource packs must be placed in the `development_resource_packs` directory under `com.mojang` manually. + +### Skin Packs +Skin packs are client-only packs for custom skins. Skin packs are installed to the `skin_packs` directory in the `com.mojang` folder. + +Development skin packs must be placed in the `development_skin_packs` directory under `com.mojang` manually, but this feature appears non-functional. + +## World Templates +`mctemplate` +Package representing an individual behavior pack, resource pack, skin pack, or world template. It's recommended only to use `mctemplate` for world templates. + +World templates are installed to the `world_templates` directory under `com.mojang`. World templates can be constructed in a few different ways: +- Zipping the *contents* of a world directory, adding a world template manifest, and renaming the extension from `zip` to `mctemplate` +- In Editor mode, using the "Export Template" button on the Game settings screen for a world +- In Editor mode, running the `/project export template` command. The world will be saved to the `projectbackups` directory in the `com.mojang` folder. + +# Composites +Composite archives are used to import up to *one* level archive and any number or combination of asset archives in a single import action. In general, contents to a composite must be packaged. Directories can also be given *on the top level* of a composite archive for importing asset types (behavior packs, resource packs, skin packs, and world templates) without needing to pre-package them. Nested sub-directories for organization may not be used. + +Composite contents are treated as usual. For example, importing a `mcaddon` contianing a `mcworld` while in Editor mode will import the world as a project. + +Composite archives may also contain any number or nesting of other composite archives, even across *Minecraft* modes. Nested composite archives cannot be used to get around the singular world import restriction. + +Composites can only be constructed manually by zipping archives and asset types. + +## Add-Ons +`mcaddon` +Generic composite content archive + +Importing a `mcaddon` package while *Minecraft* is launched in Editor mode will import any contained world as a project. The imported world will then be inaccessible outside Editor mode and will need to be re-exported as a world for playing. Asset types are imported as usual. + +## Editor Add-Ons +`mceditoraddon` +Composite content archive for Editor mode + +If *Minecraft* is not open, launching a `mcproject` file will open Editor mode. Importing a `mcproject` will fail if *Minecraft* is open but not in Editor mode. diff --git a/docs/wiki/documentation/fog-ids.md b/docs/wiki/documentation/fog-ids.md new file mode 100644 index 00000000..9a0e3eb4 --- /dev/null +++ b/docs/wiki/documentation/fog-ids.md @@ -0,0 +1,163 @@ +--- +title: Fog IDs +mentions: + - SirLich + - MedicalJewel105 + - TheItsNameless +--- + +## By Element X + +| ID | Note | +| ---------------------------------------------- | -------------------------------------------------------------------------------- | +| minecraft:fog_bamboo_jungle | Fog used in the bamboo jungle. | +| minecraft:fog_bamboo_jungle_hills | Fog used in the bamboo jungle hills. | +| minecraft:fog_basalt_deltas | Fog used in the basalt deltas. Adds a gray-red tint to the edge of the sky | +| minecraft:fog_beach | Fog used in the beach biome. | +| minecraft:fog_birch_forest | Fog used in the birch forest | +| minecraft:fog_birch_forest_hills | Fog used in the birch forest hills biome. | +| minecraft:fog_cold_beach | Fog used in the cold beach biome. | +| minecraft:fog_cold_ocean | Fog used in the cold ocean biome. | +| minecraft:fog_cold_taiga | Fog used in the cold taiga biome. | +| minecraft:fog_cold_taiga_hills | Fog used in the cold taiga hills biome. | +| minecraft:fog_cold_taiga_mutated | Fog used in the mutated cold taiga biome. | +| minecraft:fog_crimson_forest | Fog used in the crimson forest biome. Adds a red tint to the edge of the sky | +| minecraft:fog_deep_cold_ocean | Fog used in the deep cold ocean biome. | +| minecraft:fog_deep_frozen_ocean | Fog used in the deep frozen ocean biome. | +| minecraft:fog_deep_lukewarm_ocean | Fog used in the deep lukewarm ocean biome. | +| minecraft:fog_deep_ocean | Fog used in the deep ocean biome. | +| minecraft:fog_deep_warm_ocean | Fog used in the deep warm ocean biome. | +| minecraft:fog_default | Default fog used in the game. | +| minecraft:fog_desert | Fog used in the desert biome. | +| minecraft:fog_desert_hills | Fog used in the desert hills biome. | +| minecraft:fog_extreme_hills | Fog used in the extreme hills biome. | +| minecraft:fog_extreme_hills_edge | Fog used in the extreme hills edge biome. | +| minecraft:fog_extreme_hills_mutated | Fog used in the mutated extreme hills biome. | +| minecraft:fog_extreme_hills_plus_trees | Fog used in the extreme hills with trees biome. | +| minecraft:fog_extreme_hills_plus_trees_mutated | Fog used in the mutated extreme hills with trees biome. | +| minecraft:fog_flower_forest | Fog used in the flower forest biome. | +| minecraft:fog_forest | Fog used in the forest biome. | +| minecraft:fog_forest_hills | Fog used in the forest hills biome. | +| minecraft:fog_frozen_ocean | Fog used in the frozen ocean biome. | +| minecraft:fog_frozen_river | Fog used in the frozen river biome. | +| minecraft:fog_hell | Fog used in the nether wastes biome. Adds a red tint to the edge of the sky | +| minecraft:fog_ice_mountains | Fog used in the ice mountains biome. | +| minecraft:fog_ice_plains | Fog used in the ice plains biome. | +| minecraft:fog_ice_plains_spikes | Fog used in the ice spikes biome. | +| minecraft:fog_jungle | Fog used in the jungle biome. | +| minecraft:fog_jungle_edge | Fog used in the jungle edge biome. | +| minecraft:fog_jungle_hills | Fog used in the jungle hills biome. | +| minecraft:fog_jungle_mutated | Fog used in the mutated jungle biome. | +| minecraft:fog_lukewarm_ocean | Fog used in the lukewarm ocean biome. | +| minecraft:fog_mega_spruce_taiga | Fog used in the mega spruce taiga biome. | +| minecraft:fog_mega_spruce_taiga_mutated | Fog used in the mega spruce mutated taiga biome. | +| minecraft:fog_mega_taiga | Fog used in the mega taiga biome. | +| minecraft:fog_mega_taiga_hills | Fog used in the mega taiga hills biome. | +| minecraft:fog_mega_taiga_mutated | Fog used in the mega mutated taiga biome. | +| minecraft:fog_mesa | Fog used in the mesa biome. | +| minecraft:fog_mesa_bryce | Fog used in the mesa bryce biome. | +| minecraft:fog_mesa_mutated | Fog used in the mutated mesa biome. | +| minecraft:fog_mesa_plateau | Fog used in the mesa plateau biome. | +| minecraft:fog_mesa_plateau_stone | Fog used in the stone mesa plateau biome. | +| minecraft:fog_mushroom_island | Fog used in the mushroom island biome. | +| minecraft:fog_mushroom_island_shore | Fog used in the mushroom island shore biome. | +| minecraft:fog_ocean | Fog used in the ocean biome. | +| minecraft:fog_plains | Fog used in the plains biome. | +| minecraft:fog_river | Fog used in the river biome. | +| minecraft:fog_roofed_forest | Fog used in the roofed forest biome. | +| minecraft:fog_savanna | Fog used in the savanna biome. | +| minecraft:fog_savanna_mutated | Fog used in the mutated savanna biome. | +| minecraft:fog_savanna_plateau | Fog used in the savanna plateau biome. | +| minecraft:fog_soulsand_valley | Fog used in the soulsand valley biome. Adds a dark green tint to the sky | +| minecraft:fog_stone_beach | Fog used in the stone beach biome. | +| minecraft:fog_sunflower_plains | Fog used in the sunflower plains biome. | +| minecraft:fog_swampland | Fog used in the swamp biome. | +| minecraft:fog_swampland_mutated | Fog used in the mutated swamp biome. | +| minecraft:fog_taiga | Fog used in the taiga biome. | +| minecraft:fog_taiga_hills | Fog used in the taiga hills biome. | +| minecraft:fog_taiga_mutated | Fog used in the mutated taiga hills biome. | +| minecraft:fog_the_end | Fog used in the end biome. Adds a black tint to the edge of the sky | +| minecraft:fog_warm_ocean | Fog used in the warm ocean biome. | +| minecraft:fog_warped_forest | Fog used in the warped forest biome. Adds a dark red tint to the edge of the sky | + +[Original Credit](https://www.youtube.com/watch?time_continue=52&v=SA79ulIgypg&feature=emb_logo) + + +## Auto-generated + + +| ID | Biome used in | +| ---------------------------------------------- | -------------------------------- | +| minecraft:fog_bamboo_jungle | bamboo_jungle | +| minecraft:fog_bamboo_jungle_hills | bamboo_jungle_hills | +| minecraft:fog_basalt_deltas | basalt_deltas | +| minecraft:fog_beach | beach | +| minecraft:fog_birch_forest | birch_forest | +| minecraft:fog_birch_forest_hills | birch_forest_hills | +| minecraft:fog_cherry_grove | cherry_grove | +| minecraft:fog_cold_beach | cold_beach | +| minecraft:fog_cold_ocean | cold_ocean | +| minecraft:fog_cold_taiga | cold_taiga | +| minecraft:fog_cold_taiga_hills | cold_taiga_hills | +| minecraft:fog_cold_taiga_mutated | cold_taiga_mutated | +| minecraft:fog_crimson_forest | crimson_forest | +| minecraft:fog_deep_cold_ocean | deep_cold_ocean | +| minecraft:fog_deep_frozen_ocean | deep_frozen_ocean | +| minecraft:fog_deep_lukewarm_ocean | deep_lukewarm_ocean | +| minecraft:fog_deep_ocean | deep_ocean | +| minecraft:fog_deep_warm_ocean | deep_warm_ocean | +| minecraft:fog_default | default | +| minecraft:fog_desert | desert | +| minecraft:fog_desert_hills | desert_hills | +| minecraft:fog_extreme_hills | extreme_hills | +| minecraft:fog_extreme_hills_edge | extreme_hills_edge | +| minecraft:fog_extreme_hills_mutated | extreme_hills_mutated | +| minecraft:fog_extreme_hills_plus_trees | extreme_hills_plus_trees | +| minecraft:fog_extreme_hills_plus_trees_mutated | extreme_hills_plus_trees_mutated | +| minecraft:fog_flower_forest | flower_forest | +| minecraft:fog_forest | forest | +| minecraft:fog_forest_hills | forest_hills | +| minecraft:fog_frozen_ocean | frozen_ocean | +| minecraft:fog_frozen_river | frozen_river | +| minecraft:fog_hell | hell | +| minecraft:fog_ice_mountains | ice_mountains | +| minecraft:fog_ice_plains | ice_plains | +| minecraft:fog_ice_plains_spikes | ice_plains_spikes | +| minecraft:fog_jungle | jungle | +| minecraft:fog_jungle_edge | jungle_edge | +| minecraft:fog_jungle_hills | jungle_hills | +| minecraft:fog_jungle_mutated | jungle_mutated | +| minecraft:fog_lukewarm_ocean | lukewarm_ocean | +| minecraft:fog_mangrove_swamp | mangrove_swamp | +| minecraft:fog_mega_spruce_taiga | mega_spruce_taiga | +| minecraft:fog_mega_spruce_taiga_mutated | mega_spruce_taiga_mutated | +| minecraft:fog_mega_taiga | mega_taiga | +| minecraft:fog_mega_taiga_hills | mega_taiga_hills | +| minecraft:fog_mega_taiga_mutated | mega_taiga_mutated | +| minecraft:fog_mesa | mesa | +| minecraft:fog_mesa_bryce | mesa_bryce | +| minecraft:fog_mesa_mutated | mesa_mutated | +| minecraft:fog_mesa_plateau | mesa_plateau | +| minecraft:fog_mesa_plateau_stone | mesa_plateau_stone | +| minecraft:fog_mushroom_island | mushroom_island | +| minecraft:fog_mushroom_island_shore | mushroom_island_shore | +| minecraft:fog_ocean | ocean | +| minecraft:fog_plains | plains | +| minecraft:fog_river | river | +| minecraft:fog_roofed_forest | roofed_forest | +| minecraft:fog_savanna | savanna | +| minecraft:fog_savanna_mutated | savanna_mutated | +| minecraft:fog_savanna_plateau | savanna_plateau | +| minecraft:fog_soulsand_valley | soulsand_valley | +| minecraft:fog_stone_beach | stone_beach | +| minecraft:fog_sunflower_plains | sunflower_plains | +| minecraft:fog_swampland | swampland | +| minecraft:fog_swampland_mutated | swampland_mutated | +| minecraft:fog_taiga | taiga | +| minecraft:fog_taiga_hills | taiga_hills | +| minecraft:fog_taiga_mutated | taiga_mutated | +| minecraft:fog_the_end | the_end | +| minecraft:fog_warm_ocean | warm_ocean | +| minecraft:fog_warped_forest | warped_forest | +*Last updated for 1.20.10* + diff --git a/docs/wiki/documentation/index.md b/docs/wiki/documentation/index.md new file mode 100644 index 00000000..05e96e29 --- /dev/null +++ b/docs/wiki/documentation/index.md @@ -0,0 +1,3 @@ +--- +title: Documentation +--- diff --git a/docs/wiki/documentation/material-config-description.md b/docs/wiki/documentation/material-config-description.md new file mode 100644 index 00000000..a23f9890 --- /dev/null +++ b/docs/wiki/documentation/material-config-description.md @@ -0,0 +1,618 @@ +--- +title: Material Configuration Description +tags: + - expert +mentions: + - MedicalJewel105 + - SmokeyStack +--- + +:::warning +Materials are not for the faint of heart. Be prepared for potential crashes, content log errors, and long loading times. +::: + +## Foreword + +This article is translated from https://mc.163.com/dev/mcmanual/mc-dev/mcguide/ - It is provided by Netease, the developers of china edition. The article will introduce the structure and configuration of the material file in detail. + +## Material files + +We will explain the material files of native Microsoft. First of all, the files under the directory are basically files with the suffix ".material". In addition, there are three important json files, namely common. json, fancy.json, sad.json. + +Let's take a look at sad.json and fancy.json first. They are used to control the image quality performance. Each of them defines a list of material files. fancy.json usually defines several more material files than sad.json and may Some additional macros have been added to some material files, and the shader can do special processing by judging these macros: + +sad.json + +```json +[ + {"path":"materials/sad.material"}, + {"path":"materials/entity.material"}, + {"path":"materials/terrain.material"}, + {"path":"materials/portal.material"}, + {"path":"materials/barrier.material"}, + {"path":"materials/wireframe.material"} +] +``` + +fancy.json + +```json +[ + {"path":"materials/fancy.material", "+defines":["FANCY"]}, + {"path":"materials/entity.material", "+defines":["FANCY"]}, + {"path":"materials/terrain.material", "+defines":["FANCY"]}, + {"path":"materials/hologram.material"}, + {"path":"materials/portal.material", "+defines":["FANCY"]}, + {"path":"materials/barrier.material"}, + {"path":"materials/wireframe.material"} +] +``` + +It can be seen that fancy.json defines more fancy.material and hologram.material material files than sad.json, and also defines FANCY macros for multiple material files. The switch of in-game settings/video/exquisite texture is to control the switch between sad and fancy. When the fancy texture switch is turned on, the material file in fancy.json will take effect, and when it is turned off, the material file in sad.json will take effect. + +In order to achieve better performance, the material files in fancy.json usually have more complex operations, while the materials in sad.json usually sacrifice a little rendering performance in exchange for better performance. If developers need to write more complex shaders, it is recommended to write a low-cost version at the same time, and then define them in fancy and sad respectively. Let the player control whether to turn on the corresponding effect through the exquisite texture option in the game. + +common.json + +```json +[ + {"path":"materials/particles.material"}, + {"path":"materials/shadows.material"}, + {"path":"materials/sky.material"}, + {"path":"materials/ui.material"}, + {"path":"materials/ui3D.material"}, + {"path":"materials/portal.material"}, + {"path":"materials/barrier.material"}, + {"path":"materials/wireframe.material"} +] +``` + +Compared with sad and fancy, they can be switched between each other. The material files defined in common.json will be loaded after entering the game. Material files are not loaded except those declared in common.json, sad.json, fancy.json. + +## Material syntax + +We use one of the material files entity.material to explain, open the file, we can see that the file starts with materials, and then defines the version number version as 1.0.0, these are fixed formats, which identify the parsing of this material file way, we can temporarily ignore it and not modify it. + +You can see that the definition of each field in the material is in the form of a key-value pair, for example: + +```json +[ + "vertexShader": "shaders/entity.vertex", +] +``` + +The left side of the colon represents the key as vertexShader, and the right side represents the value shaders/entity.vertex; + +There are also definitions in list form: + +```json +[ + "vertexFields": [ + { "field": "Position" }, + { "field": "Normal" }, + { "field": "UV0" } + ], +] +``` + +The declaration with the symbol [ ] is a list, and then inside is the json definition of each child element. + +## Overview of all property fields of the material + +### Render state + +#### `states` + +Configure the rendering environment, which can have the following values: + +- `EnableAlphaToCoverage`:An order-independent rendering method for translucent objects. This switch is only useful in environments that support MSAA. When enabled, the edges of objects will be more accurately softened and transitioned according to the transparency. It can also be used for some complex scenes with a large number of meshes overlapping. + +- `Wireframe`: Draw wireframe mode + +- `Blending`: Enables color blending mode, often used to render translucent objects. After declaring this, it is usually necessary to declare the blending factor blendSrc, blendDst + +- `DisableColorWrite`: Do not write color values to the color buffer, none of the RGBA channels are written + +- `DisableAlphaWrite`: Do not write transparency alpha values to the color buffer, allow RGB values to be written + +- `DisableRGBWrite`: Do not write transparency RGB values to the color buffer, allow writing alpha values + +- `DisableDepthTest`: Turn off depth testing + +- `DisableDepthWrite`: Turn off depth writing + +- `DisableCulling`: Render front and back simultaneously + +- `InvertCulling`:Use front cropping. The default is back cropping. After declaring this, the back side is rendered and the front side is cropped. + +- `StencilWrite`: Enable stencil mask writing + +- `EnableStencilTest`: Enable stencil mask testing + + +### Shader path + +#### `vertexShader` + +The path to the vertex shader, usually shaders/XXX.vertex. + +#### `vrGeometryShader` or `geometryShader` + +The path of the geometry shader, usually shaders/XXX.geometry, is not used on the mobile side, and does not need to be modified. + +#### `fragmentShader` + +The path to the fragment shader, usually shaders/XXX.fragment. + +### Shader macro definition + +#### `defines` + +Define macros for the shaders used. For code reuse, we use the same shader for many different materials. At this time, if you want to execute different logic somewhere in the shader according to the current material, you can judge it through the macro declared by the material defines. We can use the material entity_for_skeleton as an illustration. Here we can see that three macros USE_SKINNING, USE_OVERLAY, and NETEASE_SKINNING are defined. + +```json +"entity_for_skeleton": { + "vertexShader": "shaders/entity.vertex", + "vrGeometryShader": "shaders/entity.geometry", + "fragmentShader": "shaders/entity.fragment", + "+defines": [ "USE_SKINNING", "USE_OVERLAY", "NETEASE_SKINNING" ], + "vertexFields": [ + { "field": "Position" }, + { "field": "Normal" }, + { "field": "BoneId0" }, + { "field": "UV0" } + ], + "msaaSupport": "Both", + "+samplerStates": [ + { + "samplerIndex": 0, + "textureFilter": "Point" + } + ] +} +``` + +Looking at the vertex shader entity.vertex, there will be #ifdef, #else, #endif to judge the macro and execute different logic branches. These judgment statements of the macro are processed at compile time, unlike the if in the traditional shader. Else, the logic branch processed at compile time will not be generated in actual operation, and the performance will not be degraded due to the branch. In addition, it can be seen below that macros can also make multi-layer judgments. First, judge the NETEASE_SKINNING macro, and then judge the LARGE_VERTEX_SHADER_UNIFORMS macro in the internal execution logic: + +```glsl +#ifdef NETEASE_SKINNING + MAT4 boneMat = transpose(mat3x4ToMat4(BONES_70[int(BONEID_0)])); + entitySpacePosition = boneMat * POSITION; + entitySpaceNormal = boneMat * NORMAL; +#else + #if defined(LARGE_VERTEX_SHADER_UNIFORMS) + entitySpacePosition = BONES[int(BONEID_0)] * POSITION; + entitySpaceNormal = BONES[int(BONEID_0)] * NORMAL; + #else + entitySpacePosition = BONE * POSITION; + entitySpaceNormal = BONE * NORMAL; + #endif +#endif +``` + +### Runtime state + +#### Depth test + +##### `depthFunc` + +The depth detection pass function can use the following values: + +- `Always`: Always pass + +- `Equal`: Passed when the depth value is equal to the buffer value + +- `NotEqual`:Passed when the depth value is not equal to the buffer value + +- `Less`:Passed when the depth value is less than the buffer value + +- `Greater`:Passed when the depth value is greater than the buffer value + +- `GreaterEqual`:Pass when the depth value is greater than or equal to the buffer value + +- `LessEqual`:Pass when the depth value is less than or equal to the buffer value + +Associated states rendering environment configuration: + +- `DisableDepthTest`: Turn off depth testing + +- `DisableDepthWrite`: Turn off depth writing + +#### Stencil Mask Test + +##### `stencilRef` + +Value to compare with or to be written to the mask buffer + +##### `stencilRefOverride` + +Whether to use the buffer's current value as stencilRef, 0 or 1 is supported: + +- `1`: Use the configured stencilRef. If stencilRef is configured, stencilRefOverride will automatically take 1 + +- `0`: Use the current value of the buffer as stencilRef, in this case do not configure stencilRef + +##### `stencilReadMask` + +The mask buffer value and the stencilRef value are bit-ANDed with stencilReadMask before being compared + +##### `stencilWriteMask` + +The stencilRef value is bit-ANDed with stencilWriteMask before being written to the mask buffer + +##### `frontFace` and `backFace` + +Configure which mask test function to use on the front or back of the grid. In addition, the order of judgment is mask detection first, then depth detection. You need to configure the following operations: + + + +- `stencilFunc`: The method used when stencilRef is compared with the mask buffer, the following values are supported: + - `Always`: Always pass + - `Equal`: Passed when stencilRef is equal to the buffer value + - `NotEqual` :Passed when stencilRef is not equal to the buffer value + - `Less`:Passed when stencilRef is less than the buffer value + - `Greater`:Passed when stencilRef is greater than the buffer value + - `GreaterEqual`:Passed when stencilRef is greater than or equal to the buffer value + - `LessEqual`:Passed when stencilRef is less than or equal to the buffer value + +- `stencilFailOp`:The processing performed when the stencilFunc comparison function fails to return, supports the following values: + - `Keep`: Keep the original value of the buffer + - `Replace`: Writes the stencilRef bit and the value of stencilWriteMask to the buffer + +- `stencilDepthFailOp` : The stencilFunc comparison function returns success, but the processing performed when the depth test fails, supports the following values: + - `Keep`: Keep the original value of the buffer + - `Replace`: Writes the stencilRef bit and the value of stencilWriteMask to the buffer + +- `stencilPassOp`: The stencilFunc comparison function returns successfully, and the processing executed when the depth test is successful, supports the following values: + - `Keep`: Keep the original value of the buffer + - `Replace`: Writes the stencilRef bit and the value of stencilWriteMask to the buffer + +Associated states rendering environment configuration: + +- `StencilWrite`:Enable mask writing + +- `EnableStencilTest`: Enable mask testing + +Finally, let's look at an example: + +```json + "shadow_back": { + "+states": [ + "StencilWrite", + "DisableColorWrite", + "DisableDepthWrite", + "InvertCulling", + "EnableStencilTest" + ], + + "vertexShader": "shaders/position.vertex", + "vrGeometryShader": "shaders/position.geometry", + "fragmentShader": "shaders/flat_white.fragment", + + "frontFace": { + "stencilFunc": "Always", + "stencilFailOp": "Keep", + "stencilDepthFailOp": "Keep", + "stencilPassOp": "Replace" + }, + + "backFace": { + "stencilFunc": "Always", + "stencilFailOp": "Keep", + "stencilDepthFailOp": "Keep", + "stencilPassOp": "Replace" + }, + + "stencilRef": 1, + "stencilReadMask": 255, + "stencilWriteMask": 1, + + "vertexFields": [ + { "field": "Position" } + ], + "msaaSupport": "Both" + } +``` + +In the example, StencilWrite represents the support for writing to the mask buffer, EnableStencilTest represents the opening of the mask test, and the configuration of frontFace represents that the mask test always passes when the front face is rendered. If the depth test fails, the buffer value remains unchanged. If it also passes, the stencil bit and the value of stencilWriteMask will be written to the buffer, that is, 1 & 1 = 1 value. The configuration of backFace is also similar. + +#### Blend translucent object color blend + +The rendering of translucent objects needs to configure the blending factor. The final output rgb color value = current color value * source blending factor + color value in buffer * destination blending factor + +##### `blendSrc` + +source mix factor + +##### `blendDst` + +target blending factor + +##### `alphaSrc` + +The source blending factor when calculating alpha, usually not configured to take the default value + +##### `alphaDst` + +The target blending factor when calculating alpha, usually not configured to take the default value + +In total, the blending factor can take on the following values: + +- `DestColor`: Buffer color value + +- `SourceColor`: Current color value + +- `Zero`: (0,0,0) + +- `One`: (1,1,1) + +- `OneMinusDestColor`: (1,1,1) - buffer color value + +- `OneMinusSrcColor`: (1,1,1) - current color value + +- `SourceAlpha`: The alpha value in the current color + +- `DestAlpha`: Alpha value in buffer color + +- `OneMinusSrcAlpha`: 1 - alpha value in the current color value + +In the engine, the default is: + +- `blendSrc`:SourceAlpha + +- `blendDst`:OneMinusSrcAlpha + +- `alphaSrc`:One + +- `alphaDst`:OneMinusSrcAlpha + +Associated states rendering environment configuration: + +- `Blending`: Enables color blending mode, often used to render translucent objects. After declaring this, it is usually necessary - to declare the blending factor blendSrc, blendDst + +- `DisableColorWrite`: Do not write color values to the color buffer, none of the RGBA channels are written + +- `DisableAlphaWrite`: Do not write transparency alpha values to the color buffer, allow RGB values to be written + +- `DisableRGBWrite`: Do not write transparency RGB values to the color buffer, allow writing alpha values + +#### Sample texture sample + +##### `samplerStates` + +Configure the sampling state, the value is a list, and configure each texture according to the number of textures to be sampled. Usually, if UV0 and UV1 are declared in the vertex attribute, it means that two textures need to be sampled, and two elements need to be configured here. Let's look at the definition of child elements: + +```json +{ + "samplerIndex": 0, + "textureFilter": "Point", + "textureWrap": "Repeat" +} +``` + +Each property is defined as follows: + +##### `samplerIndex` + +Number, representing the attribute of the texture that is currently being set, starting from 0 + +##### `textureFilter` + +Texture filtering mode (default is Point), when the actual displayed texture map is enlarged or reduced compared to the original image, the mapping relationship between the new resolution map and the pixels on the original resolution map can have the following values: + + +- `Point`: Point sampling + +- `Bilinear`: Bilinear sampling + +- `Trilinear`: Trilinear sampling + +- `MipMapBilinear`: MipMap bilinear sampling + +- `TexelAA`:Texel antialiasing (not supported on all devices, not recommended) + +- `PCF`:Sampling by comparison function (not supported on all devices, not recommended) + +##### `textureWrap` + +Texture wrapping mode, which controls what kind of texture should be sampled when uv is outside [0,1]. It can have the following values: + +- `Repeat`: Repeat, that is, modulo the value to [0, 1] for sampling + +- `Clamp`: Edge sampling, sampling the value of the closest edge, that is, if 1.1 is closer to 1, then take 1; if -0.1 is closer to 0, then take 0. + + +#### Vertex + +##### `vertexFields` + +Vertex attributes, which are used to declare what attributes each vertex of the mesh that is rendered using this material holds. It is determined when the art is producing resources. The following values ​​may be used: + +- `Position`: Model space coordinates + +- `Color`: Color + +- `Normal`: Normal + +- `UV0`: Texture sample coordinates + +- `UV1`:Texture sample coordinates + +- `UV2`:Texture sample coordinates + +- `BoneId0`: Bone ID, used in the bone model + +#### Rasterizer environment configuration + +##### `msaaSupport` + +Configure MSAA (Multi-Sample Anti-Aliasing) support (the default in the engine is NonMSAA) + +- `NonMSAA`: Materials are allowed when MSAA is not enabled + +- `MSAA`: Materials are allowed when MSAA is enabled + +- `Both`:Materials are allowed with or without MSAA enabled. Usually just use this value. + + +##### `depth offset` + +Depth offset is mainly used to solve the z-fighting problem, that is, when two objects have similar depths, some frames may display this object and some frames display another object when rendering. The principle of depth offset is to offset one of the objects in the direction of large or small depth, so that their depths are no longer the same. The following four variables can be configured: + +- depthBias + +- slopeScaledDepthBias + +- depthBiasOGL + +- slopeScaledDepthBiasOGL + +The specific offset depth is: + +`offset = (slopeScaledDepthBias * m) + (depthBias * r)` + +On the OGL platform it is: + +`offset = (slopeScaledDepthBiasOGL * m) + (depthBiasOGL * r)` + +m is the maximum value in the slope of the depth of the polygon (computed at the rasterization stage). The more parallel a polygon is to the near clipping plane, the closer m is to 0. r is the smallest value that produces a discernible difference in depth values ​​in the window coordinate system, and r is a constant specified by the platform that implements OpenGL. + +Associated states rendering environment configuration: + +- `Wireframe`: Draw wireframe mode + +- `DisableCulling`: Render front and back simultaneously + +- `InvertCulling`:Use front cropping. The default is back cropping. After declaring this, the back side is rendered and the front - side is cropped. + +#### Primitive + +##### `primitiveMode` + +Primitive rendering mode (the default in the engine is TriangleList): + +- `None`: Do not render, normally not used + +- `QuadList`:Quadrilateral pattern + +- `TriangleList`: A pattern of drawing a triangle every three vertices, for example the first triangle uses vertices v0, v1, v2, and the second uses v3, v4, v5 + +- `TriangleStrip`: Each vertex will form a triangle with the first two vertices, the structure is a bit more complicated, but it - will save the amount of data + +- `LineList`: Draw a line segment every two vertices + +- `Line`: Each vertex forms a line segment with a vertex that appears before it. + +### Material variant + +#### `variants` + +Useful for quickly implementing multiple sub-materials based on most of the same definitions. See the actual example of entity_static below: + +```json + "entity_static": { + "vertexShader": "shaders/entity.vertex", + "vrGeometryShader": "shaders/entity.geometry", + "fragmentShader": "shaders/entity.fragment", + "vertexFields": [ + { "field": "Position" }, + { "field": "Normal" }, + { "field": "UV0" } + ], + "variants": [ + { + "skinning": { + "+defines": [ "USE_SKINNING" ], + "vertexFields": [ + { "field": "Position" }, + { "field": "BoneId0" }, + { "field": "Normal" }, + { "field": "UV0" } + ] + } + }, + { + "skinning_color": { + "+defines": [ "USE_SKINNING", "USE_OVERLAY" ], + "+states": [ "Blending" ], + "vertexFields": [ + { "field": "Position" }, + { "field": "BoneId0" }, + { "field": "Color" }, + { "field": "Normal" }, + { "field": "UV0" } + ] + } + } + ], + "msaaSupport": "Both", + "+samplerStates": [ + { + "samplerIndex": 0, + "textureFilter": "Point" + } + ] + } +``` + +Variants are declarations of material variants. The above declarations declare two sub-variants, skinning and skinning_color. Some external fields are rewritten in the sub-variants. In actual use, it is equivalent to quickly defining two materials. The body and the variant are connected with a dot ".". The two materials are entity_static.skinning and entity_static.skinning_color. + +In addition, if there are other materials that inherit from entity_static, such as entity_dynamic, this material will also inherit these two variants, entity_dynamic.skinning and entity_dynamic.skinning_color. + +## Material Merge Rules + +When the same material is declared in different directory files, it will be merged according to the following rules after loading: 1. Normally, the material fields of the files loaded later will overwrite the previously loaded ones. 2. The following fields are special. Operations to add attributes with "+" and delete attributes with "-" are supported: + +- defines +- states +- samplerStates + +As an example, for example, such a material is declared in the package body file (irrelevant code is omitted), and three macros are defined: + +```json +"testMat": { + "defines": [ "MACRO_1", "MACRO_2", "MACRO_3" ], +} +``` + +At this point, a mod also declares this material, defining another three macros: + +```json +"testMat": { + "defines": [ "MACRO_4", "MACRO_5", "MACRO_6" ], +} +``` + +In the above case, the final runtime is equivalent to the defines field being overwritten, and the macros that take effect at the actual runtime are only: MACRO_4, MACRO_5, MACRO_6 + +If the "+" symbol is used when defining in the MOD: + +```json +"testMat": { + "+defines": [ "MACRO_4", "MACRO_5", "MACRO_6" ], +} +``` + +Equivalent to adding definitions on the original basis, the macros that take effect at actual runtime are: MACRO_1, MACRO_2, MACRO_3, MACRO_4, MACRO_5, MACRO_6 + +If the "-" symbol is used when defining in the MOD: + +```json +"testMat": { + "-defines": [ "MACRO_3"], +} +``` + +It is equivalent to deleting some definitions on the original basis, the only macros that take effect at runtime are: MACRO_1, MACRO_2 + +If multiple files define the same material, and they involve overlay, add, and delete operations, the order in which they will take effect is: first perform all overlay operations, then perform all add operations, and finally perform all delete operations . + +i.e. if one of the material files declares a delete MACRO_3 action: + +```json +"testMat": { + "-defines": [ "MACRO_3"], +} +``` + +Then no matter how other files are covered, add MACRO_3, and this material must not have MACRO_3 macro after the final synthesis. \ No newline at end of file diff --git a/docs/wiki/documentation/materials.md b/docs/wiki/documentation/materials.md new file mode 100644 index 00000000..677355c0 --- /dev/null +++ b/docs/wiki/documentation/materials.md @@ -0,0 +1,419 @@ +--- +title: Vanilla Materials +show_toc: false +tags: + - expert +mentions: + - SirLich + - Luthorius + - MedicalJewel105 + - SmokeyStack + - ThomasOrs +--- + +:::warning +Materials are not for the faint of heart. Be prepared for potential crashes, content log errors, and long loading times. +::: + +Materials are extremely useful for making entities more unique. You can make new ones for your addons, or use pre-existing vanilla materials. + +You can learn more about creating materials [here](/visuals/materials). + +## List of Vanilla Materials + +| Vanilla_Material | +| --------------------------------------------------------------------------------------- | +| [alpha_block](#alpha-block) | +| [alpha_block_color](#alpha-block-color) | +| [banner](#banner) | +| [banner_pole](#banner-pole) | +| [beacon_beam](#beacon-beam) | +| [beacon_beam_transparent](#beacon-beam-transparent) | +| [charged_creeper](#charged-creeper) | +| [conduit_wind](#conduit-wind) | +| [entity](#entity) | +| [entity_alphablend](#entity-alphablend) | +| [entity_alphablend_nocolorentity_static](#entity-alphablend-nocolorentity-static) | +| [entity_alphatest](#entity-alphatest) | +| [entity_alphatest_change_color](#entity-alphatest-change-color) | +| [entity_alphatest_change_color_glint](#entity-alphatest-change-color-glint) | +| [entity_alphatest_glint](#entity-alphatest-glint) | +| [entity_alphatest_glint_item](#entity-alphatest-glint-item) | +| [entity_alphatest_multicolor_tint](#entity-alphatest-multicolor-tint) | +| [entity_beam](#entity-beam) | +| [entity_beam_additive](#entity-beam-additive) | +| [entity_change_color](#entity-change-color) | +| [entity_change_color_glint](#entity-change-color-glint) | +| [entity_custom](#entity-custom) | +| [entity_dissolve_layer0](#entity-dissolve-layer0) | +| [entity_dissolve_layer1](#entity-dissolve-layer1) | +| [entity_emissive](#entity-emissive) | +| [entity_emissive_alpha](#entity-emissive-alpha) | +| [entity_emissive_alpha_one_sided](#entity-emissive-alpha-one-sided) | +| [entity_flat_color_line](#entity-flat-color-line) | +| [entity_glint](#entity-glint) | +| [entity_lead_base](#entity-lead-base) | +| [entity_loyalty_rope](#entity-loyalty-rope) | +| [entity_multitexture](#entity-multitexture) | +| [entity_multitexture_alpha_test](#entity-multitexture-alpha-test) | +| [entity_multitexture_alpha_test_color_mask](#entity-multitexture-alpha-test-color-mask) | +| [entity_multitexture_color_mask](#entity-multitexture-color-mask) | +| [entity_multitexture_masked](#entity-multitexture-masked) | +| [entity_multitexture_multiplicative_blend](#entity-multitexture-multiplicative-blend) | +| [entity_nocull](#entity-nocull) | +| [guardian_ghost](#guardian-ghost) | +| [item_in_hand](#item-in-hand) | +| [item_in_hand_entity_alphatest](#item-in-hand-entity-alphatest) | +| [item_in_hand_entity_alphatest_color](#item-in-hand-entity-alphatest-color) | +| [item_in_hand_glint](#item-in-hand-glint) | +| [item_in_hand_multicolor_tint](#item-in-hand-multicolor-tint) | +| [map](#map) | +| [map_decoration](#map-decoration) | +| [map_marker](#map-marker) | +| [moving_block](#moving-block) | +| [moving_block_alpha](#moving-block-alpha) | +| [moving_block_alpha_seasons](#moving-block-alpha-seasons) | +| [moving_block_alpha_single_side](#moving-block-alpha-single-side) | +| [moving_block_blend](#moving-block-blend) | +| [moving_block_double_side](#moving-block-double-side) | +| [moving_block_seasons](#moving-block-seasons) | +| [opaque_block](#opaque-block) | +| [opaque_block_color](#opaque-block-color) | +| [opaque_block_color_uv2](#opaque-block-color-uv2) | + +## Properties + +Materials can have a range of different properties which affect their appearance, including: + +### Backface-Culling + +This makes the inside faces of models **not** render. + +### Alpha Channel + +Enables analogue translucency, usage of the alpha channel of textures. + +### Emissive + +Causes the texture to not be affected by dim lighting, and appear to glow. If there is usage of the alpha channel, the emissivity is in direct proportion to how transparent each individual pixel is. + +### Set Translucency + +Regardless of other properties, is always completely rendered at a pre-determined translucency. + +### Texture Blending + +When multiple textures are present, may use a filter of sorts to change the entities appearance, based on the textures. + +## Details on the Materials + +The following is a last of each material, along with general known properties. The names are vague pointers to what each will do, some may act rather unpredictably, or have undocumented usages, so this only is what's certain for each: + +:::warning +The following section has currently **only** been tested for with single textures. Take it all with a pinch of salt. It is highly recommended to experiment with the materials yourself. +::: + +### alpha_block + +- Backface-culling +- Completely Opaque + +### alpha_block_color + +- Backface-Culling +- Translucencies as Transparent + +### banner + +Inconsistently renders objects with transparency behind. + +- N/A + +### banner_pole + +Inconsistently renders objects with transparency behind. + +- Backface-Culling +- Transparency + +### beacon_beam + +- Completely Opaque + +### beacon_beam_transparent + +This one is rather different. Particles that are behind it are rendered in front, and it appears to have "Frontface-Culling". + +- Alpha Channel + +### charged_creeper + +Inconsistently renders objects with transparency behind. + +- Emissive +- Set Translucency + +### conduit_wind + +- Transparency +- Translucency as Transparency + +### entity + +- Completely Opaque +- Backface Culling + +### entity_alphablend + +Inconsistently renders objects with transparency behind. + +- Backface-Culling +- Alpha Channel + +### entity_alphablend_nocolorentity_static + +- Unknown +- Potential Crash + +### entity_alphatest + +- Transparency +- Translucency as Transparency + +### entity_alphatest_change_color + +- Transparency +- Translucency as Opaque + +### entity_alphatest_change_color_glint + +- Unknown + +### entity_alphatest_glint + +- Unknown + +### entity_alphatest_glint_item + +- Unknown + +### entity_alphatest_multicolor_tint + +- Greyscale +- Backface-Culling +- Transparency +- Translucency as Opaque + +### entity_beam + +- Transparency +- Translucency as Transparency + +### entity_beam_additive + +Particles always render on top + +- Transparency +- Emissive +- Backface-Culling +- Set Translucency + +### entity_change_color + +- Completely Opaque + +### entity_change_color_glint + +- Unknown + +### entity_custom + +Inconsistently renders objects with transparency behind. + +- Backface-Culling +- Alpha Channel + +### entity_dissolve_layer0 + +Inconsistently renders objects with transparency behind. + +- Unknown + +### entity_dissolve_layer1 + +- Unknown + +### entity_emissive + +- Emissive +- Completely Opaque +- Backface-Culling + +### entity_emissive_alpha + +- Emissive +- Alpha Channel +- Transparency + +### entity_emissive_alpha_one_sided + +- Emissive +- Alpha Channel +- Transparency +- Backface-Culling + +### entity_flat_color_line + +- Backface-Culling +- Completely Opaque + +### entity_glint + +- Unknown + +### entity_lead_base + +Inconsistently renders objects with transparency behind. + +- Alpha Channel + +### entity_loyalty_rope + +- Unknown + +### entity_multitexture + +- Unknown + +### entity_multitexture_alpha_test + +- Unknown + +### entity_multitexture_alpha_test_color_mask + +- Unknown + +### entity_multitexture_color_mask + +- Unknown + +### entity_multitexture_masked + +- Unknown + +### entity_multitexture_multiplicative_blend + +- Unknown + +### entity_nocull + +- Completely Opaque + +### guardian_ghost + +Inconsistently renders objects with transparency behind. + +- Backface-Culling +- Alpha Channel + +### item_in_hand + +- Completely Opaque +- Backface-Culling + +### item_in_hand_entity_alphatest + +- Transparency +- Translucency into either Opaque or Transparent depends on level. + +### item_in_hand_entity_alphatest_color + +- Transparency +- Translucency into either Opaque or Transparent depends on level. + +### item_in_hand_glint + +- Unknown + +### item_in_hand_multicolor_tint + +- Greyscale +- Completely Opaque +- Backface-Culling + +### map + +- Transparency +- Translucency into either Opaque or Transparent depends on level. + +### map_decoration + +- Backface-Culling +- Transparency +- Translucency into either Opaque or Transparent depends on level. + +### map_marker + +- Backface-Culling +- Transparency +- Translucency into either Opaque or Transparent depends on level. +- Potential Crash + +### moving_block + +- Completely Opaque +- Backface-Culling + +### moving_block_alpha + +- Backface-Culling +- Transparency +- Translucency into either Opaque or Transparent depends on level. + +### moving_block_alpha_seasons + +- Translucency into either Opaque or Transparent depends on level. +- Transparency + +### moving_block_alpha_single_side + +- Backface-Culling +- Transparency +- Translucency into either Opaque or Transparent depends on level. + +### moving_block_blend + +Inconsistently renders objects with transparency behind. + +- Backface-Culling +- Alpha Channel + +### moving_block_double_side + +- Completely Opaque + +### moving_block_seasons + +- Completely Opaque +- Backface-Culling + +### opaque_block + +- Completely Opaque +- Backface-Culling + +### opaque_block_color + +- Completely Opaque +- Backface-Culling + +### opaque_block_color_uv2 + +- Completely Opaque +- Backface-Culling + + +:::warning +Please note, that these have also only been tested using a RenderDragon platform. Non-RenderDragon visuals may differ. +::: + diff --git a/docs/wiki/documentation/pack-structure.md b/docs/wiki/documentation/pack-structure.md new file mode 100644 index 00000000..6e12ff78 --- /dev/null +++ b/docs/wiki/documentation/pack-structure.md @@ -0,0 +1,113 @@ +--- +title: Pack Folder Structure +show_toc: false +mentions: + - SirLich + - ThijsHankelMC + - MedicalJewel105 + - Esatz77 + - ChibiMango + - TheItsNameless + - JaylyDev + - SmokeyStack +--- + + diff --git a/docs/wiki/documentation/projectiles.md b/docs/wiki/documentation/projectiles.md new file mode 100644 index 00000000..20a82b8c --- /dev/null +++ b/docs/wiki/documentation/projectiles.md @@ -0,0 +1,256 @@ +--- +title: Projectiles +mentions: + - SirLich + - stirante + - retr0cube + - SmokeyStack + - Luthorius + - ThomasOrs +--- + +## Overview + +This page intends to document all different fields you can use inside `minecraft:projectile` entity behavior component. + +:::warning +_Disclaimer: this component has been mostly documented based on projectiles found in the game or reverse engineering the game._ +_This information was last tested on **1.18.2**._ +::: + +| Name | Type | Default Value | Description | +| ------------------------- | ---------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| anchor | Integer | | | +| angle_offset | Decimal | 0 | Determines the angle at which the projectile is thrown | +| catch_fire | Boolean | false | If true, the entity hit will be set on fire | +| crit_particle_on_hurt | Boolean | false | If true, the projectile will produce critical hit particles when it happens | +| destroy_on_hurt | Boolean | false | If true, this entity will be destroyed when hit | +| filter | String | | Entity Definitions defined here can't be hurt by the projectile | +| fire_affected_by_griefing | Boolean | false | If true, whether the projectile causes fire is affected by the mob griefing game rule | +| gravity | Decimal | 0.05 | The gravity applied to this entity when thrown. The higher the value, the faster the entity falls | +| hit_ground_sound | String | | The sound that plays when the projectile hits ground | +| hit_sound | String | | The sound that plays when the projectile hits an entity | +| homing | Boolean | false | If true, the projectile homes in to the nearest. **Does not work on 1.18.2** entity | +| inertia | Decimal | 0.99 | The fraction of the projectile's speed maintained every frame while traveling in air | +| is_dangerous | Boolean | false | If true, the projectile will be treated as dangerous to the players | +| knockback | Boolean | true | If true, the projectile will knock back the entity it hits | +| lightning | Boolean | false | If true, the entity hit will be struck by lightning | +| liquid_inertia | Decimal | 0.6 | The fraction of the projectile's speed maintained every frame while traveling in water | +| multiple_targets | Boolean | true | If true, the projectile can hit multiple entities per flight | +| offset | Vector [a, b, c] | [0, 0.5, 0] | The offset from the entity's anchor where the projectile will spawn | +| on_fire_time | Decimal | 5 | Time in seconds that the entity hit will be on fire for | +| on_hit | Object | | Projectile's behavior on hit. More info [below](#on_hit) | +| particle | String | iconcrack | Particle to use upon collision | +| potion_effect | Integer | -1 | Defines the effect the arrow will apply to the entity it hits | +| power | Decimal | 1.3 | Determines the velocity of the projectile | +| reflect_on_hurt | Boolean | false | If true, this entity will be reflected back when hit | +| semi_random_diff_damage | Boolean | false | If true, damage will be randomized based on damage and speed | +| shoot_sound | String | | The sound that plays when the projectile is shot | +| shoot_target | Boolean | true | If true, the projectile will be shot towards the target of the entity firing it | +| should_bounce | Boolean | false | If true, the projectile will bounce upon hit | +| splash_potion | Boolean | false | If true, the projectile will be treated like a splash potion | +| splash_range | Decimal | 4 | Radius in blocks of the 'splash' effect | +| stop_on_hurt | Boolean | | | +| uncertainty_base | Decimal | 0 | The base accuracy. Accuracy is determined by the formula uncertaintyBase - difficultyLevel \* uncertaintyMultiplier | +| uncertainty_multiplier | Decimal | 0 | Determines how much difficulty affects accuracy. Accuracy is determined by the formula uncertaintyBase - difficultyLevel \* uncertaintyMultiplier | +| hit_water | Boolean | false | If true, liquid blocks will be treated as solid. **Requires "Education Edition" toggle active** | + +## on_hit + +This object contains all behaviors, that can be executed, when projectile hits something. + +### arrow_effect + +_Exact behavior unknown_ + +### teleport_owner + +Teleports shooter to the hit location. + +### catch_fire + +_Exact behavior unknown_ + +Sets target on fire + +### ignite + +_Exact behavior unknown_ + +Sets target on fire + +### remove_on_hit + +Removes the projectile when it hits something. + +### douse_fire + +_Exact behavior unknown_ + +### impact_damage + +Deals damage on hit. + +| Name | Type | Description | +| ------------------------------ | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| damage | Integer/Integer Array [min, max] | Damage dealt to entity on hit | +| semi_random_diff_damage | Boolean | | +| max_critical_damage | Decimal | | +| min_critical_damage | Decimal | | +| power_multiplier | Decimal | | +| channeling | Boolean | | +| set_last_hurt_requires_damage | Boolean | | +| destroy_on_hit_requires_damage | Boolean | | +| filter | String | Entity to affect. Much more primitive than filters used elsewhere, as it cannot "test" for anything other than an identifier | +| destroy_on_hit | Boolean | | +| knockback | Boolean | | +| catch_fire | Boolean | Dictates wether or not targets will be engulfed in flames | + +### definition_event + +Calls an event on hit. + +| Name | Type | Description | +| ------------------ | ------- | --------------------------------------------------- | +| affect_projectile | Boolean | Event will be triggered for projectile entity | +| affect_shooter | Boolean | Event will be triggered for shooter entity | +| affect_target | Boolean | Event will be triggered for hit entity | +| affect_splash_area | Boolean | Event will be triggered for all entities in an area | +| splash_area | Decimal | Area of entities | +| event_trigger | Object | Event to trigger. Structure below. | + +| Name | Type | Description | +| ------- | ------ | ------------------------------------- | +| event | String | Event to trigger | +| target | String | Target of the event | +| filters | Object | Criteria required in order to trigger | + +### stick_in_ground + +Sticks the projectile into the ground. + +| Name | Type | Description | +| ---------- | ------- | ----------- | +| shake_time | Decimal | | + +### spawn_aoe_cloud + +Spawns an area of effect cloud of potion effect. + +| Name | Type | Description | +| ------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| radius | Decimal | Radius of the cloud | +| radius_on_use | Decimal | | +| potion | Integer | Lingering Potion ID | +| particle | String | [Vanilla Particles](/particles/vanilla-particles) emitter of the cloud. Only accepts Vanilla Particles. **dragonbreath** enables the usage of Bottles to obtain Dragon's Breath. | +| duration | Integer | Duration of the cloud in seconds | +| color | Integer array [r, g, b] | Color of the particles | +| affect_owner | Boolean | Is potion effect affecting the shooter. Does not appear to apply to the player | +| reapplication_delay | Integer | Delay in ticks between application of the potion effect | + +#### Potion IDs + +| Potion | Regular | Extended | Enhanced (Level II) | +| ------------------------- | ------- | -------- | ------------------- | +| Water Bottle | 0 | | | +| Mundane Potion | 1 | 2 | | +| Thick Potion | 3 | | | +| Awkward Potion | 4 | | | +| Potion of Night Vision | 5 | 6 | | +| Potion of Invisibility | 7 | 8 | | +| Potion of Leaping | 9 | 10 | 11 | +| Potion of Fire Resistance | 12 | 13 | | +| Potion of Swiftness | 14 | 15 | 16 | +| Potion of Slowness | 17 | 18 | | +| Potion of Water Breathing | 19 | 20 | | +| Potion of Healing | 21 | | 22 | +| Potion of Harming | 23 | | 24 | +| Potion of Poison | 25 | 26 | 27 | +| Potion of Regeneration | 28 | 29 | 30 | +| Potion of Strength | 31 | 32 | 33 | +| Potion of Weakness | 34 | 35 | | +| Potion of Decay | 36 | | | +| Potion of Turtle Master | 37 | 38 | 39 | +| Potion of Slow Falling | 40 | 41 | | +| Potion of Slowness IV | 42 | | | +| Potion of Crashing | 43+ | | | + +### spawn_chance + +Spawns an entity on hit. + +| Name | Type | Description | +| --------------------------- | ------- | ------------------------------------------- | +| first_spawn_percent_chance | Decimal | | +| second_spawn_percent_chance | Decimal | | +| first_spawn_count | Integer | | +| second_spawn_count | Integer | | +| spawn_definition | String | ID of the entity to spawn | +| spawn_baby | Boolean | Whether the spawned entity should be a baby | + +### particle_on_hit + +Spawns particles on hit. + +| Name | Type | Description | +| ------------- | ------- | -------------------------------------------------------- | +| particle_type | String | [Vanilla Particles](/particles/vanilla-particles) to use | +| num_particles | Integer | Number of particles | +| on_entity_hit | Boolean | Whether it should spawn particles on entity hit | +| on_other_hit | Boolean | Whether it should spawn particles on other hit | + + +### mob_effect + +Applies a mob effect to the target. + +| Name | Type | Description | +| -------------- | ------- | ------------------------------------------- | +| effect | String | Effect | +| duration | Integer | Duration of the effect | +| durationeasy | Integer | Duration of the effect on easy difficulty | +| durationnormal | Integer | Duration of the effect on normal difficulty | +| durationhard | Integer | Duration of the effect on hard difficulty | +| amplifier | Integer | Effect amplifier | +| ambient | Boolean | | +| visible | Boolean | | + +### grant_xp + +Despite the name, this actually spawns a number of experience orbs, being worth the amount stated. + +| Name | Type | Description | +| ----- | ------- | ----------------------------------------------------------------------------------------------- | +| minXP | Integer | Minimum amount of experience to give | +| maxXP | Integer | Maximum amount of experience to give | +| xp | Integer | Constant amount of experience to give. When set, it will be used instead of min and max values. | + +### freeze_on_hit + +_Exact behavior unknown_ + +_Requires Education Edition toggle to be enabled._ +Freezes water on hit. + +| Name | Type | Description | +| ------------- | ------- | ----------------------------- | +| shape | String | "sphere" or "cube" | +| snap_to_block | Boolean | | +| size | Integer | The size of the freeze effect | + +### hurt_owner + +_Exact behavior unknown. Right now it crashes minecraft probably because of wrong parameters_ + +| Name | Type | Description | +| ------------ | ------- | ----------- | +| owner_damage | Integer | | +| knockback | Boolean | | +| ignite | Boolean | | + +### thrown_potion_effect + +_Exact behavior unknown. Right now it crashes minecraft probably because it's only valid for thrown potions_ + +## Additional Information +When it comes to creating a custom projectile, such as an arrow or trident variant, or something entirely your own, you may want to consider defining a [runtime identifier](/entities/runtime-identifier) to ensure that it acts as intended. Not doing so may result in unintended behaviour, from odd visuals to incorrect knockback direction and arrows that you can kill with your bare hands. \ No newline at end of file diff --git a/docs/wiki/documentation/queries.md b/docs/wiki/documentation/queries.md new file mode 100644 index 00000000..51185518 --- /dev/null +++ b/docs/wiki/documentation/queries.md @@ -0,0 +1,567 @@ +--- +title: Molang Queries +toc_max_level: 2 +mentions: + - SirLich + - solvedDev + - stirante + - SmokeyStack + - Dreamedc2015 + - Ultr4Anubis + - MedicalJewel105 + - TreaBeane + - r4isen1920 + - ChillRx + - Luthorius + - TheItsNameless + - ThomasOrs +--- + +The bedrock documentation for Molang is notoriously bad. This page will attempt to remedy this by providing additional details for individual queries, _where possible_. This page is intended to be searched, not read in full. Use the side-bar, or use `ctrl-f` to navigate. + +:::tip +This page is not an exhaustive list list! It only contains queries we've written extra information for. The full list of queries can be found [here](https://bedrock.dev/docs/stable/Molang#List%20of%20Entity%20Queries)! +::: + +## query.armor_texture_slot + +Formatted like: `query.armor_texture_slot(x) = y`. + +Where `x` and `y` are both integer arguments, from the following table: + +### X + +| Argument | Slot | +| -------- | ---------- | +| 0 | Helmet | +| 1 | Chestplace | +| 2 | Leggings | +| 3 | Boots | + +### Y + +| Argument | Type | +| -------- | --------------------- | +| -1 | none | +| 0 | Leather armor piece | +| 1 | Chain armor piece | +| 2 | Iron armor piece | +| 3 | Diamond armor piece | +| 4 | Gold armor piece | +| 5 | Elytra | +| 6 | Turtle helmet | +| 7 | Netherite armor piece | + +### Y for horses + +| Argument | Type | +| -------- | --------------------- | +| 1 | Leather armor piece | +| 2 | Iron armor piece | +| 3 | Gold armor piece | +| 4 | Diamond armor piece | + +### Example + +`query.armor_texture_slot(3) == 1`: queries for Iron Boots. + +## query.armor_material_slot + +Formatted like: `query.armor_material_slot(x) = y`. + +Where `x` and `y` are both integer arguments, from the following table: + +### X + +| Argument | Slot | +| -------- | ---------- | +| 0 | Helmet | +| 1 | Chestplace | +| 2 | Leggings | +| 3 | Boots | + +### Y + +Unknown, possibly: + +| Argument | Slot | +| -------- | -------------------------- | +| 0 | Default armor material | +| 1 | Enchanted armor material | +| 2 | Leather armor material | +| 3 | Leather enchanted material | + +## query.armor_color_slot + +_Notice: As of version `1.16.100.51`, this query is crashing minecraft. It might be fixed in later versions._ + +Formatted like: `color = query.armor_color_slot(slot, channel)`. + +Where `slot` and `channel` are both integer arguments, from the following tables: + +### Slot + +| Argument | Slot | +| -------- | ---------- | +| 0 | Helmet | +| 1 | Chestplace | +| 2 | Leggings | +| 3 | Boots | + +### Channel + +| Argument | Slot | +| -------- | ------------- | +| 0 | Red channel | +| 1 | Green channel | +| 2 | Blue channel | +| 3 | Alpha channel | + +### Color + +Query returns color value in specified channel. + +## query.get_equipped_item_name + +:::warning +**DEPRECATED QUERY:** It is recommended to use the new query (`query.is_item_name_any`) if possible as it is more of an updated version of this query. However, this query will still continue to work in the future for backwards compatibility. +::: + +Formatted like: `query.get_equipped_item_name('main_hand') = 'item_name'` + +Takes one optional hand slot as a parameter (0 or 'main_hand' for main hand, 1 or 'off_hand' for off hand), and a second parameter (0=default) if you would like the equipped item or any non-zero number for the currently rendered item, and returns the name of the item in the requested slot (defaulting to the main hand if no parameter is supplied) if there is one, otherwise returns ''. + +Where `item_name` is the item you want to test for. No namespace, and please notice the quotes. + +Example: `"query.get_equipped_item_name == 'diamond'"` + +**Can you test for items in the inventory? Yes! Using the new query `query.is_item_name_any`.** + +## query.get_name + +:::warning +**DEPRECATED QUERY:** It is recommended to use the new query (`query.is_name_any`) if possible as it is more of an updated version of this query. However, this query will still continue to work in the future for backwards compatibility. +::: + +Formatted like: `query.get_name == 'Name'` + +Turns true if actual in-game displayed name matches name (use OnixClient to see names in third view). +Needs to be used in special conditions. + + + +animation_controllers/ac.json + +```json +{ + "format_version": "1.10.0", + "animation_controllers": { + "controller.animation.ac": { + "initial_state": "default", + "states": { + "default": { + "transitions": [ + { + "active": "query.is_alive" + } + ] + }, + "active": { + "transitions": [ + { + "default": "(1.0)" + } + ], + "animations": [ + { + "anim": "query.get_name == '...'" // You can use it only here! + } + ] + } + } + } + } +} +``` + + + +## query.is_name_any + +Formatted like: `query.get_name('Name1', 'Name2')`. +Takes one or more arguments. +Turns true if actual in-game displayed name matches one of the given names. +Needs to be used in special conditions. + + + +animation_controllers/ac.json + +```json +{ + "format_version": "1.10.0", + "animation_controllers": { + "controller.animation.ac": { + "initial_state": "default", + "states": { + "default": { + "transitions": [ + { + "active": "query.is_alive" + } + ] + }, + "active": { + "transitions": [ + { + "default": "(1.0)" + } + ], + "animations": [ + { + "anim": "query.is_name_any(...)" // You can use it only here! + } + ] + } + } + } + } +} +``` + + + +## query.is_item_name_any + +Formatted like: `query.is_item_name_any('slot.weapon.mainhand', 0, 'namespace:item_name')` + +Takes the equipment slot name first, followed by the slot index value, and then the list of item names with namespaces after it. + +Possible equipment slot are as follows: +| Slot Name | Slot Counts | Description | +| ---------------------- | ----------- | ----------------------------------------------------------------------------------- | +| `slot.weapon.mainhand` | 0 | Usually any held items are in here | +| `slot.weapon.offhand` | 0 | Offhand slot for things like `Shield`, `Totem of Undying` or a `Map` | +| `slot.armor.head` | 0 | Head armor piece | +| `slot.armor.chest` | 0 | Chestplate armor piece | +| `slot.armor.legs` | 0 | Leggings armor piece | +| `slot.armor.feet` | 0 | Boots armor piece | +| `slot.armor` | 0 | Horse armor | +| `slot.saddle` | 0 | Saddle slot | +| `slot.hotbar` | 0 to 8 | Player hotbar slots | +| `slot.inventory` | 0+ (varies) | Entities that has an inventory, like the player, minecart with chests, donkey, etc. | +| `slot.enderchest` | 0 to 26 | Ender chest inventory for players only | + +### Test for items within the player's inventory + +Formatted like: `t.val = 0; t.i = 0; loop(27, {t.val = q.is_item_name_any('slot.inventory', t.i, 'namespace:item_name'); t.val ? {return t.val;}; t.i = t.i+1;});` + +Replace `namespace:item_name` with any item you wish to check for. This simply loops through all 27 slots of the inventory and returns `1.0` if it has found any slot that has the specified item provided. Note that the hotbar is in a different slot from the main inventory slot so you will have to check that separately. + +## query.is_enchanted + +Formatted like: `is_enchanted = query.is_enchanted`. + +Return 1.0 or 0.0 based on whether the entity is enchanted. + +_Currently, can be only used in materials._ + +## query.is_eating + +This query tracks when certain entities are 'eating'. It's not used for the player. To trigger, use one of the following components: + - `minecraft:behavior.eat_carried_item` + - `minecraft:behavior.snacking` + +## query.is_ghost + +Formatted like: `is_ghost = query.is_ghost`. + +Return 1.0 or 0.0 based on whether the entity is a ghost. + +_Currently, only returns 1.0 for a guardian ghost and is used by its renderer._ + +## query.is_grazing + +Formatted like: `is_grazing = query.is_grazing`. + +Return 1.0 or 0.0 based on whether the entity is eating a block. + +_Currently, only returns 1.0 for a sheep and entities using runtime identifier of a sheep._ + +## query.is_jumping + +Formatted like: `is_jumping = query.is_jumping`. + +Return 1.0 or 0.0 based on whether the entity is jumping. + +For the player, conditions for its activation are: + +- the jump button is pressed (includes being in water and climbing a scaffolding) +- OR auto-jump is triggered +- OR swimming with auto-jump +- OR charging the jump of a ridable entity + +## query.modified_move_speed + +Formatted like: `modified_move_speed = query.modified_move_speed`. + +Returns the current walk speed of the entity modified by status flags such as is_baby or on_fire + +Value example: + +- Player is walking: around 0.86 +- Player is sprinting: 1.0 +- Player is sprinting and jumping: 0.35 +- Player is walking on fire: 1.0 +- Player is sprinting on fire: 1.0 +- Player is sprinting and jumping on fire: 0.525 + +## query.log + +Content log is NOT debug log, they're different files. `query.log` outputs to the debug log only. + +## query.on_fire_time + +Formatted like: `on_fire_time = query.on_fire_time`. + +Returns the time in ticks since the entity started or stopped being on fire, else it returns 0.0 + +Value example: + +- Entity is summoned: value is 0 +- Entity is ignited: value is 0 and starts counting up 1 every tick +- Entity is on fire for 2 seconds already: value is 40 and still counts up 1 every tick +- Entity stops being on fire: value resets to 0 and continues to count up 1 every tick despite not being on fire +- Entity is ignited second time: value resets to 0 and continues counting up 1 every tick +- Entity stops being on fire the second time: value resets to 0 and continues to count up 1 every tick despite not being on fire + +Basically it's tick timer that starts after entity is first ignited and resets every time it changes from/to being on fire. + +## query.scoreboard + +Formatted like: `query.scoreboard('objective_name') > 0` + +Returns 1.0 or 0.0 if the queried value is within the specified range provided. Or based on score count, molang operator and number. + +Note that sometimes it might not work because of unknown reasons. One of which is that this cannot query scoreboard objective names with uppercase letters. In this case, for example, objective `testfoo` will work but **not** `testFoo`. + +## query.structural_integrity + +Formatted like: `structural_integrity = query.structural_integrity`. + +Used by boats and minecarts for destroying it. It will decrease when attacking the entity and will recover with time. +Probably unusable by anything other than boats and minecarts. + +## variable.attack_time + +### Explanation + +This variable is setup as IF it was a query. In other words, it can be used on any entity, both on the client and server, regardless of whether you setup/define the variable correctly. + +### For entities + +The variable tracks when the entity is swinging to attack. When not attacking, it will return 0.0, when attacking it will range from 0.0 to the total attack time, which may be around 0.3 or something similar. For players, this value ranges from 0.0 to 1.0. The variable returns a percentage, in the form of a decimal, for how far into the attack the entity is. For example, if an entity is halfway into its attack swing, then the variable will return 0.5. It increments linearly. + +### For the Player + +For the player, the variable will track whenever the arm bones are swinging, this includes: + +- placing blocks +- placing entities +- interacting (when swing is enabled) +- melee attack + +## query.is_roaring + +Evaluates to true when a `knockback_roar` attack is happening. + +## query.head_x_rotation + +Formatted like: `query.head_x_rotation(x)` + +Where `x` specifies the head of the entity. It is not really relevant for any entity but the wither. + +Returns head pitch. looking up returns `-89.9`, looking all the way down returns `89.9`. + +## query.head_y_rotation + +Formatted like: `query.head_y_rotation(x)` + +Where `x` specifies the head of the entity. It is not really relevant for any entity but the wither. + +Returns yaw of the head from `-179.9` to `179.9`. the values wrap around so like if you are at `-179.9` and you turn just a little bit, it instantly goes to `179.9`. + +## query.target_x_rotation and query.target_y_rotation + +Identical to the respective `query.head_*_rotation`, however has no optional argument for selecting head. + +## query.time_of_day + +Returns the time of day (midnight=0.0, sunrise=0.25, noon=0.5, sunset=0.75) of the dimension the entity is in. +Day time is calculated via this formula: + +`f(x) = (x*0.25/2400)mod 1` + +query.time_of_day - day time table + + + +| `query.time_of_day` | Day Time | +| ------------------- | -------- | +| 0.00 | 18000 | +| 0.01 | 18240 | +| 0.02 | 18480 | +| 0.03 | 18720 | +| 0.04 | 18960 | +| 0.05 | 19200 | +| 0.06 | 19440 | +| 0.07 | 19680 | +| 0.08 | 19920 | +| 0.09 | 20162 | +| 0.10 | 20400 | +| 0.11 | 20640 | +| 0.12 | 20880 | +| 0.13 | 21120 | +| 0.14 | 21360 | +| 0.15 | 21602 | +| 0.16 | 21840 | +| 0.17 | 22080 | +| 0.18 | 22322 | +| 0.19 | 22560 | +| 0.20 | 22800 | +| 0.21 | 23040 | +| 0.22 | 23280 | +| 0.23 | 23520 | +| 0.24 | 23760 | +| 0.25 | 0 | +| 0.26 | 240 | +| 0.27 | 480 | +| 0.28 | 720 | +| 0.29 | 960 | +| 0.30 | 1202 | +| 0.31 | 1440 | +| 0.32 | 1680 | +| 0.33 | 1922 | +| 0.34 | 2160 | +| 0.35 | 2400 | +| 0.36 | 2642 | +| 0.37 | 2880 | +| 0.38 | 3120 | +| 0.39 | 3360 | +| 0.40 | 3600 | +| 0.41 | 3840 | +| 0.42 | 4080 | +| 0.43 | 4320 | +| 0.44 | 4560 | +| 0.45 | 4800 | +| 0.46 | 5040 | +| 0.47 | 5280 | +| 0.48 | 5520 | +| 0.49 | 5760 | +| 0.50 | 6000 | +| 0.51 | 6240 | +| 0.52 | 6480 | +| 0.53 | 6720 | +| 0.54 | 6960 | +| 0.55 | 7200 | +| 0.56 | 7440 | +| 0.57 | 7680 | +| 0.58 | 7920 | +| 0.59 | 8160 | +| 0.60 | 8402 | +| 0.61 | 8640 | +| 0.62 | 8880 | +| 0.63 | 9120 | +| 0.64 | 9360 | +| 0.65 | 9600 | +| 0.66 | 9842 | +| 0.67 | 10080 | +| 0.68 | 10320 | +| 0.69 | 10560 | +| 0.70 | 10800 | +| 0.71 | 11040 | +| 0.72 | 11282 | +| 0.73 | 11520 | +| 0.74 | 11760 | +| 0.75 | 12000 | +| 0.76 | 12240 | +| 0.77 | 12480 | +| 0.78 | 12720 | +| 0.79 | 12962 | +| 0.80 | 13200 | +| 0.81 | 13440 | +| 0.82 | 13680 | +| 0.83 | 13920 | +| 0.84 | 14160 | +| 0.85 | 14402 | +| 0.86 | 14640 | +| 0.87 | 14880 | +| 0.88 | 15120 | +| 0.89 | 15360 | +| 0.90 | 15600 | +| 0.91 | 15842 | +| 0.92 | 16080 | +| 0.93 | 16320 | +| 0.94 | 16560 | +| 0.95 | 16800 | +| 0.96 | 17040 | +| 0.97 | 17282 | +| 0.98 | 17520 | +| 0.99 | 17760 | +| 1.00 | 18000 | + +Credit: [Analysis of query.time_of_day](https://gist.github.com/DoubleF3lix/a03afde0a979dfa41e8525ee92f12ca5) + + + +## query.eye_target_x_rotation and query.eye_target_y_rotation + +Not valid for player. not really sure what its good for. + +## variable.short_arm_offset_right + +Returns the offset factor for the player's rightarm bone compared to the default skin geometry. Slim-armed (3 pixel wide) skins will return `0.5` when equipped on the player. Normal (4 pixel wide) skins will return `0.0` when equipped on the player. Note: the player must go into 1st person perspective at least once for this variable to be initialized and usable elsewhere on the entity. + +## variable.short_arm_offset_left + +Identical behavior to `variable.short_arm_offset_right` except it references the player leftarm bone. + +## query.movement_direction + +Returns one of the 3 components from the normalized vector of the entity movement meaning the magnitude/modulus/length of the vector is between 0 and 1. + +**Note**: As of writing the documentation, the value returned from any of the axis will change depending on the speed of the entity (If the entity is on the ground the value will be less than the value of the entity if it were in the air even if it is moving in the same direction). + +To get the actual normalized velocity vector of the entity movement you will have to normalize the values. Here is the Molang setup: + +``` +variable.mag = math.sqrt( math.pow( query.movement_direction(0), 2 ) + math.pow( query.movement_direction(1), 2) + math.pow( query.movement_direction(2), 2)); +variable.xNorm = query.movement_direction(0) / variable.mag; +variable.yNorm = query.movement_direction(1) / variable.mag; +variable.zNorm = query.movement_direction(2) / variable.mag; +``` + +For more information on normalized vectors you can play around with this Desmos graph + +| Argument | Axis | +| -------- | ---- | +| 0 | X | +| 1 | Y | +| 2 | Z | + +## query.block_neighbor_has_any_tag and query.relative_block_has_any_tag + +Requires `Experimental Molang Features` to use. From the docs `Takes a relative position and one or more tag names, and returns either 0 or 1 based on if the block at that position has any of the tags provided`. This is useful for using connecting blocks or detecting entities. + +`query.block_neighbor_has_any_tag` - Takes block position +`query.relative_block_has_any_tag` - Takes entity position + +The syntax for it is `q.block_neighbor_has_any_tag(x,y,z,'tag_name')` and `q.relative_block_has_any_tag(x,y,z,'tag_name')`. + +Example: +- `q.relative_block_has_any_tag(0,-1,0,'grass')` would try to detect a block with the grass tag one block under the entity. +- `q.block_neighbor_has_any_tag(0,-1,0,'grass')` would try to detect a block with the grass tag one block under the block. + +To do multiple tags you would use `q.correct_query(0,-1,0,'grass', 'plant')` with `correct_query` being replaced by the right query. + +Note that this can also detect custom tags and [vanilla tags](/blocks/block-tags) diff --git a/docs/wiki/documentation/shared-constructs.md b/docs/wiki/documentation/shared-constructs.md new file mode 100644 index 00000000..d06437f0 --- /dev/null +++ b/docs/wiki/documentation/shared-constructs.md @@ -0,0 +1,40 @@ +--- +title: Shared Constructs +nav_order: 1 +tags: + - Stable + - Last updated for Version 1.18.10 +mentions: + - Ciosciaa + - ThomasOrs +--- + +A few JSON constructs are expressible in multiple locations in the add-ons system. + +## Range Objects +Range objects define a spread between two numbers. + +Range Object Example + +```json +{ + "min": 2, + "max": 4 +} +``` + +When provided, a random value will be selected inclusively between the minimum and maximum. Rolls are not retained; a new random value will be rolled each instance the range object would be used. The maximum must not be less than the minimum, but they may be equal to affix rolls to a specific value. + +## Fraction Objects +Fraction objects define a fraction using a numerator and denominator. + +Fraction Object Example + +```json +{ + "numerator": 3, + "denominator": 5 +} +``` + +The value used in place of the object will be the computed division, `numerator` ÷ `denominator`. Both the numerator and denominator must be at least `1`, and the denominator cannot be equal to the numerator. \ No newline at end of file diff --git a/docs/wiki/documentation/sound-definitions.md b/docs/wiki/documentation/sound-definitions.md new file mode 100644 index 00000000..968df28e --- /dev/null +++ b/docs/wiki/documentation/sound-definitions.md @@ -0,0 +1,2712 @@ +--- +title: Sound Definitions +mentions: + - MedicalJewel105 +--- + +Sounds from `sound_definitions.json` sorted by categories and subcategories based on their names. +This page was created with [Wiki Content Generator](https://github.com/Bedrock-OSS/bedrock-wiki-content-generator). If there are issues, contact us on [Bedrock OSS](https://discord.gg/XjV87YN) Discord server. +*Last updated for 1.20.10* + +## ambient + +#### ambient +--- +`ambient.basalt_deltas.additions` + +`ambient.basalt_deltas.loop` + +`ambient.basalt_deltas.mood` + +`ambient.cave` + +`ambient.crimson_forest.additions` + +`ambient.crimson_forest.loop` + +`ambient.crimson_forest.mood` + +`ambient.nether_wastes.additions` + +`ambient.nether_wastes.loop` + +`ambient.nether_wastes.mood` + +`ambient.soulsand_valley.additions` + +`ambient.soulsand_valley.loop` + +`ambient.soulsand_valley.mood` + +`ambient.warped_forest.additions` + +`ambient.warped_forest.loop` + +`ambient.warped_forest.mood` + +#### firework +--- +`firework.blast` + +`firework.large_blast` + +`firework.launch` + +`firework.shoot` + +`firework.twinkle` + +#### portal +--- +`portal.travel` + +`portal.trigger` + +## block + +#### ambient +--- +`ambient.candle` + +#### beacon +--- +`beacon.activate` + +`beacon.ambient` + +`beacon.deactivate` + +`beacon.power` + +#### block +--- +`block.bamboo.break` + +`block.bamboo.fall` + +`block.bamboo.hit` + +`block.bamboo.place` + +`block.bamboo.step` + +`block.bamboo_sapling.break` + +`block.bamboo_sapling.place` + +`block.barrel.close` + +`block.barrel.open` + +`block.beehive.drip` + +`block.beehive.enter` + +`block.beehive.exit` + +`block.beehive.shear` + +`block.beehive.work` + +`block.bell.hit` + +`block.blastfurnace.fire_crackle` + +`block.bowhit` + +`block.campfire.crackle` + +`block.cartography_table.use` + +`block.chorusflower.death` + +`block.chorusflower.grow` + +`block.click` + +`block.composter.empty` + +`block.composter.fill` + +`block.composter.fill_success` + +`block.composter.ready` + +`block.enchanting_table.use` + +`block.end_portal.spawn` + +`block.end_portal_frame.fill` + +`block.false_permissions` + +`block.furnace.lit` + +`block.grindstone.use` + +`block.itemframe.add_item` + +`block.itemframe.break` + +`block.itemframe.place` + +`block.itemframe.remove_item` + +`block.itemframe.rotate_item` + +`block.lantern.break` + +`block.lantern.fall` + +`block.lantern.hit` + +`block.lantern.place` + +`block.lantern.step` + +`block.loom.use` + +`block.mangrove_roots.break` + +`block.mangrove_roots.fall` + +`block.mangrove_roots.hit` + +`block.mangrove_roots.place` + +`block.mangrove_roots.step` + +`block.mud.break` + +`block.mud.fall` + +`block.mud.hit` + +`block.mud.place` + +`block.mud.step` + +`block.mud_bricks.break` + +`block.mud_bricks.fall` + +`block.mud_bricks.hit` + +`block.mud_bricks.place` + +`block.mud_bricks.step` + +`block.muddy_mangrove_roots.break` + +`block.muddy_mangrove_roots.fall` + +`block.muddy_mangrove_roots.hit` + +`block.muddy_mangrove_roots.place` + +`block.muddy_mangrove_roots.step` + +`block.packed_mud.break` + +`block.packed_mud.fall` + +`block.packed_mud.hit` + +`block.packed_mud.place` + +`block.packed_mud.step` + +`block.scaffolding.break` + +`block.scaffolding.climb` + +`block.scaffolding.fall` + +`block.scaffolding.hit` + +`block.scaffolding.place` + +`block.scaffolding.step` + +`block.sign.waxed_interact_fail` + +`block.smoker.smoke` + +`block.sniffer_egg.crack` + +`block.sniffer_egg.hatch` + +`block.stonecutter.use` + +`block.sweet_berry_bush.break` + +`block.sweet_berry_bush.hurt` + +`block.sweet_berry_bush.pick` + +`block.sweet_berry_bush.place` + +`block.turtle_egg.break` + +`block.turtle_egg.crack` + +`block.turtle_egg.drop` + +#### bloom +--- +`bloom.sculk_catalyst` + +#### break +--- +`break.amethyst_block` + +`break.amethyst_cluster` + +`break.azalea` + +`break.bamboo_wood` + +`break.bamboo_wood_hanging_sign` + +`break.big_dripleaf` + +`break.calcite` + +`break.cherry_leaves` + +`break.cherry_wood` + +`break.cherry_wood_hanging_sign` + +`break.chiseled_bookshelf` + +`break.decorated_pot` + +`break.dirt_with_roots` + +`break.dripstone_block` + +`break.frog_spawn` + +`break.froglight` + +`break.hanging_roots` + +`break.hanging_sign` + +`break.large_amethyst_bud` + +`break.medium_amethyst_bud` + +`break.nether_wood` + +`break.nether_wood_hanging_sign` + +`break.pink_petals` + +`break.pointed_dripstone` + +`break.sculk` + +`break.sculk_catalyst` + +`break.sculk_sensor` + +`break.sculk_shrieker` + +`break.sculk_vein` + +`break.small_amethyst_bud` + +`break.spore_blossom` + +`break.suspicious_gravel` + +`break.suspicious_sand` + +`break.tuff` + +#### bubble +--- +`bubble.down` + +`bubble.downinside` + +`bubble.pop` + +`bubble.up` + +`bubble.upinside` + +#### bucket +--- +`bucket.empty_fish` + +`bucket.empty_lava` + +`bucket.empty_powder_snow` + +`bucket.empty_water` + +`bucket.fill_fish` + +`bucket.fill_lava` + +`bucket.fill_water` + +#### cake +--- +`cake.add_candle` + +#### cauldron +--- +`cauldron.adddye` + +`cauldron.cleanarmor` + +`cauldron.cleanbanner` + +`cauldron.dyearmor` + +`cauldron.explode` + +`cauldron.fillpotion` + +`cauldron.fillwater` + +`cauldron.takepotion` + +`cauldron.takewater` + +#### cauldron_drip +--- +`cauldron_drip.lava.pointed_dripstone` + +`cauldron_drip.water.pointed_dripstone` + +#### chime +--- +`chime.amethyst_block` + +#### click_off +--- +`click_off.bamboo_wood_button` + +`click_off.bamboo_wood_pressure_plate` + +`click_off.cherry_wood_button` + +`click_off.cherry_wood_pressure_plate` + +`click_off.metal_pressure_plate` + +`click_off.nether_wood_button` + +`click_off.nether_wood_pressure_plate` + +`click_off.stone_pressure_plate` + +`click_off.wooden_pressure_plate` + +#### click_on +--- +`click_on.bamboo_wood_button` + +`click_on.bamboo_wood_pressure_plate` + +`click_on.cherry_wood_button` + +`click_on.cherry_wood_pressure_plate` + +`click_on.metal_pressure_plate` + +`click_on.nether_wood_button` + +`click_on.nether_wood_pressure_plate` + +`click_on.stone_pressure_plate` + +`click_on.wooden_pressure_plate` + +#### close +--- +`close.bamboo_wood_door` + +`close.bamboo_wood_fence_gate` + +`close.bamboo_wood_trapdoor` + +`close.cherry_wood_door` + +`close.cherry_wood_fence_gate` + +`close.cherry_wood_trapdoor` + +`close.fence_gate` + +`close.iron_door` + +`close.iron_trapdoor` + +`close.nether_wood_door` + +`close.nether_wood_fence_gate` + +`close.nether_wood_trapdoor` + +`close.wooden_door` + +`close.wooden_trapdoor` + +#### conduit +--- +`conduit.activate` + +`conduit.ambient` + +`conduit.attack` + +`conduit.deactivate` + +`conduit.short` + +#### dig +--- +`dig.ancient_debris` + +`dig.azalea_leaves` + +`dig.basalt` + +`dig.bone_block` + +`dig.candle` + +`dig.cave_vines` + +`dig.chain` + +`dig.cloth` + +`dig.copper` + +`dig.coral` + +`dig.deepslate` + +`dig.deepslate_bricks` + +`dig.fungus` + +`dig.grass` + +`dig.gravel` + +`dig.honey_block` + +`dig.lodestone` + +`dig.moss` + +`dig.nether_brick` + +`dig.nether_gold_ore` + +`dig.nether_sprouts` + +`dig.nether_wart` + +`dig.netherite` + +`dig.netherrack` + +`dig.nylium` + +`dig.powder_snow` + +`dig.roots` + +`dig.sand` + +`dig.shroomlight` + +`dig.snow` + +`dig.soul_sand` + +`dig.soul_soil` + +`dig.stem` + +`dig.stone` + +`dig.vines` + +`dig.wood` + +#### drip +--- +`drip.lava.pointed_dripstone` + +`drip.water.pointed_dripstone` + +#### extinguish +--- +`extinguish.candle` + +#### fire +--- +`fire.fire` + +`fire.ignite` + +#### hatch +--- +`hatch.frog_spawn` + +#### hit +--- +`hit.amethyst_block` + +`hit.amethyst_cluster` + +`hit.ancient_debris` + +`hit.anvil` + +`hit.azalea` + +`hit.azalea_leaves` + +`hit.bamboo_wood` + +`hit.basalt` + +`hit.big_dripleaf` + +`hit.bone_block` + +`hit.calcite` + +`hit.candle` + +`hit.cave_vines` + +`hit.chain` + +`hit.cherry_leaves` + +`hit.cherry_wood` + +`hit.chiseled_bookshelf` + +`hit.cloth` + +`hit.copper` + +`hit.coral` + +`hit.deepslate` + +`hit.deepslate_bricks` + +`hit.dirt_with_roots` + +`hit.dripstone_block` + +`hit.grass` + +`hit.gravel` + +`hit.hanging_roots` + +`hit.honey_block` + +`hit.ladder` + +`hit.moss` + +`hit.nether_brick` + +`hit.nether_gold_ore` + +`hit.nether_sprouts` + +`hit.nether_wart` + +`hit.nether_wood` + +`hit.netherite` + +`hit.netherrack` + +`hit.nylium` + +`hit.pink_petals` + +`hit.pointed_dripstone` + +`hit.powder_snow` + +`hit.roots` + +`hit.sand` + +`hit.sculk` + +`hit.sculk_catalyst` + +`hit.sculk_sensor` + +`hit.sculk_shrieker` + +`hit.shroomlight` + +`hit.slime` + +`hit.snow` + +`hit.soul_sand` + +`hit.soul_soil` + +`hit.spore_blossom` + +`hit.stem` + +`hit.stone` + +`hit.suspicious_gravel` + +`hit.suspicious_sand` + +`hit.tuff` + +`hit.vines` + +`hit.wood` + +#### insert +--- +`insert.chiseled_bookshelf` + +#### insert_enchanted +--- +`insert_enchanted.chiseled_bookshelf` + +#### item +--- +`item.bone_meal.use` + +`item.book.put` + +#### liquid +--- +`liquid.lava` + +`liquid.lavapop` + +`liquid.water` + +#### lodestone_compass +--- +`lodestone_compass.link_compass_to_lodestone` + +#### open +--- +`open.bamboo_wood_door` + +`open.bamboo_wood_fence_gate` + +`open.bamboo_wood_trapdoor` + +`open.cherry_wood_door` + +`open.cherry_wood_fence_gate` + +`open.cherry_wood_trapdoor` + +`open.fence_gate` + +`open.iron_door` + +`open.iron_trapdoor` + +`open.nether_wood_door` + +`open.nether_wood_fence_gate` + +`open.nether_wood_trapdoor` + +`open.wooden_door` + +`open.wooden_trapdoor` + +#### pick_berries +--- +`pick_berries.cave_vines` + +#### pickup +--- +`pickup.chiseled_bookshelf` + +#### pickup_enchanted +--- +`pickup_enchanted.chiseled_bookshelf` + +#### place +--- +`place.amethyst_block` + +`place.amethyst_cluster` + +`place.azalea` + +`place.azalea_leaves` + +`place.bamboo_wood` + +`place.big_dripleaf` + +`place.calcite` + +`place.cherry_leaves` + +`place.cherry_wood` + +`place.chiseled_bookshelf` + +`place.copper` + +`place.deepslate` + +`place.deepslate_bricks` + +`place.dirt_with_roots` + +`place.dripstone_block` + +`place.hanging_roots` + +`place.large_amethyst_bud` + +`place.medium_amethyst_bud` + +`place.moss` + +`place.nether_wood` + +`place.pink_petals` + +`place.pointed_dripstone` + +`place.powder_snow` + +`place.sculk` + +`place.sculk_catalyst` + +`place.sculk_sensor` + +`place.sculk_shrieker` + +`place.small_amethyst_bud` + +`place.spore_blossom` + +`place.suspicious_gravel` + +`place.suspicious_sand` + +`place.tuff` + +#### portal +--- +`portal.portal` + +#### power +--- +`power.off.sculk_sensor` + +`power.on.sculk_sensor` + +#### random +--- +`random.anvil_break` + +`random.anvil_land` + +`random.anvil_use` + +`random.chestclosed` + +`random.chestopen` + +`random.door_close` + +`random.door_open` + +`random.enderchestclosed` + +`random.enderchestopen` + +`random.explode` + +`random.fizz` + +`random.fuse` + +`random.glass` + +`random.lever_click` + +`random.potion.brewed` + +`random.shulkerboxclosed` + +`random.shulkerboxopen` + +`random.stone_click` + +`random.wood_click` + +#### resonate +--- +`resonate.amethyst_block` + +#### respawn_anchor +--- +`respawn_anchor.ambient` + +`respawn_anchor.charge` + +`respawn_anchor.deplete` + +`respawn_anchor.set_spawn` + +#### shatter +--- +`shatter.decorated_pot` + +#### shriek +--- +`shriek.sculk_shrieker` + +#### smithing_table +--- +`smithing_table.use` + +#### step +--- +`step.candle` + +`step.cherry_leaves` + +`step.decorated_pot` + +`step.frog_spawn` + +`step.froglight` + +`step.sculk_shrieker` + +`step.sculk_vein` + +#### tile +--- +`tile.piston.in` + +`tile.piston.out` + +#### tilt_down +--- +`tilt_down.big_dripleaf` + +#### tilt_up +--- +`tilt_up.big_dripleaf` + +#### ui +--- +`ui.cartography_table.take_result` + +`ui.loom.select_pattern` + +`ui.loom.take_result` + +`ui.stonecutter.take_result` + +#### use +--- +`use.ancient_debris` + +`use.basalt` + +`use.bone_block` + +`use.candle` + +`use.cave_vines` + +`use.chain` + +`use.cloth` + +`use.copper` + +`use.coral` + +`use.deepslate` + +`use.deepslate_bricks` + +`use.dirt_with_roots` + +`use.dripstone_block` + +`use.grass` + +`use.gravel` + +`use.hanging_roots` + +`use.honey_block` + +`use.ladder` + +`use.moss` + +`use.nether_brick` + +`use.nether_gold_ore` + +`use.nether_sprouts` + +`use.nether_wart` + +`use.netherite` + +`use.netherrack` + +`use.nylium` + +`use.pointed_dripstone` + +`use.roots` + +`use.sand` + +`use.sculk_sensor` + +`use.shroomlight` + +`use.slime` + +`use.snow` + +`use.soul_sand` + +`use.soul_soil` + +`use.spore_blossom` + +`use.stem` + +`use.stone` + +`use.vines` + +`use.wood` + +## bottle + +#### bottle +--- +`bottle.dragonbreath` + +## hostile + +#### entity +--- +`entity.zombie.converted_to_drowned` + +#### mob +--- +`mob.blaze.breathe` + +`mob.blaze.death` + +`mob.blaze.hit` + +`mob.blaze.shoot` + +`mob.creeper.death` + +`mob.creeper.say` + +`mob.drowned.death` + +`mob.drowned.death_water` + +`mob.drowned.hurt` + +`mob.drowned.hurt_water` + +`mob.drowned.say` + +`mob.drowned.say_water` + +`mob.drowned.shoot` + +`mob.drowned.step` + +`mob.drowned.swim` + +`mob.elderguardian.curse` + +`mob.elderguardian.death` + +`mob.elderguardian.hit` + +`mob.elderguardian.idle` + +`mob.enderdragon.death` + +`mob.enderdragon.flap` + +`mob.enderdragon.growl` + +`mob.enderdragon.hit` + +`mob.endermen.death` + +`mob.endermen.hit` + +`mob.endermen.idle` + +`mob.endermen.portal` + +`mob.endermen.scream` + +`mob.endermen.stare` + +`mob.endermite.hit` + +`mob.endermite.kill` + +`mob.endermite.say` + +`mob.endermite.step` + +`mob.evocation_fangs.attack` + +`mob.evocation_illager.ambient` + +`mob.evocation_illager.cast_spell` + +`mob.evocation_illager.celebrate` + +`mob.evocation_illager.death` + +`mob.evocation_illager.hurt` + +`mob.evocation_illager.prepare_attack` + +`mob.evocation_illager.prepare_summon` + +`mob.evocation_illager.prepare_wololo` + +`mob.fox.aggro` + +`mob.fox.bite` + +`mob.frog.lay_spawn` + +`mob.frog.tongue` + +`mob.ghast.affectionate_scream` + +`mob.ghast.charge` + +`mob.ghast.death` + +`mob.ghast.fireball` + +`mob.ghast.moan` + +`mob.ghast.scream` + +`mob.goat.horn_break` + +`mob.goat.prepare_ram` + +`mob.goat.prepare_ram.screamer` + +`mob.goat.ram_impact` + +`mob.goat.ram_impact.screamer` + +`mob.guardian.ambient` + +`mob.guardian.attack_loop` + +`mob.guardian.death` + +`mob.guardian.flop` + +`mob.guardian.hit` + +`mob.guardian.land_death` + +`mob.guardian.land_hit` + +`mob.guardian.land_idle` + +`mob.hoglin.ambient` + +`mob.hoglin.angry` + +`mob.hoglin.attack` + +`mob.hoglin.death` + +`mob.hoglin.howl` + +`mob.hoglin.hurt` + +`mob.hoglin.retreat` + +`mob.hoglin.step` + +`mob.husk.ambient` + +`mob.husk.death` + +`mob.husk.hurt` + +`mob.husk.step` + +`mob.irongolem.death` + +`mob.irongolem.hit` + +`mob.irongolem.throw` + +`mob.irongolem.walk` + +`mob.magmacube.big` + +`mob.magmacube.jump` + +`mob.magmacube.small` + +`mob.panda.bite` + +`mob.panda.death` + +`mob.panda.hurt` + +`mob.phantom.bite` + +`mob.phantom.death` + +`mob.phantom.flap` + +`mob.phantom.hurt` + +`mob.phantom.idle` + +`mob.phantom.swoop` + +`mob.piglin.admiring_item` + +`mob.piglin.ambient` + +`mob.piglin.angry` + +`mob.piglin.celebrate` + +`mob.piglin.converted_to_zombified` + +`mob.piglin.death` + +`mob.piglin.hurt` + +`mob.piglin.jealous` + +`mob.piglin.retreat` + +`mob.piglin.step` + +`mob.piglin_brute.ambient` + +`mob.piglin_brute.angry` + +`mob.piglin_brute.converted_to_zombified` + +`mob.piglin_brute.death` + +`mob.piglin_brute.hurt` + +`mob.piglin_brute.step` + +`mob.pillager.celebrate` + +`mob.pillager.death` + +`mob.pillager.hurt` + +`mob.pillager.idle` + +`mob.polarbear.death` + +`mob.polarbear.hurt` + +`mob.polarbear.warning` + +`mob.ravager.ambient` + +`mob.ravager.bite` + +`mob.ravager.celebrate` + +`mob.ravager.death` + +`mob.ravager.hurt` + +`mob.ravager.roar` + +`mob.ravager.step` + +`mob.ravager.stun` + +`mob.shulker.ambient` + +`mob.shulker.bullet.hit` + +`mob.shulker.close` + +`mob.shulker.close.hurt` + +`mob.shulker.death` + +`mob.shulker.hurt` + +`mob.shulker.open` + +`mob.shulker.shoot` + +`mob.shulker.teleport` + +`mob.silverfish.hit` + +`mob.silverfish.kill` + +`mob.silverfish.say` + +`mob.silverfish.step` + +`mob.skeleton.death` + +`mob.skeleton.hurt` + +`mob.skeleton.say` + +`mob.skeleton.step` + +`mob.slime.attack` + +`mob.slime.big` + +`mob.slime.death` + +`mob.slime.hurt` + +`mob.slime.jump` + +`mob.slime.small` + +`mob.slime.squish` + +`mob.spider.death` + +`mob.spider.say` + +`mob.spider.step` + +`mob.stray.ambient` + +`mob.stray.death` + +`mob.stray.hurt` + +`mob.stray.step` + +`mob.vex.ambient` + +`mob.vex.charge` + +`mob.vex.death` + +`mob.vex.hurt` + +`mob.vindicator.celebrate` + +`mob.vindicator.death` + +`mob.vindicator.hurt` + +`mob.vindicator.idle` + +`mob.warden.agitated` + +`mob.warden.angry` + +`mob.warden.attack` + +`mob.warden.clicking` + +`mob.warden.death` + +`mob.warden.dig` + +`mob.warden.emerge` + +`mob.warden.heartbeat` + +`mob.warden.hurt` + +`mob.warden.idle` + +`mob.warden.listening` + +`mob.warden.listening_angry` + +`mob.warden.nearby_close` + +`mob.warden.nearby_closer` + +`mob.warden.nearby_closest` + +`mob.warden.roar` + +`mob.warden.sniff` + +`mob.warden.sonic_boom` + +`mob.warden.sonic_charge` + +`mob.warden.step` + +`mob.witch.ambient` + +`mob.witch.celebrate` + +`mob.witch.death` + +`mob.witch.drink` + +`mob.witch.hurt` + +`mob.witch.throw` + +`mob.wither.ambient` + +`mob.wither.break_block` + +`mob.wither.death` + +`mob.wither.hurt` + +`mob.wither.shoot` + +`mob.wither.spawn` + +`mob.zoglin.angry` + +`mob.zoglin.attack` + +`mob.zoglin.death` + +`mob.zoglin.hurt` + +`mob.zoglin.idle` + +`mob.zoglin.step` + +`mob.zombie.death` + +`mob.zombie.hurt` + +`mob.zombie.remedy` + +`mob.zombie.say` + +`mob.zombie.step` + +`mob.zombie.unfect` + +`mob.zombie.wood` + +`mob.zombie.woodbreak` + +`mob.zombie_villager.death` + +`mob.zombie_villager.hurt` + +`mob.zombie_villager.say` + +`mob.zombiepig.zpig` + +`mob.zombiepig.zpigangry` + +`mob.zombiepig.zpigdeath` + +`mob.zombiepig.zpighurt` + +## music + +#### music +--- +`music.game` + +`music.game.basalt_deltas` + +`music.game.creative` + +`music.game.credits` + +`music.game.crimson_forest` + +`music.game.deep_dark` + +`music.game.dripstone_caves` + +`music.game.end` + +`music.game.endboss` + +`music.game.frozen_peaks` + +`music.game.grove` + +`music.game.jagged_peaks` + +`music.game.lush_caves` + +`music.game.meadow` + +`music.game.nether` + +`music.game.nether_wastes` + +`music.game.snowy_slopes` + +`music.game.soul_sand_valley` + +`music.game.soulsand_valley` + +`music.game.stony_peaks` + +`music.game.swamp_music` + +`music.game.warped_forest` + +`music.game.water` + +`music.game_and_wild_equal_chance` + +`music.game_and_wild_favor_game` + +`music.menu` + +`music.overworld.bamboo_jungle` + +`music.overworld.cherry_grove` + +`music.overworld.desert` + +`music.overworld.flower_forest` + +`music.overworld.jungle` + +`music.overworld.jungle_edge` + +`music.overworld.mesa` + +## neutral + +#### charge +--- +`charge.sculk` + +#### component +--- +`component.jump_to_block` + +#### copper +--- +`copper.wax.off` + +`copper.wax.on` + +#### fall +--- +`fall.sculk_shrieker` + +#### leashknot +--- +`leashknot.break` + +`leashknot.place` + +#### minecart +--- +`minecart.base` + +`minecart.inside` + +#### mob +--- +`mob.agent.spawn` + +`mob.allay.death` + +`mob.allay.hurt` + +`mob.allay.idle` + +`mob.allay.idle_holding` + +`mob.allay.item_given` + +`mob.allay.item_taken` + +`mob.allay.item_thrown` + +`mob.armor_stand.break` + +`mob.armor_stand.hit` + +`mob.armor_stand.land` + +`mob.armor_stand.place` + +`mob.axolotl.attack` + +`mob.axolotl.death` + +`mob.axolotl.hurt` + +`mob.axolotl.idle` + +`mob.axolotl.idle_water` + +`mob.axolotl.splash` + +`mob.axolotl.swim` + +`mob.bat.death` + +`mob.bat.hurt` + +`mob.bat.idle` + +`mob.bat.takeoff` + +`mob.bee.aggressive` + +`mob.bee.death` + +`mob.bee.hurt` + +`mob.bee.loop` + +`mob.bee.pollinate` + +`mob.bee.sting` + +`mob.camel.ambient` + +`mob.camel.dash` + +`mob.camel.dash_ready` + +`mob.camel.death` + +`mob.camel.eat` + +`mob.camel.hurt` + +`mob.camel.sit` + +`mob.camel.stand` + +`mob.camel.step` + +`mob.camel.step_sand` + +`mob.cat.beg` + +`mob.cat.eat` + +`mob.cat.hiss` + +`mob.cat.hit` + +`mob.cat.meow` + +`mob.cat.purr` + +`mob.cat.purreow` + +`mob.cat.straymeow` + +`mob.chicken.hurt` + +`mob.chicken.plop` + +`mob.chicken.say` + +`mob.chicken.step` + +`mob.cow.hurt` + +`mob.cow.milk` + +`mob.cow.say` + +`mob.cow.step` + +`mob.dolphin.attack` + +`mob.dolphin.blowhole` + +`mob.dolphin.death` + +`mob.dolphin.eat` + +`mob.dolphin.hurt` + +`mob.dolphin.idle` + +`mob.dolphin.idle_water` + +`mob.dolphin.jump` + +`mob.dolphin.play` + +`mob.dolphin.splash` + +`mob.dolphin.swim` + +`mob.fish.flop` + +`mob.fish.hurt` + +`mob.fish.step` + +`mob.fox.ambient` + +`mob.fox.death` + +`mob.fox.eat` + +`mob.fox.hurt` + +`mob.fox.screech` + +`mob.fox.sleep` + +`mob.fox.sniff` + +`mob.fox.spit` + +`mob.frog.ambient` + +`mob.frog.death` + +`mob.frog.eat` + +`mob.frog.hurt` + +`mob.frog.jump_to_block` + +`mob.frog.step` + +`mob.glow_squid.ambient` + +`mob.glow_squid.death` + +`mob.glow_squid.hurt` + +`mob.glow_squid.ink_squirt` + +`mob.goat.ambient` + +`mob.goat.ambient.screamer` + +`mob.goat.death` + +`mob.goat.death.screamer` + +`mob.goat.eat` + +`mob.goat.hurt` + +`mob.goat.hurt.screamer` + +`mob.goat.milk.screamer` + +`mob.goat.step` + +`mob.horse.angry` + +`mob.horse.armor` + +`mob.horse.breathe` + +`mob.horse.death` + +`mob.horse.donkey.angry` + +`mob.horse.donkey.death` + +`mob.horse.donkey.hit` + +`mob.horse.donkey.idle` + +`mob.horse.eat` + +`mob.horse.gallop` + +`mob.horse.hit` + +`mob.horse.idle` + +`mob.horse.jump` + +`mob.horse.land` + +`mob.horse.leather` + +`mob.horse.skeleton.death` + +`mob.horse.skeleton.hit` + +`mob.horse.skeleton.idle` + +`mob.horse.soft` + +`mob.horse.wood` + +`mob.horse.zombie.death` + +`mob.horse.zombie.hit` + +`mob.horse.zombie.idle` + +`mob.irongolem.crack` + +`mob.irongolem.repair` + +`mob.llama.angry` + +`mob.llama.death` + +`mob.llama.eat` + +`mob.llama.hurt` + +`mob.llama.idle` + +`mob.llama.spit` + +`mob.llama.step` + +`mob.llama.swag` + +`mob.mooshroom.convert` + +`mob.mooshroom.eat` + +`mob.mooshroom.suspicious_milk` + +`mob.ocelot.death` + +`mob.ocelot.idle` + +`mob.panda.cant_breed` + +`mob.panda.eat` + +`mob.panda.idle` + +`mob.panda.idle.aggressive` + +`mob.panda.idle.worried` + +`mob.panda.presneeze` + +`mob.panda.sneeze` + +`mob.panda.step` + +`mob.panda_baby.idle` + +`mob.parrot.death` + +`mob.parrot.eat` + +`mob.parrot.fly` + +`mob.parrot.hurt` + +`mob.parrot.idle` + +`mob.parrot.step` + +`mob.pig.boost` + +`mob.pig.death` + +`mob.pig.say` + +`mob.pig.step` + +`mob.polarbear.idle` + +`mob.polarbear.step` + +`mob.polarbear_baby.idle` + +`mob.rabbit.death` + +`mob.rabbit.hop` + +`mob.rabbit.hurt` + +`mob.rabbit.idle` + +`mob.sheep.say` + +`mob.sheep.step` + +`mob.skeleton.convert_to_stray` + +`mob.sniffer.death` + +`mob.sniffer.digging` + +`mob.sniffer.drop_seed` + +`mob.sniffer.eat` + +`mob.sniffer.happy` + +`mob.sniffer.hurt` + +`mob.sniffer.idle` + +`mob.sniffer.long_sniff` + +`mob.sniffer.plop` + +`mob.sniffer.searching` + +`mob.sniffer.sniffsniff` + +`mob.sniffer.stand_up` + +`mob.sniffer.step` + +`mob.snowgolem.death` + +`mob.snowgolem.hurt` + +`mob.snowgolem.shoot` + +`mob.squid.ambient` + +`mob.squid.death` + +`mob.squid.hurt` + +`mob.squid.ink_squirt` + +`mob.strider.death` + +`mob.strider.eat` + +`mob.strider.hurt` + +`mob.strider.idle` + +`mob.strider.panic` + +`mob.strider.step` + +`mob.strider.step_lava` + +`mob.strider.tempt` + +`mob.tadpole.convert_to_frog` + +`mob.tadpole.death` + +`mob.tadpole.hurt` + +`mob.turtle.ambient` + +`mob.turtle.death` + +`mob.turtle.hurt` + +`mob.turtle.step` + +`mob.turtle.swim` + +`mob.turtle_baby.born` + +`mob.turtle_baby.death` + +`mob.turtle_baby.hurt` + +`mob.turtle_baby.step` + +`mob.villager.death` + +`mob.villager.haggle` + +`mob.villager.hit` + +`mob.villager.idle` + +`mob.villager.no` + +`mob.villager.yes` + +`mob.wanderingtrader.death` + +`mob.wanderingtrader.disappeared` + +`mob.wanderingtrader.drink_milk` + +`mob.wanderingtrader.drink_potion` + +`mob.wanderingtrader.haggle` + +`mob.wanderingtrader.hurt` + +`mob.wanderingtrader.idle` + +`mob.wanderingtrader.no` + +`mob.wanderingtrader.reappeared` + +`mob.wanderingtrader.yes` + +`mob.wolf.bark` + +`mob.wolf.death` + +`mob.wolf.growl` + +`mob.wolf.hurt` + +`mob.wolf.panting` + +`mob.wolf.shake` + +`mob.wolf.step` + +`mob.wolf.whine` + +#### raid +--- +`raid.horn` + +`scrape` + +#### spread +--- +`spread.sculk` + +#### step +--- +`step.sculk` + +`step.sculk_catalyst` + +## player + +#### armor +--- +`armor.equip_chain` + +`armor.equip_diamond` + +`armor.equip_generic` + +`armor.equip_gold` + +`armor.equip_iron` + +`armor.equip_leather` + +`armor.equip_netherite` + +#### brush +--- +`brush.generic` + +`brush.suspicious_gravel` + +`brush.suspicious_sand` + +#### brush_completed +--- +`brush_completed.suspicious_gravel` + +`brush_completed.suspicious_sand` + +#### bucket +--- +`bucket.fill_powder_snow` + +#### camera +--- +`camera.take_picture` + +#### crossbow +--- +`crossbow.loading.end` + +`crossbow.loading.middle` + +`crossbow.loading.start` + +`crossbow.quick_charge.end` + +`crossbow.quick_charge.middle` + +`crossbow.quick_charge.start` + +`crossbow.shoot` + +#### damage +--- +`damage.fallbig` + +`damage.fallsmall` + +#### elytra +--- +`elytra.loop` + +#### fall +--- +`fall.amethyst_block` + +`fall.amethyst_cluster` + +`fall.ancient_debris` + +`fall.azalea` + +`fall.azalea_leaves` + +`fall.bamboo_wood` + +`fall.basalt` + +`fall.big_dripleaf` + +`fall.bone_block` + +`fall.calcite` + +`fall.cave_vines` + +`fall.chain` + +`fall.cherry_leaves` + +`fall.cherry_wood` + +`fall.cloth` + +`fall.copper` + +`fall.coral` + +`fall.deepslate` + +`fall.deepslate_bricks` + +`fall.dirt_with_roots` + +`fall.dripstone_block` + +`fall.egg` + +`fall.grass` + +`fall.gravel` + +`fall.hanging_roots` + +`fall.honey_block` + +`fall.ladder` + +`fall.moss` + +`fall.nether_brick` + +`fall.nether_gold_ore` + +`fall.nether_sprouts` + +`fall.nether_wart` + +`fall.nether_wood` + +`fall.netherite` + +`fall.netherrack` + +`fall.nylium` + +`fall.pink_petals` + +`fall.pointed_dripstone` + +`fall.powder_snow` + +`fall.roots` + +`fall.sand` + +`fall.sculk_sensor` + +`fall.shroomlight` + +`fall.slime` + +`fall.snow` + +`fall.soul_sand` + +`fall.soul_soil` + +`fall.spore_blossom` + +`fall.stem` + +`fall.stone` + +`fall.tuff` + +`fall.vines` + +`fall.wood` + +#### game +--- +`game.player.attack.nodamage` + +`game.player.attack.strong` + +`game.player.die` + +`game.player.hurt` + +#### item +--- +`item.shield.block` + +`item.spyglass.stop_using` + +`item.spyglass.use` + +`item.trident.hit` + +`item.trident.hit_ground` + +`item.trident.return` + +`item.trident.riptide_1` + +`item.trident.riptide_2` + +`item.trident.riptide_3` + +`item.trident.throw` + +`item.trident.thunder` + +#### jump +--- +`jump.ancient_debris` + +`jump.azalea` + +`jump.basalt` + +`jump.big_dripleaf` + +`jump.bone_block` + +`jump.cave_vines` + +`jump.chain` + +`jump.cloth` + +`jump.coral` + +`jump.deepslate` + +`jump.deepslate_bricks` + +`jump.dirt_with_roots` + +`jump.dripstone_block` + +`jump.grass` + +`jump.gravel` + +`jump.hanging_roots` + +`jump.honey_block` + +`jump.moss` + +`jump.nether_brick` + +`jump.nether_gold_ore` + +`jump.nether_sprouts` + +`jump.nether_wart` + +`jump.netherite` + +`jump.netherrack` + +`jump.nylium` + +`jump.pointed_dripstone` + +`jump.roots` + +`jump.sand` + +`jump.sculk_sensor` + +`jump.shroomlight` + +`jump.slime` + +`jump.snow` + +`jump.soul_sand` + +`jump.soul_soil` + +`jump.spore_blossom` + +`jump.stem` + +`jump.stone` + +`jump.vines` + +`jump.wood` + +#### land +--- +`land.ancient_debris` + +`land.azalea` + +`land.basalt` + +`land.big_dripleaf` + +`land.bone_block` + +`land.cave_vines` + +`land.chain` + +`land.cloth` + +`land.coral` + +`land.deepslate` + +`land.deepslate_bricks` + +`land.dirt_with_roots` + +`land.dripstone_block` + +`land.grass` + +`land.gravel` + +`land.hanging_roots` + +`land.honey_block` + +`land.moss` + +`land.nether_brick` + +`land.nether_gold_ore` + +`land.nether_sprouts` + +`land.nether_wart` + +`land.netherite` + +`land.netherrack` + +`land.nylium` + +`land.pointed_dripstone` + +`land.roots` + +`land.sand` + +`land.sculk_sensor` + +`land.shroomlight` + +`land.slime` + +`land.snow` + +`land.soul_sand` + +`land.soul_soil` + +`land.spore_blossom` + +`land.stem` + +`land.stone` + +`land.vines` + +`land.wood` + +#### mob +--- +`mob.player.hurt_drown` + +`mob.player.hurt_freeze` + +`mob.player.hurt_on_fire` + +`mob.sheep.shear` + +#### particle +--- +`particle.soul_escape` + +#### random +--- +`random.bow` + +`random.bowhit` + +`random.break` + +`random.burp` + +`random.drink` + +`random.drink_honey` + +`random.eat` + +`random.hurt` + +`random.levelup` + +`random.orb` + +`random.pop` + +`random.pop2` + +`random.splash` + +`random.swim` + +`random.totem` + +#### step +--- +`step.amethyst_block` + +`step.amethyst_cluster` + +`step.ancient_debris` + +`step.azalea` + +`step.azalea_leaves` + +`step.bamboo_wood` + +`step.bamboo_wood_hanging_sign` + +`step.basalt` + +`step.big_dripleaf` + +`step.bone_block` + +`step.calcite` + +`step.cave_vines` + +`step.chain` + +`step.cherry_wood` + +`step.cherry_wood_hanging_sign` + +`step.chiseled_bookshelf` + +`step.cloth` + +`step.copper` + +`step.coral` + +`step.deepslate` + +`step.deepslate_bricks` + +`step.dirt_with_roots` + +`step.dripstone_block` + +`step.grass` + +`step.gravel` + +`step.hanging_roots` + +`step.hanging_sign` + +`step.honey_block` + +`step.ladder` + +`step.moss` + +`step.nether_brick` + +`step.nether_gold_ore` + +`step.nether_sprouts` + +`step.nether_wart` + +`step.nether_wood` + +`step.nether_wood_hanging_sign` + +`step.netherite` + +`step.netherrack` + +`step.nylium` + +`step.pink_petals` + +`step.pointed_dripstone` + +`step.powder_snow` + +`step.roots` + +`step.sand` + +`step.sculk_sensor` + +`step.shroomlight` + +`step.slime` + +`step.snow` + +`step.soul_sand` + +`step.soul_soil` + +`step.spore_blossom` + +`step.stem` + +`step.stone` + +`step.suspicious_gravel` + +`step.suspicious_sand` + +`step.tuff` + +`step.vines` + +`step.wood` + +#### vr +--- +`vr.stutterturn` + +## record + +#### horn +--- +`horn.call.0` + +`horn.call.1` + +`horn.call.2` + +`horn.call.3` + +`horn.call.4` + +`horn.call.5` + +`horn.call.6` + +`horn.call.7` + +#### note +--- +`note.banjo` + +`note.bass` + +`note.bassattack` + +`note.bd` + +`note.bell` + +`note.bit` + +`note.chime` + +`note.cow_bell` + +`note.creeper` + +`note.didgeridoo` + +`note.enderdragon` + +`note.flute` + +`note.guitar` + +`note.harp` + +`note.hat` + +`note.iron_xylophone` + +`note.piglin` + +`note.pling` + +`note.skeleton` + +`note.snare` + +`note.witherskeleton` + +`note.xylophone` + +`note.zombie` + +#### record +--- +`record.11` + +`record.13` + +`record.blocks` + +`record.cat` + +`record.chirp` + +`record.far` + +`record.mall` + +`record.mellohi` + +`record.pigstep` + +`record.stal` + +`record.strad` + +`record.wait` + +`record.ward` + +## ui + +#### item +--- +`item.book.page_turn` + +#### random +--- +`random.click` + +`random.screenshot` + +`random.toast` + +## weather + +#### ambient +--- +`ambient.weather.lightning.impact` + +`ambient.weather.rain` + +`ambient.weather.thunder` + +## No category + +#### record +--- +`record.5` + +`record.otherside` + +`record.relic` + +#### sign +--- +`sign.dye.use` + +`sign.ink_sac.use` + diff --git a/docs/wiki/guide/addons.md b/docs/wiki/guide/addons.md new file mode 100644 index 00000000..794220aa --- /dev/null +++ b/docs/wiki/guide/addons.md @@ -0,0 +1,72 @@ +--- +title: Addons Explained +category: Guide +description: The basics of Addons +nav_order: 2 +prefix: '2. ' +mentions: + - SirLich + - Dreamedc2015 + - sermah + - cda94581 + - RedSmarty + - TheItsNameless + - MedicalJewel105 + - ChibiMango + - profeplaysminecraft + - retr0cube + - SmokeyStack +--- + +## What are addons? + +Addons allow us to modify the contents of our Minecraft Experience by _modifying_ or _removing_ existing content and _adding_ our own. Addons are very powerful and allow us to create custom entities, items, and blocks, as well as things like custom loot tables and crafting recipes. Your imagination is the limit! + +Addons are primarily written in [json](/guide/understanding-json), which is a structured data-format. An addon is essentially a collection of json files, images, and sounds, which modify or add to the game in some way. + +## What's the difference between a Behavior Pack & a Resource Pack? + +Addons are split into two pack types: Resource Packs, and Behavior Packs. Both can function independently, but they are most commonly used together. When you have both a Resource Pack and Behavior Pack, this is referred to as an _addon_. + +### Resource Pack + +The Resource Pack, also known as the _client_, or RP, is responsible for the _visuals_ and _sounds_ in your addon. This includes things like: + +- Textures +- Sounds +- Geometry +- Animations +- Particles + +### Behavior Pack + +The Behavior Pack, also known as the _server_, or BP, is responsible for the _logic_ of your addon. This can include things like: + +- How your entity acts +- Crafting recipes +- Loot tables +- Custom functions + +### Communication between packs + +In most cases, you will have both a RP and a BP together. These packs can communicate with or will require each other for them to function properly, in the sense that assets defined in one can be accessed in the other. For example, when creating a custom entity, you need two files: + +- An RP entity definition, which describes how your entity will _look_ +- A BP entity definition, which describes how your entity will _act_ + +## What you have learned + +:::tip + +- Addons modify Minecraft content or add their own +- Addons are written in json +- An addon is split into the **Resource Pack** and the **Behavior Pack**: - Resource Packs contain Textures, Sounds, ... and control how the game looks - Behavior Packs contain entity-files, crafting recipes, ... and control the logic of your game +::: + +## What to do now? + +Check out software and preparation page! + diff --git a/docs/wiki/guide/advancedmanifest.md b/docs/wiki/guide/advancedmanifest.md new file mode 100644 index 00000000..02900c1a --- /dev/null +++ b/docs/wiki/guide/advancedmanifest.md @@ -0,0 +1,47 @@ +--- +title: Advanced Manifest +category: Extra +description: How to work with manifests - a more detailed guide [UNDER CONSTRUCTION] +nav_order: 4 +prefix: 'd.' +mentions: + - MRBBATES1 + - Luthorius + - SirLich + - smell-of-curry + - MedicalJewel105 + - QuazChick +--- + +::: tip +This is an appendix page. You can start the guide from the beginning [here](/guide/index). +::: + +This page is desgined to go into more detail about the manifest.json file, here we will cover what UUIDs are in more detail and how to add them. We will explain the use of dependencies, the different format versions, and how to include meta-data. + +We will also go over the version differences between Behaviour packs, Resource packs, and Skin packs. + +## UUIDs + +UUID is an abbreviation for Universal Unique Identifier, there are 5 UUID versions plus one common unofficial version, A UUID is a 36 character string containing numbers, letters, and dashes. + +Minecraft uses Version 4: Variant 1, which is completely random. This is what creates your pack's unique identity in Minecraft. + +### How to Generate the correct UUID + +You can use online sites such as [UUID Generator](https://www.uuidgenerator.net/version4/) and [UUID Tools](https://www.uuidtools.com/generate/v4) to generate the correct version required for Minecraft. + +## + +### UUID FAQ + +- **Are UUIDs Case-sensitive?** + + - _No, UUIDs are written in base 16 which uses numbers 0-9 and characters a-f. There is no distinction between upper and lowercase letters._ + +- **Can I use the same UUID for the header and the modules UUID?** + - _No, the UUID for the header and the module needs to be different._ + +:::warning +This page is under construction! +::: diff --git a/docs/wiki/guide/blockbench.md b/docs/wiki/guide/blockbench.md new file mode 100644 index 00000000..26b3235f --- /dev/null +++ b/docs/wiki/guide/blockbench.md @@ -0,0 +1,283 @@ +--- +title: 'Blockbench: Modeling, Texturing and Animating' +category: Guide +description: A first peek into Blockbench +prefix: '7. ' +nav_order: 7 +mentions: + - KaiFireborn + - SirLich + - Dreamedc2015 + - SmokeyStack + - sermah + - cda94581 + - TheItsNameless + - ThijsHankelMC + - MedicalJewel105 + - ChibiMango + - smell-of-curry +--- + +Blockbench is a free software designed to make Minecraft modeling, texturing, and animating possible. It is available for mobile browsers, Windows 10, and macOS. Please install it at [blockbench.net](https://blockbench.net/). + +Let's get started. + +1. Open Blockbench. +2. Choose _File>New>Bedrock Model_. This is important because Minecraft Bedrock will not be able to read Java models. +3. A screen like this will have popped up. + + ![](/assets/images/guide/create_entity_project_menu.png) + + - `"File name:"` is self-explanatory. My file will generate as "skele_yaklin.geo.json". + - `"Model Identifier:"` is the model identifier (namespace not required), a short name for this ID will be defined later. + - `"Box UV"` has to be checked on for automatic UV editing and unwrapping for texturing. + - `"Texture Height"` and `"Texture Width"` define the resolution of the model's textures. + +4. Press confirm. You'll see a screen like this: + + ![](/assets/images/guide/create_entity_workspace.png) + + - You can see many tools here: move, resize, rotate, etc. + - You can add bones and cubes in the menu on the right-bottom corner. Cubes can rotate on their own; the bones will carry everything in them along; + +5. Now, you are ready to create your model! For more in-depth tutorials on modeling, please check out the videos by Everbloom Studio below. + + + + + +## Texturing + +Now that you have your model in place let's start texturing! + +1. On the left-bottom panel, click "Create Texture" +1. Write down your image file name under "Name:". Mine will export as `ghost.png`. Check "Template:" to make a template texture - it'll be easier to work with. + ![](/assets/images/guide/create_entity_texture_1.png) +1. Check everything and change your resolution to the one you set in the very first step. + ![](/assets/images/guide/create_entity_texture_2.png) +1. Go to "Paint" in the upper right corner and paint your texture. + +## Animating + +Once your model and texture are done, you can start animating. Go to "Animate" in the upper right corner. + +You might want to adjust one of the toolbars by adding "Export Animations" and "Import Animations" like this: +![](/assets/images/guide/create_entity_animation_1.png) + +1. Click "Add Animation" [the plus icon on the top right side] and name it `animation.{yourEntityName}.move`. + Create the first frame of your walking animation under 0 on the timeline by moving the legs. + ![](/assets/images/guide/create_entity_animation_2.png) +1. Create the second frame under 0.5 on the timeline. + ![](/assets/images/guide/create_entity_animation_3.png) +1. Finally, copy the first frame to the third frame by placing your timeline cursor on 1.0 and selecting the first frame, then ctrl+c, ctrl+v. +1. Right-click the animation and tick "Loop" for the animation to loop. + ![](/assets/images/guide/create_entity_animation_4.png) + +## Saving your work + +Now that our model, texture, and walk animation are complete, you can save your work. + +Go to _File > Save Model_ or _File > Export Bedrock Geometry_. Save the model in `RP/models/entity`, the texture in `RP/textures/entity/` and the animation in `RP/animations`. Congratulations! You've successfully created your first entity's visuals! You can see the file examples below. + +_Meanwhile, why not upgrade the visuals of your own unique entities' or create another one?_ + + + +RP/models/entity/ghost.geo.json + +```json +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.ghost", + "texture_width": 64, + "texture_height": 64, + "visible_bounds_width": 3, + "visible_bounds_height": 3.5, + "visible_bounds_offset": [0, 1.25, 0] + }, + "bones": [ + { "name": "root", "pivot": [0, 3, 0] }, + { + "name": "body", + "parent": "root", + "pivot": [0, 4.625, 0], + "cubes": [ + { + "origin": [-4, 3, -4], + "size": [8, 13, 8], + "uv": [0, 20] + } + ] + }, + { + "name": "leftArm", + "parent": "body", + "pivot": [4.6, 15.5, 0.5], + "cubes": [ + { + "origin": [4.1, 7, -1], + "size": [3, 9, 3], + "uv": [32, 32] + } + ] + }, + { + "name": "rightArm", + "parent": "body", + "pivot": [-4.5, 15.5, 0.5], + "cubes": [ + { + "origin": [-7.1, 7, -1], + "size": [3, 9, 3], + "uv": [32, 20] + } + ] + }, + { + "name": "head", + "parent": "body", + "pivot": [0, 16, 0], + "cubes": [ + { + "origin": [-5, 16, -5], + "size": [10, 10, 10], + "uv": [0, 0] + } + ] + } + ] + } + ] +} +``` + +RP/animations/ghost.a.animations.json + +```json +{ + "format_version": "1.8.0", + "animations": { + "animation.ghost.idle": { + "loop": true, + "animation_length": 3, + "bones": { + "body": { + "rotation": { "0.0": [10, 0, 0], "3.0": [10, 0, 0] }, + "position": { + "0.0": [0, 0, 0], + "1.5": [0, 1, 0], + "3.0": [0, 0, 0] + } + }, + "leftArm": { + "rotation": { + "0.0": [-10, 0, 0], + "1.5": [-5, 0, 0], + "3.0": [-10, 0, 0] + } + }, + "rightArm": { + "rotation": { + "0.0": [-10, 0, 0], + "1.5": [-5, 0, 0], + "3.0": [-10, 0, 0] + } + }, + "head": { + "rotation": { + "0.0": [-7.5, 0, 0], + "1.5": [-2.5, 0, 0], + "3.0": [-7.5, 0, 0] + } + } + } + }, + "animation.ghost.attack": { + "animation_length": 0.75, + "bones": { + "body": { + "rotation": { + "0.0": [10, 0, 0], + "0.2917": [10, 15, 0], + "0.5": [22.5, -12.5, 0], + "0.75": [10, 0, 0] + }, + "position": { + "0.0": [0, 0, 0], + "0.2917": [0, 0, 3], + "0.5": [0, 0, -3], + "0.75": [0, 0, 0] + } + }, + "leftArm": { + "rotation": { "0.0": [-10, 0, 0], "0.75": [-10, 0, 0] } + }, + "rightArm": { + "rotation": { + "0.0": [-10, 0, 0], + "0.2083": [-10, 0, 0], + "0.2917": [-10, 62.5, 117.5], + "0.5": [-80, -17.5, 22.5], + "0.75": [-10, 0, 0] + } + }, + "head": { + "rotation": { "0.0": [-7.5, 0, 0], "0.75": [-7.5, 0, 0] } + } + } + }, + "animation.ghost.move": { + "loop": true, + "animation_length": 1, + "bones": { + "body": { + "rotation": { + "0.0": [15, 0, 0], + "0.25": [15, -2.5, 0], + "0.5": [15, 0, 0], + "0.75": [15, 2.5, 0], + "1.0": [15, 0, 0] + }, + "position": [0, 0, 0] + }, + "leftArm": { + "rotation": { + "0.0": [15, 0, 0], + "0.5": [20, 0, 0], + "1.0": [15, 0, 0] + } + }, + "rightArm": { + "rotation": { + "0.0": [15, 0, 0], + "0.5": [20, 0, 0], + "1.0": [15, 0, 0] + } + }, + "head": { + "rotation": { + "0.0": [-12.5, 0, 0], + "0.5": [-15, 0, 0], + "1.0": [-12.5, 0, 0] + } + } + } + } + } +} +``` + + + +## What you have learned + + + +- [x] How to create an entity in Blockbench +- [x] How to use Blockbench to model, texture, and animate your entity + + + diff --git a/docs/wiki/guide/custom-entity.md b/docs/wiki/guide/custom-entity.md new file mode 100644 index 00000000..647a3d65 --- /dev/null +++ b/docs/wiki/guide/custom-entity.md @@ -0,0 +1,1431 @@ +--- +title: 'Create a custom Entity' +category: Guide +description: How to create your first custom Entity +nav_order: 6 +prefix: '6. ' +mentions: + - ThijsHankelMC + - TheItsNameless + - SmokeyStack + - MedicalJewel105 + - SirLich + - ChibiMango + - smell-of-curry + - Hatchibombotar + - Sephodious + - LeGend077 + - Ascent817 + - BaHuu + - Sprunkles317 + - ThomasOrs +--- + +Similarly to custom items, we can also make custom entities with many similar mechanics to the vanilla entities in the game. These entities can be incredibly powerful allowing you to make your own animals which can be bred and tamed or an aggressive mob that attacks anything it sees. + +Here we will make a ghost entity which will float, attack the player and drop our ectoplasm item on death. + +
+ +
+
+ +Just like items, entities are made up of two parts: + +- The visuals (texture, name, animations, sounds) +- The behaviors (movement, attacks) + +Differently though, we will need two main files for our entity called the _server_ file and the _client_ file which sit in our BP and RP respectively. +We will also need additional files to describe the geometry of our entity and its animations, but we will cover those in later sections. + +First, we will cover how to create an entity & define its behavior. Next, we will look at how to add the visuals. + +## Entity Behavior + +Like with items, we need a file to tell our entity how to behave which points an identifier to certain components which define behavior. This file will be very similar to our item behavior file except with a lot more components. + +We define our server file in our BP, under the `BP/entities/` folder. We will call this file `ghost.se.json`. Here the `.se` stands for _server entity_. This is for clarity and is recommend in the [Style Guide](/meta/style-guide). + +This is a basic overview of the file: + +BP/entities/ghost.se.json + +```json +{ + "format_version": "1.16.0", + "minecraft:entity": { + "description": {...}, + "components": {...} + } +} +``` + +Just like with the items, we have our format version and here we have `"minecraft:entity"` as this is an entity file. From now on we won't comment on the format version and recommend to use the version example that we give. + +For entities we have a little bit more information under `description`: + +BP/entities/ghost.se.json#minecraft:entity + +```json +"description": { + "identifier": "wiki:ghost", + "is_summonable": true, + "is_spawnable": true, + "is_experimental": false +} +``` + +The `identifier` key serves the same purpose, to point to which entity we are talking about. +The other keys determine what ways we can add the entity to our world: + +- `is_summonable` : Whether it can be summoned using the `/summon` command. +- `is_spawnable` : Whether it can spawn in the world using a spawn egg or spawn rules. +- `is_experimental`: Whether the entity is experimental (if so it can only be added to Experimental Worlds). + +We recommend leaving the settings as they are here as any changes will make it harder to test your entity in game. + +### Components + +An entity has a lot more behaviors than just an item, so we need to define more components for it. +We will break down the types of components will use into categories and then look at them closer. +For more information on components in entities, you can check out our page [here](/entities/entity-intro-bp). + +### Stat Components + +These are the components that you will generally have on every entity. This define some core attributes to your entity. + +BP/entities/ghost.se.json#minecraft:entity#components + +```json +"minecraft:type_family": { + "family": ["ghost", "monster"] +}, +"minecraft:health": { + "value": 20, + "max": 20 +}, +"minecraft:attack": { + "damage": 3 +}, +"minecraft:movement": { + "value": 0.2 +}, +"minecraft:collision_box": { + "width": 1, + "height": 2 +}, +"minecraft:loot": { + "table": "loot_tables/entities/ghost.json" +}, +``` + +The components `minecraft:health` and `minecraft:attack` and `minecraft:movement` are straight forward and set the entities health, attack damage and movement speed. The collision box of an entity is the box within which the entity interacts with or collides with blocks or other entities. This is defined with `minecraft:collision_box` which will center the box on the middle on the entity. + +`minecraft:type_family` adds family tags to the entity. Family tags are used to group entities in a similar category together. For example `monster` includes zombies, skeletons and creepers. This allows us to be able to select all entities with the `monster` tag. + +`minecraft:loot` defines the path to the loot table that the entity will drop on death. We will create this loot table in a later section using this path. + +### Movement Components + +In order for an entity to move around, we need to define two things, _how_ it moves and _where_ it can move to. This is defined using the `movement` and `navigation` components respectively. + +You will always need a `movement` and `navigation` component if you want your entity to be able to move. + +BP/entities/ghost.se.json#minecraft:entity#components + +```json +"minecraft:physics": {}, +"minecraft:jump.static": {}, +"minecraft:movement.basic": {}, +"minecraft:navigation.walk": { + "can_walk": true, + "avoid_sun": true, + "can_pass_doors": true, + "can_open_doors": true +} +``` + +`minecraft:physics` is used to apply gravity and collision to your entity. Note: you can not change this component via using a component group. +`minecraft:jump.static` allows your entity to jump up blocks for traversal. Both are used on almost every entity. + +There are few different types of movement components which allow different types of movement such as `minecraft:movement.swim` used by dolphins, `minecraft:movement.fly` used by parrots and `minecraft:movement.hover` used by bees. +The `minecraft:movement.basic` component allows our entity to walk by moving over blocks. To make it seem like our entity is actually floating, we will use our geometry . + +The navigation component is a pathfinder which defines what paths we allow our entity to follow. For example skeletons will try not to walk in sunlight, so their pathing stops them from taking paths that would put them in sunlight. Additionally, parrots can fly so they can path into the air unlike walking mobs. + +These components have a lot of different settings which allow for interesting pathing. The settings we've chosen let our ghost walk along the ground, avoid stepping into sunlight, pass through doorways and open doors. + +### Behavior Components + +While we have defined _how_ our entity does things, we haven't yet defined _when_ or _what_ they do. This is where `.behavior` components come in. These components define the specific actions that our entity will do. +For example, villagers will try to breed so they have the `minecraft:behavior.breed` component and tamed wolves follow their owners so they have the `minecraft:behavior.follow_owner` component. + +We want our ghost to be able to idly walk and look around, target the player when nearby and then attack them. Here are the components that we use: + +BP/entities/ghost.se.json#minecraft:entity#components + +```json +// Allow for random movement and looking around +"minecraft:behavior.random_stroll": {...}, +"minecraft:behavior.random_look_around": {...}, +"minecraft:behavior.look_at_player": {...}, +// Allow for targeting +"minecraft:behavior.hurt_by_target": {...}, +"minecraft:behavior.nearest_attackable_target": {...}, +// Allow for attacking +"minecraft:behavior.delayed_attack": {...} +``` + +The first component, `minecraft:behavior.random_stroll` allows our entity to choose a random point nearby to path to periodically. This path is created with our `navigation` component and then the type of movement is defined by our `movement` component. + +The next two components allow our entity to randomly look around and to look at the player if they are within range. + +For attacking, in order for our entity to attack, it needs a `target`. The two behaviors `minecraft:behavior.hurt_by_target` and `minecraft:behavior.nearest_attackable_target` will cause the entity to target any entity that hurts it and target any the nearest enemy to it within range. + +Finally, the `minecraft:behavior.delayed_attack` is how our entity actually attacks it target. + +Each of these behaviors have further settings to tweak the exact behavior we want. + +BP/entities/ghost.se.json#minecraft:entity#components + +```json +"minecraft:behavior.random_stroll": { + "priority": 6, + "speed_multiplier": 1 +}, +"minecraft:behavior.random_look_around": { + "priority": 7 +}, +"minecraft:behavior.look_at_player": { + "priority": 7, + "look_distance": 6, + "probability": 0.02 +}, +"minecraft:behavior.hurt_by_target": { + "priority": 1 +}, +"minecraft:behavior.nearest_attackable_target": { + "priority": 2, + "within_radius": 25, + "reselect_targets": true, + "entity_types": [ + { + "filters": { + "any_of": [ + { + "test": "is_family", + "subject": "other", + "value": "player" + } + ] + }, + "max_dist": 35 + } + ] +}, +"minecraft:behavior.delayed_attack": { + "priority": 0, + "attack_once": false, + "track_target": true, + "require_complete_path": false, + "random_stop_interval": 0, + "reach_multiplier": 1.5, + "speed_multiplier": 1, + "attack_duration": 0.75, + "hit_delay_pct": 0.5 +} +``` + +For more details about what each of these options do, you can read about them on the official documentation, [bedrock.dev](https://bedrock.dev/docs/stable/Entities). + +#### Priority + +All behaviors contain a `"priority"` field. This field is used to decide which behavior to run when many can. + +When the entity is picking something to do, it searches all its behaviors from lowest priority to the highest priority and picks the first one that it can do. For this reason, you need to make important behaviors like `minecraft:behavior.nearest_attackable_target` lower than behaviors like `minecraft:behavior.look_at_player`. If the `look_at_player` behavior is lower, it will always run this first when the player is close, and the entity will never attack. + +In general, important behaviors will have a priority of `0` or `1`. + +### Full Entity Server File + + + +BP/entities/ghost.se.json + +```json +{ + "format_version": "1.16.0", + "minecraft:entity": { + "description": { + "identifier": "wiki:ghost", + "is_summonable": true, + "is_spawnable": true, + "is_experimental": false + }, + "components": { + "minecraft:type_family": { + "family": ["ghost", "monster"] + }, + "minecraft:health": { + "value": 20, + "max": 20 + }, + "minecraft:attack": { + "damage": 3 + }, + "minecraft:movement": { + "value": 0.2 + }, + "minecraft:collision_box": { + "width": 1, + "height": 2 + }, + "minecraft:loot": { + "table": "loot_tables/entities/ghost.json" + }, + "minecraft:physics": {}, + "minecraft:jump.static": {}, + "minecraft:movement.basic": {}, + "minecraft:navigation.walk": { + "can_walk": true, + "avoid_sun": true, + "can_pass_doors": true, + "can_open_doors": true + }, + + "minecraft:behavior.random_stroll": { + "priority": 6, + "speed_multiplier": 1 + }, + "minecraft:behavior.random_look_around": { + "priority": 7 + }, + "minecraft:behavior.look_at_player": { + "priority": 7, + "look_distance": 6, + "probability": 0.02 + }, + "minecraft:behavior.hurt_by_target": { + "priority": 1 + }, + "minecraft:behavior.nearest_attackable_target": { + "priority": 2, + "within_radius": 25, + "reselect_targets": true, + "entity_types": [ + { + "filters": { + "any_of": [ + { + "test": "is_family", + "subject": "other", + "value": "player" + } + ] + }, + "max_dist": 35 + } + ] + }, + "minecraft:behavior.delayed_attack": { + "priority": 0, + "attack_once": false, + "track_target": true, + "require_complete_path": false, + "random_stop_interval": 0, + "reach_multiplier": 1.5, + "speed_multiplier": 1, + "attack_duration": 0.75, + "hit_delay_pct": 0.5 + } + } + } +} +``` + + + +With that we have completed our entity behavior file. + +More complex entities can also have different _states_, where they will behave differently depending on what state they are in. For example, a wild wolf will walk around freely, but once it is tamed it will follow the player. An _event_ (being tamed) caused the wolf to change _states_. This feature allows us to create dynamic entities which can perform different actions when different events occurs. You can learn more about this in our guide [here](/entities/entity-intro-bp). + +If you open your world and try to summon in your entity using `/summon wiki:ghost`, it should behave like we expect but there will only be a shadow on the ground. You might also see its name as a translation key, similar to how it happened with our item. + +Next we will learn how to create our resource or client file and how to assign our texture, geometry and animations. + +## Entity Resource + +Applying visuals to an entity is very different to an item. Since there are a lot more pieces, we have a separate file dedicated to defining the resources. +This is the called entity _client file_ which we will name `ghost.ce.json`. These files go in the folder `RP/entity/`. + +In this section, we will use the example resources created for our ghost entity to demonstrate how to add them to an entity. In the next section of the guide, we explain how to use Blockbench, a dedicated 3D editor, to create your own entity geometry and animations. + +### Model + +The 'model' for our entity is the shape of our entity, also called the 'geometry'. This describes the shape of our entity, like how a pig is a box with 4 legs and a head whereas a chicken has 2 legs, a head and wings. The geometry is stored as a JSON file in `RP/models/entity/` and ours will be named `ghost.geo.json`. + +This file is automatically generated by Blockbench for us, so there is no need to learn its syntax by hand. As such, we won't go into full detail when looking at the file. It stores the data about each block in our model, such as size, position and rotation. + +RP/models/entity/ghost.geo.json + +```json +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.ghost", + "texture_width": 64, + "texture_height": 64, + "visible_bounds_width": 3, + "visible_bounds_height": 3.5, + "visible_bounds_offset": [0, 1.25, 0] + }, + "bones": [ + { "name": "root", "pivot": [0, 3, 0] }, + { + "name": "body", + "parent": "root", + "pivot": [0, 4.625, 0], + "cubes": [ + { + "origin": [-4, 3, -4], + "size": [8, 13, 8], + "uv": [0, 20] + } + ] + }, + { + "name": "leftArm", + "parent": "body", + "pivot": [4.6, 15.5, 0.5], + "cubes": [ + { + "origin": [4.1, 7, -1], + "size": [3, 9, 3], + "uv": [32, 32] + } + ] + }, + { + "name": "rightArm", + "parent": "body", + "pivot": [-4.5, 15.5, 0.5], + "cubes": [ + { + "origin": [-7.1, 7, -1], + "size": [3, 9, 3], + "uv": [32, 20] + } + ] + }, + { + "name": "head", + "parent": "body", + "pivot": [0, 16, 0], + "cubes": [ + { + "origin": [-5, 16, -5], + "size": [10, 10, 10], + "uv": [0, 0] + } + ] + } + ] + } + ] +} +``` + +The important information that we need is the `identifier` which we will use to reference our geometry file, which here is `geometry.ghost`. + +### Texture + +Our entity now has its shape, but it also needs a texture. This texture can also be created in Blockbench and is simply a `.png` file. + +`RP/textures/entity/ghost.png` + +![ectoplasm.png](https://raw.githubusercontent.com/Bedrock-OSS/wiki-addon/main/ma-guide/guide_RP/textures/entity/ghost.png) + +Download texture here + +You may recall, when we made our item, we assigned a shortname to our texture to reference later. We will be doing something similar for our entity within our entity file, so make sure you keep the file path to the texture. + +### Animations + +Animations allow our entity to have more life and move in different ways. We can have as many animations for an entity as we want and we can also trigger them at different types using an _animation controller_ which we will cover in the next section. + +Depending on your entity, you may want different animations. For our ghost we will have an `idle`, `attack` and `move` animation. These files are also created automatically in Blockbench, so we won't look into it in full detail. + +An animation file can contain one or multiple animations within it. Our animations will all be under one file called `ghost.a.json` under `RP/animations/`. + +RP/animations/ghost.a.json + +```json +{ + "format_version": "1.8.0", + "animations": { + "animation.ghost.idle": {...}, + "animation.ghost.attack": {...}, + "animation.ghost.move": {...} + } +} +``` + +Each animation is defined by the key, so here our three animation identifiers are `animation.ghost.idle`, `animation.ghost.attack` and `animation.ghost.move`. + +:::tip NOTE +If you have multiple animation files for one entity, consider moving them all into one file to keep your folders easy to read and navigate. +If not, ensure that when you are referencing the animation in your entity file, you use the animation identifier and _not_ the file name. +::: + + + +RP/animations/ghost.a.json + +```json +{ + "format_version": "1.8.0", + "animations": { + "animation.ghost.idle": { + "loop": true, + "animation_length": 3, + "bones": { + "body": { + "rotation": { "0.0": [10, 0, 0], "3.0": [10, 0, 0] }, + "position": { + "0.0": [0, 0, 0], + "1.5": [0, 1, 0], + "3.0": [0, 0, 0] + } + }, + "leftArm": { + "rotation": { + "0.0": [-10, 0, 0], + "1.5": [-5, 0, 0], + "3.0": [-10, 0, 0] + } + }, + "rightArm": { + "rotation": { + "0.0": [-10, 0, 0], + "1.5": [-5, 0, 0], + "3.0": [-10, 0, 0] + } + }, + "head": { + "rotation": { + "0.0": [-7.5, 0, 0], + "1.5": [-2.5, 0, 0], + "3.0": [-7.5, 0, 0] + } + } + } + }, + "animation.ghost.attack": { + "animation_length": 0.75, + "bones": { + "body": { + "rotation": { + "0.0": [10, 0, 0], + "0.2917": [10, 15, 0], + "0.5": [22.5, -12.5, 0], + "0.75": [10, 0, 0] + }, + "position": { + "0.0": [0, 0, 0], + "0.2917": [0, 0, 3], + "0.5": [0, 0, -3], + "0.75": [0, 0, 0] + } + }, + "leftArm": { + "rotation": { "0.0": [-10, 0, 0], "0.75": [-10, 0, 0] } + }, + "rightArm": { + "rotation": { + "0.0": [-10, 0, 0], + "0.2083": [-10, 0, 0], + "0.2917": [-10, 62.5, 117.5], + "0.5": [-80, -17.5, 22.5], + "0.75": [-10, 0, 0] + } + }, + "head": { + "rotation": { "0.0": [-7.5, 0, 0], "0.75": [-7.5, 0, 0] } + } + } + }, + "animation.ghost.move": { + "loop": true, + "animation_length": 1, + "bones": { + "body": { + "rotation": { + "0.0": [15, 0, 0], + "0.25": [15, -2.5, 0], + "0.5": [15, 0, 0], + "0.75": [15, 2.5, 0], + "1.0": [15, 0, 0] + }, + "position": [0, 0, 0] + }, + "leftArm": { + "rotation": { + "0.0": [15, 0, 0], + "0.5": [20, 0, 0], + "1.0": [15, 0, 0] + } + }, + "rightArm": { + "rotation": { + "0.0": [15, 0, 0], + "0.5": [20, 0, 0], + "1.0": [15, 0, 0] + } + }, + "head": { + "rotation": { + "0.0": [-12.5, 0, 0], + "0.5": [-15, 0, 0], + "1.0": [-12.5, 0, 0] + } + } + } + } + } +} +``` + + + +### Animation Controller + +We have our animations but our entity won't know when to play them. This is where animation controllers are used. These controllers at their core, _control_ how the animations are played. +An animation controller is made up of _states_ and _transitions_ between states. This allows us to play certain animations when the entity is in certain states, which we can transition between when certain conditions are met. + +For example, while an entity is moving, transition to the moving state which plays the `move` animation. Or while an entity is attacking, transition to the attack state which plays the `attack` animation. + +Let us look at our animation controller for attacking. + +RP/animation_controllers/ghost.ac.json#animation_controllers + +```json +"controller.animation.ghost.attack": { + "states": { + "default": { + "transitions": [ + { + "attacking": "q.is_delayed_attacking" + } + ] + }, + "attacking": { + "blend_transition": 0.2, + "animations": ["attack"], + "transitions": [ + { + "default": "!q.is_delayed_attacking" + } + ] + } + } +} +``` + +You can see we have two states, `default` and `attacking`. Our entity begins in the default state. + +You can see under `transitions`, we have a condition, which when true will transfer the entity to a state. + + + +```json +{ + "attacking": "q.is_delayed_attacking" +} +``` + +Here, `attacking` is the state that will be transitioned to, and `q.is_delayed_attacking` is the condition that needs to be true for the transition to occur. +This condition is called a _query_. These queries can tell us things about the entity such as if it is attacking or moving. The query `q.is_delayed_attacking` will return `true` when the entity is performing the attack behavior. + +When the entity is in the `attacking` state, it also has a transition back to the default state. Now the condition is `!q.is_delayed_attacking`. Here the `!` means _not_, so it will return the opposite result of `q.is_delayed_attacking` (If `q.is_delayed_attacking` returns `true` then `!q.is_delayed_attacking` returns false). + +This state also has `animations`. These are the animations that will always play while in this state. Note that we are using the _shortname_ for our animation here, which we will reference in our entity file later. If you don't, the animations will not play. +There is also the `blend_transition` key, which allows the animations to slowly fade into each other. A higher number means a longer blending time. + +We can also make a similar controller for our `move` and `idle` animation. + +RP/animation_controllers/ghost.ac.json#animation_controllers + +```json +"controller.animation.ghost.walk": { + "initial_state": "standing", + "states": { + "standing": { + "blend_transition": 0.2, + "animations": ["idle"], + "transitions": [ + { + "moving": "q.modified_move_speed > 0.1" + } + ] + }, + "moving": { + "blend_transition": 0.2, + "animations": ["move"], + "transitions": [ + { + "standing": "q.modified_move_speed < 0.1" + } + ] + } + } +} +``` + +This follows a similar pattern with some additions. +We now have `initial_state` which tells the controller which state to start on. If none is listed then it will start on the state `default`. +You'll also notice our queries look slightly different. Here the query `q.modified_move_speed` returns a value, so in order to return a boolean (i.e. true or false) we look at when the value is above or below `0.1`. For more in depth information on animation controllers, you can read [here](/animation-controllers/animation-controllers-intro). + +Now that we have our animation controllers, we can add them to our animation controller file. Similarly to animations, the key is the identifier for our animation controller; `controller.animation.ghost.attack` and `controller.animation.ghost.walk`. + +Our file will be called `ghost.ac.json` and will be placed in `RP/animation_controllers/`. + +RP/animation_controllers/ghost.ac.json + +```json +{ + "format_version": "1.12.0", + "animation_controllers": { + "controller.animation.ghost.attack": { + "states": { + "default": { + "transitions": [ + { + "attacking": "q.is_delayed_attacking" + } + ] + }, + "attacking": { + "blend_transition": 0.2, + "animations": ["attack"], + "transitions": [ + { + "default": "!q.is_delayed_attacking" + } + ] + } + } + }, + "controller.animation.ghost.walk": { + "initial_state": "standing", + "states": { + "standing": { + "blend_transition": 0.2, + "animations": ["idle"], + "transitions": [ + { + "moving": "q.modified_move_speed > 0.1" + } + ] + }, + "moving": { + "blend_transition": 0.2, + "animations": ["move"], + "transitions": [ + { + "standing": "q.modified_move_speed < 0.1" + } + ] + } + } + } + } +} +``` + +With that, we have created all the resources we need for our entity. We will now create our entity file. + +### Entity Client File + +The client file contains all the references to the visual components of our entity. +Our client file will go in `RP/entity/` and we name this file `ghost.ce.json`. This file will have all our information under the `description` key. We begin with the familiar formatting: + +RP/entity/ghost.ce.json + +```json +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "wiki:ghost" + } + } +} +``` + +We use the same identifier as for our behavior file in order to point to the correct entity. + +To begin, we need to define the visuals of our entity in our file so we know which models and textures we are using. We also need to do the same for our animations and animation controllers. + +#### Render Controller + +In order to display our entity it needs to be _rendered_. For this to happen, it needs a material, texture and geometry. We have already made a texture and geometry. A material defines how our texture will be displayed. For example, a skeleton uses a material to allow for transparency and an enderman uses a material to allow its eyes to glow. + +Since our ghost has some transparency, we need a material which will render this correctly. Luckily, Minecraft has many pre-built materials for us to use such as `entity_alphatest` which will allow us to do this. You can create your own materials but be warned it is very advanced. If you are interested though, you can begin [here](/documentation/materials). + +For us to now use these resources, we need to define a reference to them with a shortname. This is similar to how we did for items within the `item_texture.json` file, except here we do it in the entity client file. Here is the layout. + +RP/entity/ghost.ce.json + +```json +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "wiki:ghost", + "materials": { + "default": "entity_alphatest" + }, + "textures": { + "default": "textures/entity/ghost" + }, + "geometry": { + "default": "geometry.ghost" + } + } + } +} +``` + +Here for each category we have assigned the shortname `default` for each of our resources, ensuring to use the correct paths and identifiers. We are able to define multiple of these, though that is more advanced. Now we can use these shortnames to reference our resources. + +In order for these resources to be rendered, we need to tell the game which resources to render in. This is controlled with a _render controller_. The controller tells the game which geometry, material and texture to render for the entity, allowing us to see it in game. + +The render controller is defined in a separate file and uses the shortnames we defined in our entity file. +The file is called `ghost.rc.json` and is under `RP/render_controllers/`: + +RP/render_controllers/entity/ghost.rc.json + +```json +{ + "format_version": "1.10.0", + "render_controllers": { + "controller.render.ghost": { + "geometry": "geometry.default", + "materials": [ + { + "*": "material.default" + } + ], + "textures": ["texture.default"] + } + } +} +``` + +This follows a similar structure to the animation controller and animation file, with our render controller identifier being `controller.render.ghost`. +This tells the game that the resource rendered should be the resource with shortname `default`. Render controllers can also allow you to display different textures or apply different materials to different parts of our model. Under `materials`, we use `"*"` to mean that we apply this material to all _bones_ in our model (i.e. each cube in our model.) For more information on render controllers, you can check our page [here](/entities/render-controllers). + +:::tip +If you keep your shortnames consistent, you can actually reference the same render controller for multiple entities. +::: + +Now to tell your entity to use this render controller, we add it to our entity file like so: + +RP/entity/ghost.ce.json#description + +```json +"render_controllers": ["controller.render.ghost"] +``` + +With that our entity file should look like this. + +RP/entity/ghost.ce.json + +```json +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "wiki:ghost", + "materials": { + "default": "entity_alphatest" + }, + "textures": { + "default": "textures/entity/ghost" + }, + "geometry": { + "default": "geometry.ghost" + }, + "render_controllers": ["controller.render.ghost"] + } + } +} +``` + +Now if we spawn our entity into a world, we should be able to see it. + +#### Scripts + +Now let us add our animations. Like with our other resources, we need to define shortnames for them. Keep in mind, we also need to define shortnames our animation controllers as well. + +RP/entity/ghost.ce.json#description + +```json +"animations": { + "walk_controller": "controller.animation.ghost.walk", + "attack_controller": "controller.animation.ghost.attack", + "attack": "animation.ghost.attack", + "idle": "animation.ghost.idle", + "move": "animation.ghost.move" +} +``` + +You'll recall, these are the shortnames we used in our animation controllers; any animations we want to use in animation controllers, must be defined with a shortname in the entity client file. + +Now that we have animations and animation controllers referenced, we need to decide when the entity will run them. This is done using `scripts`: + +RP/entity/ghost.ce.json#description + +```json +"scripts": { + "animate": [ + "walk_controller", + "attack_controller" + ] +} +``` + +Here, `scripts` tell the entity to perform certain actions at certain times. The `animate` key will run any animation or controller referenced every tick. This means that each tick our animation controller will check whether to transition to a new state and perform any animations in the state they are in. + +With this our animations should be working correctly. + +#### Spawn Egg + +The final step to finalise our entity client file, is to create a spawn egg for our entity. Luckily, our file can generate one for us with the key `spawn_egg`. + +RP/entity/ghost.ce.json#description + +```json +"spawn_egg": { + "overlay_color": "#bdd1d1", + "base_color": "#9fb3b3" +} +``` + +This will generate a spawn egg which will summon our entity when used. It uses the hex codes in `base_color` and `overlay_color` to color the egg. If you want a custom icon for your spawn egg, instead use the key `texture` and put in the shortname to the texture you want. Follow the method in the item tutorial on how to define an texture shortname for an item. + +```json +"spawn_egg": { + "texture": "texture_shortname" +} +``` + +With that, we have completed our entity client file. + + + +RP/entity/ghost.ce.json + +```json +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "wiki:ghost", + "materials": { + "default": "entity_alphatest" + }, + "textures": { + "default": "textures/entity/ghost" + }, + "geometry": { + "default": "geometry.ghost" + }, + "scripts": { + "animate": ["walk_controller", "attack_controller"] + }, + "animations": { + "walk_controller": "controller.animation.ghost.walk", + "attack_controller": "controller.animation.ghost.attack", + "attack": "animation.ghost.attack", + "idle": "animation.ghost.idle", + "move": "animation.ghost.move" + }, + "spawn_egg": { + "overlay_color": "#bdd1d1", + "base_color": "#9fb3b3" + }, + "render_controllers": ["controller.render.ghost"] + } + } +} +``` + + + +### Entity name + +The final steps are to add our entity's name to the language files. You may have also noticed that if you created a spawn egg, it will also have a translation key for a name; we will also add this. Within `en_US.lang`, make sure you add names for both the entity and entity spawn egg item. They should look similar to this: + +RP/texts/en_US.lang + +```json +entity.wiki:ghost.name=Ghost +item.spawn_egg.entity.wiki:ghost.name=Ghost +``` + +## Overview + +Done! Your entity should now show up in Minecraft, complete with all behaviors and visuals, including animations! You should be able to summon your entity using `/summon` or by finding the spawn egg in the creative menu. + +Your folder structure should look like this: + + + + + +BP/entities/ghost.se.json + +```json +{ + "format_version": "1.16.0", + "minecraft:entity": { + "description": { + "identifier": "wiki:ghost", + "is_summonable": true, + "is_spawnable": true, + "is_experimental": false + }, + "components": { + "minecraft:type_family": { + "family": ["ghost", "monster"] + }, + "minecraft:health": { + "value": 20, + "max": 20 + }, + "minecraft:attack": { + "damage": 3 + }, + "minecraft:movement": { + "value": 0.2 + }, + "minecraft:collision_box": { + "width": 1, + "height": 2 + }, + "minecraft:loot": { + "table": "loot_tables/entities/ghost.json" + }, + "minecraft:physics": {}, + "minecraft:jump.static": {}, + "minecraft:movement.basic": {}, + "minecraft:navigation.walk": { + "can_walk": true, + "avoid_sun": true, + "can_pass_doors": true, + "can_open_doors": true + }, + + "minecraft:behavior.random_stroll": { + "priority": 6, + "speed_multiplier": 1 + }, + "minecraft:behavior.random_look_around": { + "priority": 7 + }, + "minecraft:behavior.look_at_player": { + "priority": 7, + "look_distance": 6, + "probability": 0.02 + }, + "minecraft:behavior.hurt_by_target": { + "priority": 1 + }, + "minecraft:behavior.nearest_attackable_target": { + "priority": 2, + "within_radius": 25, + "reselect_targets": true, + "entity_types": [ + { + "filters": { + "any_of": [ + { + "test": "is_family", + "subject": "other", + "value": "player" + } + ] + }, + "max_dist": 35 + } + ] + }, + "minecraft:behavior.delayed_attack": { + "priority": 0, + "attack_once": false, + "track_target": true, + "require_complete_path": false, + "random_stop_interval": 0, + "reach_multiplier": 1.5, + "speed_multiplier": 1, + "attack_duration": 0.75, + "hit_delay_pct": 0.5 + } + } + } +} +``` + + + + + +RP/entity/ghost.ce.json + +```json +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "wiki:ghost", + "materials": { + "default": "entity_alphatest" + }, + "textures": { + "default": "textures/entity/ghost" + }, + "geometry": { + "default": "geometry.ghost" + }, + "scripts": { + "animate": ["walk_controller", "attack_controller"] + }, + "animations": { + "walk_controller": "controller.animation.ghost.walk", + "attack_controller": "controller.animation.ghost.attack", + "attack": "animation.ghost.attack", + "idle": "animation.ghost.idle", + "move": "animation.ghost.move" + }, + "spawn_egg": { + "overlay_color": "#bdd1d1", + "base_color": "#9fb3b3" + }, + "render_controllers": ["controller.render.ghost"] + } + } +} +``` + + + + + +RP/models/entity/ghost.geo.json + +```json +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.ghost", + "texture_width": 64, + "texture_height": 64, + "visible_bounds_width": 3, + "visible_bounds_height": 3.5, + "visible_bounds_offset": [0, 1.25, 0] + }, + "bones": [ + { "name": "root", "pivot": [0, 3, 0] }, + { + "name": "body", + "parent": "root", + "pivot": [0, 4.625, 0], + "cubes": [ + { + "origin": [-4, 3, -4], + "size": [8, 13, 8], + "uv": [0, 20] + } + ] + }, + { + "name": "leftArm", + "parent": "body", + "pivot": [4.6, 15.5, 0.5], + "cubes": [ + { + "origin": [4.1, 7, -1], + "size": [3, 9, 3], + "uv": [32, 32] + } + ] + }, + { + "name": "rightArm", + "parent": "body", + "pivot": [-4.5, 15.5, 0.5], + "cubes": [ + { + "origin": [-7.1, 7, -1], + "size": [3, 9, 3], + "uv": [32, 20] + } + ] + }, + { + "name": "head", + "parent": "body", + "pivot": [0, 16, 0], + "cubes": [ + { + "origin": [-5, 16, -5], + "size": [10, 10, 10], + "uv": [0, 0] + } + ] + } + ] + } + ] +} +``` + + + + + +RP/animations/ghost.a.json + +```json +{ + "format_version": "1.8.0", + "animations": { + "animation.ghost.idle": { + "loop": true, + "animation_length": 3, + "bones": { + "body": { + "rotation": { "0.0": [10, 0, 0], "3.0": [10, 0, 0] }, + "position": { + "0.0": [0, 0, 0], + "1.5": [0, 1, 0], + "3.0": [0, 0, 0] + } + }, + "leftArm": { + "rotation": { + "0.0": [-10, 0, 0], + "1.5": [-5, 0, 0], + "3.0": [-10, 0, 0] + } + }, + "rightArm": { + "rotation": { + "0.0": [-10, 0, 0], + "1.5": [-5, 0, 0], + "3.0": [-10, 0, 0] + } + }, + "head": { + "rotation": { + "0.0": [-7.5, 0, 0], + "1.5": [-2.5, 0, 0], + "3.0": [-7.5, 0, 0] + } + } + } + }, + "animation.ghost.attack": { + "animation_length": 0.75, + "bones": { + "body": { + "rotation": { + "0.0": [10, 0, 0], + "0.2917": [10, 15, 0], + "0.5": [22.5, -12.5, 0], + "0.75": [10, 0, 0] + }, + "position": { + "0.0": [0, 0, 0], + "0.2917": [0, 0, 3], + "0.5": [0, 0, -3], + "0.75": [0, 0, 0] + } + }, + "leftArm": { + "rotation": { "0.0": [-10, 0, 0], "0.75": [-10, 0, 0] } + }, + "rightArm": { + "rotation": { + "0.0": [-10, 0, 0], + "0.2083": [-10, 0, 0], + "0.2917": [-10, 62.5, 117.5], + "0.5": [-80, -17.5, 22.5], + "0.75": [-10, 0, 0] + } + }, + "head": { + "rotation": { "0.0": [-7.5, 0, 0], "0.75": [-7.5, 0, 0] } + } + } + }, + "animation.ghost.move": { + "loop": true, + "animation_length": 1, + "bones": { + "body": { + "rotation": { + "0.0": [15, 0, 0], + "0.25": [15, -2.5, 0], + "0.5": [15, 0, 0], + "0.75": [15, 2.5, 0], + "1.0": [15, 0, 0] + }, + "position": [0, 0, 0] + }, + "leftArm": { + "rotation": { + "0.0": [15, 0, 0], + "0.5": [20, 0, 0], + "1.0": [15, 0, 0] + } + }, + "rightArm": { + "rotation": { + "0.0": [15, 0, 0], + "0.5": [20, 0, 0], + "1.0": [15, 0, 0] + } + }, + "head": { + "rotation": { + "0.0": [-12.5, 0, 0], + "0.5": [-15, 0, 0], + "1.0": [-12.5, 0, 0] + } + } + } + } + } +} +``` + + + + + +RP/animation_controllers/ghost.ac.json + +```json +{ + "format_version": "1.12.0", + "animation_controllers": { + "controller.animation.ghost.attack": { + "states": { + "default": { + "transitions": [ + { + "attacking": "q.is_delayed_attacking" + } + ] + }, + "attacking": { + "blend_transition": 0.2, + "animations": ["attack"], + "transitions": [ + { + "default": "!q.is_delayed_attacking" + } + ] + } + } + }, + "controller.animation.ghost.walk": { + "initial_state": "standing", + "states": { + "standing": { + "blend_transition": 0.2, + "animations": ["idle"], + "transitions": [ + { + "moving": "q.modified_move_speed > 0.1" + } + ] + }, + "moving": { + "blend_transition": 0.2, + "animations": ["move"], + "transitions": [ + { + "standing": "q.modified_move_speed < 0.1" + } + ] + } + } + } + } +} +``` + + + + + +RP/render_controllers/entity/ghost.rc.json + +```json +{ + "format_version": "1.10.0", + "render_controllers": { + "controller.render.ghost": { + "geometry": "geometry.default", + "materials": [ + { + "*": "material.default" + } + ], + "textures": ["texture.default"] + } + } +} +``` + + + +## Your progress so far + + + +- [x] Setup your pack +- [x] Create a custom item +- [x] Create a custom entity +- [x] - How to format the behavior- and resource files for an item +- [x] - How to set an entities texture +- [x] - How to use models, animations, and animation controllers to make your entity more exciting +- [ ] Create the entity's loot, spawn rules, and a custom recipe + + diff --git a/docs/wiki/guide/custom-item.md b/docs/wiki/guide/custom-item.md new file mode 100644 index 00000000..0246141c --- /dev/null +++ b/docs/wiki/guide/custom-item.md @@ -0,0 +1,322 @@ +--- +title: 'Create a custom Item' +category: Guide +description: How to create your first custom Item +nav_order: 5 +prefix: '5. ' +mentions: + - KaiFireborn + - SirLich + - cda94581 + - TheItsNameless + - MedicalJewel105 + - ChibiMango + - TheDoctor15 + - SmokeyStack + - unickorn + - Sprunkles317 + - ThomasOrs + - davedavis +--- + +In Minecraft, we can create custom items, which can be dropped, traded, crafted, and otherwise used like a normal item. There is a lot of power in the system, including the ability to make food, fuel, and tools. + +In this tutorial we are going to learn how to create a simple "ectoplasm" item, which we will later use as a loot-table drop for our ghost entity. + +
+ +
+
+ +Conceptually, items are made up of two parts: + +- The visuals (texture, name) +- The behaviors (how the item should behave) + +First, we will learn how to create a new simple item & define its behaviors. In the next section we will assign a texture to this item, so you can see it in game. + +:::warning +This guide requires experimental features toggled on. +::: + +## Item Behavior + +To make an item we will need a way to identify it and define how we want it to behave. To do this we will be making a file which tell Minecraft to apply certain behaviors to a specific item of our choice. + +At the end of this section we will have fully defined the behavior of our item. + +### Components + +Different items behave differently; you can eat a porkchop, enchanted items glow & eggs can only stack to 16. These are all examples of how the item behaves. +We are able to define how our custom item will behave by using behavior components. + + + +BP/items/example.json/components/ + +```json +"minecraft:food": +"minecraft:foil": true, +"minecraft:max_stack_size": 16 +``` + + + +Components contain information which tells the game what our item should do. For example the component `"minecraft:foil"` determines whether the item should have an enchanted foil to it, so setting it to `true` will apply it. +All components have a `value` attached to it which we can edit to get the behaviour we want. + +For our ectoplasm, we will set it to have a stack size of 16, similar to eggs. To do this we use the component `"minecraft:max_stack_size"` and set its value to `16`. + +### Identifier + +In order for the game to apply the correct components to the correct item, we need to be able to tell the game which item is ours. We do this by defining an identifier for our item. + +An identifier is a name unique to this item. For a vanilla minecraft egg it's identifier is `minecraft:egg`. An identifier is made of two parts, + +- The namespace (`minecraft`) +- The id (`egg`) + +The namespace is unique to your addon and you will use it throughout the project. This is to reduce issues if someone adds two packs to your game which both add an ectoplasm item; the namespace reduces the chance of the identifier being the same. +The namespace that Minecraft use is `minecraft`. Your namespace should be unique to you, for example the authors initials or an abbreviation of the pack name. We will use the namespace `wiki` in our example; for more information on making a namespace check out our page [here](/concepts/namespaces). + +The id is an informative shorthand name for your item. Here we will use `ectoplasm`. + +Together our custom identifier becomes `wiki:ectoplasm`. Note that we use a colon, `:`, to spilt the namespace and id. When we want to reference our item we will use this identifier, for example using the `/give` command. + +### Item File + +Now that we have our components and identifier, we can now start defining our item. We define an item by creating an item definition file in our behavior pack. This is where all our information will go. + +All item definitions go in `BP/items/`. The name of your file doesn't affect anything, but for ease of navigation it's recommend to name it after your id. +We will create a file `BP/items/ectoplasm.json`. Here is the the basic layout of the file: + +BP/items/ectoplasm.json + +```json +{ + "format_version": "1.16.100", + "minecraft:item": { + "description": {...}, + "components": {...} + } +} +``` + +Most files in your pack will have 2 top level definitions, `"format_version"` and `"minecraft:"`. +The format version defines which version of the Addon system Minecraft will use to read this file. For our item, we will be using `1.16.100` to allow us to use the experimental features. For more information on format version you can check [here](/guide/format-version). + +The second definitions defines what kind of file this is. In our case, as this is an item definition, it is `minecraft:item`. Under this is where we will put all our information. This will always contain a `description` key. + +Let us look closer at the `"description"`: + +ectoplasm.json/minecraft:item/ + +```json +"description": { + "identifier": "wiki:ectoplasm", + "category": "Items" +}, +``` + +The description key contains the `identifier` and any other information required. The `identifier` allows the file to know which item to apply the components to. +The `category` key defines which tab of the creative inventory the item would show up in. There are four tabs to choose from: `"Nature"`, `"Equipment"`, `"Construction"` and `"Items"`. If this key is not included, then the item will not show in the creative inventory, but you can still get the item by using `/give`. + +Now we can actually define the behavior of our item, under `components`. Here we simply place any components we want our item to have. +This will be our `"minecraft:max_stack_size"` component. For other components you can use, check out our more in depth guide on Items [here](/items/item-components). + +ectoplasm.json/minecraft:item/ + +```json +"components": { + "minecraft:max_stack_size": 16 +} +``` + +With that, we have now fully defined our item's behavior. This is what your file should currently look like. + +BP/items/ectoplasm.json + +```json +{ + "format_version": "1.16.100", + "minecraft:item": { + "description": { + "identifier": "wiki:ectoplasm", + "category": "Items" + }, + "components": { + "minecraft:max_stack_size": 16 + } + } +} +``` + +If you open a world with your addon, your item should be in the correct menu but invisible and have a strange name. + +This is because we haven't defined the visuals yet. However, you should see that it does stack as expected. In the next section, we will define the items texture and assign it to our item. + +## Item Visuals + +Now that we have an item that works, we want to add a texture and name to it. + +Textures are stored in the resource pack under `RP/textures` as images. In order for Minecraft to know which texture to use where, we need to assign a shortname to it, so we can access it. + +### Texture + +To start we need a texture for our item. For our ectoplasm, we will be using this image. + +![ectoplasm.png](https://raw.githubusercontent.com/Bedrock-OSS/wiki-addon/86b0380310d3d5748a43a4be1f93d4c59668e4bf/guide/guide_RP/textures/items/ectoplasm.png) + +Download texture here + +All item textures are stored in `RP/textures/items/`. From here, you can create any subdirectories you wish. +It's best to name your texture image files with the items' _id_, in our case it will be `ectoplasm.png`. +It is recommended to have your images in `.png` format and be of size `16x16`, though Minecraft will accept other formats such as `.jpg` or `.tga`. + +Your folder layout should look like this: + + + +### Shortname + +A shortname is essentially a name that is assigned to the folder path of the texture, so whenever we want to use a texture somewhere, we will use its shortname instead of its folder path. + +All item shortnames are stored in one file called `item_texture.json` which is in `RP/textures`. This contains a list of shortnames and its assigned textures. + +RP/textures/item_texture.json + +```json +{ + "resource_pack_name": "Ghostly Guide", + "texture_name": "atlas.items", + "texture_data": {...} +} +``` + +Here we have 3 top level definitions, `texture_data` is where we will define our shortnames, the other two define the type of file this is. +The `resource_pack_name` is simply our resource pack's name and `texture_name` is what kind of texture file this is. Since this is for _items_, this will always be set to `atlas.items`. + +Under `texture_data` will our list of item shortname definitions. An example definition looks like this: + +RP/textures/item_texture.json/texture_data + +```json +"wiki.ectoplasm": { + "textures": "textures/items/ectoplasm" +} +``` + +Here `wiki.ectoplasm` is our shortname and under `textures` we have the path to our item. Notice that this is relative to the resource pack, and does not include the file extension. Your shortname should be short and unique. We recommend setting it as the namespace and id for the item we are assigning it to. + +Now whenever we want to refer our image, we will use the shortname `wiki.ectoplasm`. + +### Icon + +To finally apply our texture to our item, we add the `minecraft:icon` component to our item definition and set its value to our shortname. + +ectoplasm.json/minecraft:item/ + +```json +"components":{ + "minecraft:max_stack_size": 16, + "minecraft:icon" : { + "texture": "wiki.ectoplasm" + } +} +``` + +Now your texture should appear on your item. + +### Item Name + +The last thing to add is a nice name to your item. Currently it will look like `item.wiki:ectoplasm`. This is the translation key for your item name, and it is used to allow for [localization](/concepts/text-and-translations). To set it, we just have to define it in our language files. + +We already created these files when making our `RP` and `BP`, so we just need to add to them. + +RP/texts/en_US.lang + +``` +item.wiki:ectoplasm=Ectoplasm +``` + +Now when you enter your world, your item should have a name. + +## Overview + +Now your first custom item, Ectoplasm, is complete! If everything has been done correctly, the item should now be obtainable through the `/give` command in-game, as well as appearing in your creative inventory. + +Your folder structure should look like this: + + + + +BP/items/ectoplasm.json + +```json +{ + "format_version": "1.16.100", + "minecraft:item": { + "description": { + "identifier": "wiki:ectoplasm", + "category": "Items" + }, + "components": { + "minecraft:max_stack_size": 16, + "minecraft:icon": { + "texture": "wiki.ectoplasm" + } + } + } +} +``` + + + + +RP/textures/item_texture.json + +```json +{ + "resource_pack_name": "Ghostly Guide", + "texture_name": "atlas.items", + "texture_data": { + "wiki.ectoplasm": { + "textures": "textures/items/ectoplasm" + } + } +} +``` + + + +If you're having some trouble, check the [Troubleshooting page](/items/troubleshooting-items). If that doesn't help, compare your results with the [example files](https://github.com/Bedrock-OSS/wiki-addon/tree/main/guide). + +## Your progress so far + + + +- [x] Setup your pack +- [x] Create a custom item +- [x] How to format the behavior and resource files for an item +- [x] What components are and how to use them +- [x] How to set an items texture +- [ ] Create a custom entity +- [ ] Create the entity's loot, spawn rules, and a custom recipe + + diff --git a/docs/wiki/guide/download-packs.md b/docs/wiki/guide/download-packs.md new file mode 100644 index 00000000..d7f6243e --- /dev/null +++ b/docs/wiki/guide/download-packs.md @@ -0,0 +1,33 @@ +--- +title: Download Example Packs +category: Extra +description: Appendix for downloading example Packs +prefix: 'b. ' +nav_order: 2 +show_toc: false +mentions: + - SirLich + - Joelant05 + - Dreamedc2015 + - sermah + - SmokeyStack + - MedicalJewel105 + - Luthorius + - TheDoctor15 + - TheItsNameless +--- + +::: tip +This is an appendix page. You can start the guide from the beginning [here](/guide/index). +::: + +To get the most out of the guide, you should always attempt all guide-exercises yourself! However if you get very stuck, the example packs should give you some valuable reference material. + +Download here: + +Download Add-On + +To install, simply unzip the behavior pack into the Minecraft folder: `com.mojang\development_behavior_packs` or `com.mojang\development_*_packs`, depending on which pack you downloaded. diff --git a/docs/wiki/guide/format-version.md b/docs/wiki/guide/format-version.md new file mode 100644 index 00000000..52005aec --- /dev/null +++ b/docs/wiki/guide/format-version.md @@ -0,0 +1,110 @@ +--- +title: Format Versions +category: Extra +description: How to work with Format Versions +prefix: 'e. ' +nav_order: 5 +mentions: + - SirLich + - SmokeyStack + - ThomasOrs + - Xterionix +--- + +Format versions are an important part of Minecraft: Bedrock Edition's Addon System. They appear at the top of most files, formatted like this: `"format_version": "1.16.100"`. You can think of this as the "version number" of the file, and the number you select here is really important! The format version you select will define which syntax and features are available to you, in that particular file. + +:::tip +Selecting the wrong format version is a common source of errors. When troubleshooting, people may ask you questions like 'what format version is your item'. Ensure that you know how to answer that question. +::: + +## Why do format versions exist? + +Format versions exist to *version* the Addon system, and allow Minecraft to introduce new features into the addon system, without breaking old Addons. For example, a `1.8.0` format version RP Entity file has very different syntax than a `1.10.0` format version RP Entity file. By using the 'format_version' key in the json *you* can decide which version you want to use. + +By using format versions *per file*, Minecraft gives you a lot of control over how your addon will be interpreted by the game. It is completely possible and expected to mix different format versions in your addon. + +## Experimental Format Versions + +Format versions are also used for the purpose of versioning experimental features. Since Minecraft releases bedrock experiments directly into stable, some format versions will be 'locked' under experimental, unless you toggle the correct experiment. + +A well known example is the item/blocks system, where `1.16.100` denotes experimental, and `1.10.0` denotes stable. If you want to make an item, it's important to select a format version early, as it will effect everything else you add to the files. If you are going with an experimental format version for your item/block you may want to go higher than `1.16.100` because some experimental features won't work properly in that format version, for example if you are making a custom spawn egg and you want it to be able to set the entity type of a monster spawner, then you need to the format version to `1.19.80` or higher. + +## Format Version is not Game Version + +It is really important to understand that format version is *per subsystem*, and is generally not equal to the base game version. This simply means that every type of file (item, rp entity, bp entity, recipe) will use a different versioning system. + +For example: `"format_version": "1.8.0"` in an RP entity file means "use version `1.8.0` of the *item system*". It does *not* mean "use version `1.8.0` of the *addon system*". + +For this reason, some file types will have very "old" format versions. Do not be tempted to replace this version with the latest game version, such as `1.17.0`. + +## Format Version Fixing + +Minecraft has a system that will "fix" your format version if you've written it wrong. This system isn't well understood, isn't enabled for all systems, and shouldn't be relied upon. But it's important to note that an incorrect format version will often "regress" downwards until it hits a valid format version. For example a `1.11.0` RP entity file will simply be interpreted as `1.10.0`, and cause no errors. + +This system is useful, as it means you are less likely to generate a broken file, by selecting the wrong format version. + +## Picking a Format Version + +Generally speaking, there is a cool tricky to pick the correct format version, for any file type. + +For example, imagine you are creating a Recipe file: + + 1) Install the [Vanilla Packs](/guide/download-packs). + 2) Look at some recipe files, to judge which format version is most used, or the most recent + 3) Use this format version in your file + +This simple trick will help you select a valid format version for your file. + +## Format Versions per Asset Type + +This section will list the format versions used in the vanilla game, alongside how many times it appears. + + - The '⭐' is the recommended *stable* version. + - The '🚀' is the recommended *experimental* version, where applicable. + +### Resource Pack + +| Resource Pack | Version | Count | +|----------------------|----------|-------| +| Entity | 1.10.0 ⭐ | 82 | +| Entity | 1.8.0 | 74 | +| Animation Controller | 1.10.0 ⭐ | 56 | +| Animation | 1.8.0 | 120 | +| Animation | 1.10.0 ⭐ | 6 | +| Attachables | 1.10.0 ⭐ | 29 | +| Attachables | 1.8.0 | 25 | +| Attachables | 1.10 | 1 | +| Models | 1.8.0 | 92 | +| Models | 1.12.0 | 19 | +| Models | 1.10.0 | 4 | +| Models | 1.16.0 | 7 | +| Particles | 1.10.0 ⭐ | 131 | +| Render Controllers | 1.10.0 ⭐ | 83 | + +### Behavior Pack + +| Category | Version | Count | +|-------------|------------|-------| +| Entities | 1.8.0 | 2 | +| Entities | 1.16.210 | 1 | +| Entities | 1.13.0 | 7 | +| Entities | 1.16.0 ⭐ | 58 | +| Entities | 1.16.100 | 3 | +| Entities | 1.12.0 | 21 | +| Entities | 1.17.20 | 7 | +| Entities | 1.17.10 | 4 | +| Entities | 1.10.0 | 1 | +| Entities | 1.14.0 | 1 | +| Items | 1.10 ⭐ | 44 | +| Items | 1.16.0 | 1 | +| Items | 1.16 | 1 | +| Items | 1.14 | 1 | +| Items | 1.16.100 🚀 | 0 | +| Items | 1.19.80 | 0 | +| Items | 1.20.40 | 0 | +| Recipes | 1.12 | 991 | +| Recipes | 1.16 ⭐ | 194 | +| Recipes | 1.14 | 2 | +| Spawn Rules | 1.8.0 ⭐ | 48 | +| Spawn Rules | 1.17.0 | 1 | +| Spawn Rules | 1.11.0 | 1 | diff --git a/docs/wiki/guide/index.md b/docs/wiki/guide/index.md new file mode 100644 index 00000000..c357f89e --- /dev/null +++ b/docs/wiki/guide/index.md @@ -0,0 +1,13 @@ +--- +title: Beginners Guide +nav_order: 1 +categories: + - title: Guide + color: green + - title: Extra + color: blue +--- + +Welcome to the Bedrock Beginners Guide! + +Get Started! diff --git a/docs/wiki/guide/introduction.md b/docs/wiki/guide/introduction.md new file mode 100644 index 00000000..817c6852 --- /dev/null +++ b/docs/wiki/guide/introduction.md @@ -0,0 +1,60 @@ +--- +title: Introduction +category: Guide +description: Introduction to our "Getting Started" Guide +tags: + - guide +nav_order: 1 +prefix: '1. ' +mentions: + - KaiFireborn + - SirLich + - BlueFrog130 + - sermah + - SmokeyStack + - TheItsNameless + - MedicalJewel105 + - smell-of-curry + - Hatchibombotar + - retr0cube +--- + +## What are Addons? + +An "Addon" is the Minecraft Bedrock Edition (_Windows 10, iOS, Android, Consoles_) equivalent to Java mods. However, in contrast to Java, the Bedrock Edition API is officially maintained by Mojang instead of the community. + +In general, you can think of _mods_ as _modifying_ the game, and _addons_ as _adding onto_ the game, following the development opportunities provided by Microsoft. + +## What is this guide? + +This guide is a beginner tutorial, intended to walk you through the first stages of addon-creation. You will create your very own fully-functional Ghost entity, as well as an Ectoplasm item, and some other associated files. + +By the end of this guide, you will have created an entire addon all by yourself, which you can play with and modify! + +In this guide you will find boxes like these: +:::tip +Some very helpful information! +::: +:::warning +Attention! Watch out for these common mistakes. +::: +Watch out for these boxes! They contain very important information that could help you with problems. + +## Is the guide up to date? + +This guide is written for the most recent _stable_ release of Minecraft Bedrock Edition. Many things won't work in previous versions, and some will be changed in later ones. We will keep the guide as up-to-date as possible, so no need to worry. + +## Appendix Pages + +Alongside the step-by-step guide, we have a few other files here, which may be interesting to you: + +- [Understanding JSON](/guide/understanding-json) +- [Downloading Example Packs](/guide/download-packs) +- [Troubleshooting](/guide/troubleshooting) + +## What to do after finishing the Guide + +At the end of the guide section, your first addon will be done! To further expand your knowledge, consider doing these: + +- Start your project! +- To dive into the other aspects of adding onto MCBE (Minecraft Bedrock Edition), you can use the different sections' sub guides listed in the Appendix. This includes but is not limited just to custom Blocks, Biomes, advanced Items, Animation Controllers, and even JS scripts. Some sections provide more technical in-depth tutorials and documents for each relevant topic. diff --git a/docs/wiki/guide/loot-table.md b/docs/wiki/guide/loot-table.md new file mode 100644 index 00000000..7585f6fe --- /dev/null +++ b/docs/wiki/guide/loot-table.md @@ -0,0 +1,179 @@ +--- +title: 'Adding a Loot Table, a Spawn rule and a crafting recipe' +category: Guide +description: How to add your first Loot Table, Spawn Rule and Crafting Recipe +nav_order: 8 +prefix: '8. ' +mentions: + - KaiFireborn + - SirLich + - sermah + - cda94581 + - Ultr4Anubis + - TheItsNameless + - Ciosciaa + - MedicalJewel105 + - ChibiMango + - FrankyRay +--- + +Next, we'll enhance the custom Ghost entity by adding some more basic mechanics to it: + +## Loot tables + +First, we'll make the ghost drop Ectoplasm upon death: create the following file: + +BP/loot_tables/entities/ghost.json + +```json +{ + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "wiki:ectoplasm", + "weight": 1, + "functions": [ + { + "function": "set_count", + "count": { + "min": 1, + "max": 3 + } + } + ] + } + ] + } + ] +} +``` + +- Loot Tables consist of `"pools"`. Each pool defines a different loot. A pool consists of 3 parts, `"rolls"`, `"entries"` and `"conditions"`. The `"conditions"` are optional and won't be covered in this guide. To learn more about conditions, look at [Loot Tables](/loot/loot-tables). +- The `"rolls"` section defines how many times a random entry will be chosen from the following `"entries"`object. +- The `"entries"` part defines the items, from which the loot table can choose. Each roll a new item will be chosen. +- `"type"` defines what will be chosen. You can set it to `"item"` or `"loot_table"` to either chose an item or an different loot table. +- `"name"` will be set to an item identifier with its namespace. It defines which item will be selected. +- `"weight"` is optional and defines how likely it is, that this item will be selected. If there is more than one item in the `"entries"` section, the `"weight"` attribute can be used to make the probability of one item more or less likely. If it isn't set, it defaults to 1. +- `"functions"` provide a powerful way of customizing the item that will be returned. They can add enchantments to an item, setting an items' name or simply setting the number of items that will be dropped. To define the number of items, we use `"set_count"`. It takes the `"count"` attribute, which sets the maximum and minimum amount of items that will be dropped. + +For more information on loot tables, see our extended guide: [Loot Tables](/loot/loot-tables)! + +## Spawn rules + +Next, we'll make the ghost spawn in deserts at night: + +BP/spawn_rules/ghost.json + +```json +{ + "format_version": "1.8.0", + "minecraft:spawn_rules": { + "description": { + "identifier": "wiki:ghost", + "population_control": "monster" + }, + "conditions": [ + { + "minecraft:spawns_on_surface": {}, + "minecraft:brightness_filter": { + "min": 0, + "max": 7, + "adjust_for_weather": true + }, + "minecraft:difficulty_filter": { + "min": "easy", + "max": "hard" + }, + "minecraft:weight": { + "default": 80 + }, + "minecraft:herd": { + "min_size": 1, + "max_size": 3 + }, + "minecraft:biome_filter": { + "test": "has_biome_tag", + "operator": "==", + "value": "desert" + } + } + ] + } +} +``` + +- You already know what `"format_version"`does. +- Inside the `"minecraft:spawn_rules"` part we define our spawn rules. +- The `"description"` defines the basic properties of the file. The `"identifier"` is used to define on which entity this spawn rule applies on. `"population_control"` is used to limit the amount of entities that will be spawned. Once the pool that is defined inside of `"population_control"` is full, no more entities will be spawned. +- With `"conditions"` we can define rules that limit the spawning of this entity to special cases. We will shortly describe each condition used here, but you can learn more conditions and how to use them [here](/entities/vanilla-usage-spawn-rules). + - `"spawns_on_surface"` allows the mob to only spawn on surfaces. + - `"minecraft:brightness_filter"` limits the spawning to areas with a lighting level thats between the defined values. If `"adjust_for_weather"` is `true`, the light level decrease during rain and storms will be ignored. + - `"minecraft:difficulty_filter"` defines the difficulty level needed to spawn the entity. + - `"weight"` defines how often this entity will spawn. The higher this value, the more often the mob will spawn. + - `"minecraft:herd"`defines how many entities will be spawned at once. + - With `"minecraft:biome_filter"` we define the biomes in which the entity is able to spawn. + +To learn more about spawn rules, take a look on our guide on [Vanilla spawn rules](/entities/vanilla-usage-spawn-rules). + +## Crafting recipes + +And finally, as an introduction to recipes, we'll make the Ectoplasm craftable into Slime Blocks: + +BP/recipes/ectoplasm_slime_blocks.json + +```json +{ + "format_version": "1.12.0", + "minecraft:recipe_shaped": { + "description": { + "identifier": "wiki:ectoplasm_slime_block" + }, + "tags": ["crafting_table"], + "pattern": ["###", "###", "###"], + "key": { + "#": { + "item": "wiki:ectoplasm" + } + }, + "result": { + "item": "minecraft:slime" + } + } +} +``` + +- `"format_version"` is already known. +- With `"recipe_shaped"` we define, that each ingredient has a set place in the crafting grid. There are some other types that can be used, you can find more information [here](/loot/recipes). +- Inside `"description"` we define the `"identifier"` of this recipe, which is the name of the recipe. +- `"tags"` is a list of benches (crafting table, furnace, etc) that are able to use this recipe. After version b1.16.100 it was possible to use custom benches, created by an addon. +- `"pattern"` defines the arrangement of the items inside the crafting grid. Each `#` represents the item that is set under `"key"`. In this case, the whole 3x3 grid has to be filled with `"wiki:ectoplasm"`, our own item. It is possible to define more items, just add an entry to `"key"` and set the key to a character, that you can use inside `"pattern"`. +- `"result"` contains an `"item"`, which is set to the item that will be the output of this recipe. + +For more information on this topic, visit our page about [recipes](/loot/recipes)! + +## What you have learned + +:::tip What you have learned: + +- How to create a loot table and define which items a mob is able to drop +- How to set the rules for a mob to spawn +- How to create new crafting recipes +::: + +## Your progress so far + +**What you've done:** + + + +- [x] Setup your pack +- [x] Create a custom item +- [x] Create a custom entity +- [x] Create the entity's loot, spawn rules, and a custom recipe + + + +Congratulations! you have finished the Guide and created your first Add-on. 🎉 diff --git a/docs/wiki/guide/project-setup-android.md b/docs/wiki/guide/project-setup-android.md new file mode 100644 index 00000000..c64dcc90 --- /dev/null +++ b/docs/wiki/guide/project-setup-android.md @@ -0,0 +1,261 @@ +--- +title: Project Setup Android +category: Guide +description: How to setup your project on Android +mentions: + - Etanarvazac + - MedicalJewel105 + - TheItsNameless + - ThomasOrs +hidden: true +--- + +## Tools + +It is not easy to find good apps to make add-ons for android platform, but we tried our best and collected Google Play apps for you. +For development on Android, you'll need a combination of 3 applications. + +1. A file manager that can create ZIP archives if your device is running Android 12 or newer. +2. A code editor (any text editor will work, but only code editors will show syntax highlights). +3. An image editor (no device comes with a editor that can go down to the pixels). + +### File Managers + +These file managers are known to have ZIP archiving and view-only access to the `Android/data` folder: + +1. [**X-Plore**](https://play.google.com/store/apps/details?id=com.lonelycatgames.Xplore) - a powerful file manager with dual-pane tree view, a built-in text editor (not code), several file compression formats (ZIP, 7zip, RAR, etc.), and more. On rooted devices, X-Plore has edit access to `Android/data` and root directories. +2. [**Total Commander**](https://play.google.com/store/apps/details?id=com.ghisler.android.TotalCommander) - not as powerful out of the box compared to X-Plore, but contains some of the same features including dual pane, ZIP and RAR archives, and view-only access to `Android/data`. Total Commander has list view instead of tree and many other features that require plugins (apps from Google Play) to use. + +### Code Editors + +1. **Acode:** [Free version](https://play.google.com/store/apps/details?id=com.foxdebug.acodefree) comes with ads that can be toggled off without paying. Supports GitHub integration using a Personal Access Token, FTP/SFTP, syntax highlighting for over 100+ languages including JSON, tab-view for multi-file editing, dozens of themes, and more. This app is open source and does have a [paid version](https://play.google.com/store/apps/details?id=com.foxdebug.acode) that allows a much deeper theme customization. + +:::info +Acode is the only powerful code editor actively being developed on Android at this time. Other editors are very limited or have been abandoned long enough to vanish from the Google Play store. If you know of a code application, you can contribute to this guide. +::: + +### Image Editors + +1. [**Pocket Paint**](https://play.google.com/store/apps/details?id=org.catrobat.paintroid) - lightweight editor with the bare minimum features needed for any add-on creation. This app is easy to use and allows importing other images over others. Saves in JPG (compressed), PNG (lossless, with transparency), and ORA (multi-layer images). This app is open source. +2. [**Pixly**](https://play.google.com/store/apps/details?id=com.meltinglogic.pixly&hl=en) - very lightweight, no ads or in app purchases. Plentiful tools and customizable brushes, ability to save palettes internally or externally. +3. [**Pixel Art editor**](https://play.google.com/store/apps/details?id=net.spc.app.pixelarteditor&hl=en) - a simple lightweight app. Would be the best if you need just to draw some texture-placeholder. + +## Your Workspace + +:::tip +In this version of the guide, "BP" refers to your behaviour pack folder and "RP" refers to your resource pack folder in your workspace. For locations in files or directories, `../` indicates "From last location" followed by the added space (e.g.: `/one/two/three/file.txt` would be shortened to `../three/file.txt`) + +If your device is rooted, you can follow the main project setup using the `/Android/data/com.mojang.minecraftpe/files/games/com.mojang` development behaviour and resource pack folders directly. Otherwise, follow the steps below. +::: + +Before we begin, you need a workspace. Using your file manager, navigate to your Internal Storage (In most cases, it's `/`. In others, the full path (e.g.: `/storage/emulated/0/`) is displayed. Both are acceptable.) and create a folder that will contain your packs. For this example, our full directory is `/Minecraft Packs/MyFirstAddon`. From there, you'll need one folder for both your behaviour and resource packs (e.g.: `../MyFirstAddon/addonBP` and `../MyFirstAddon/addonRP`). + +Now that you have the workplace setup, code editors should have a way for you to open a folder as a workplace. In this guide, we'll be walking through Acode. + +1. Open Acode. +2. Tap the file browser button (3 bars in the top-left), followed by "Open folder" +3. Tap "Add a storage", followed by "select folder" +4. This should have opened your device's file browser. Navigate to the _main_ folder for your projects (for us, `/Minecraft Packs`) then tap "Use this folder". If your device asked you to allow Acode access, tap "Allow". +5. You should be back in Acode now. Tap "OK" and your folder should now be in the list. Tap on it and then "Select Folder" on the bottom of the screen. +6. Now when you open the file browser (3 bars in top-left), you should see your folder in the list. You now have quick access to your addon's behaviour and resource pack folders. The file browser uses tree view to display your active workspace. + +:::tip +You can create new files and folders inside your packs from the file browser by tapping and holding on the folder you want to create the item in. +::: + +## BP & RP Manifests + +:::warning +From here on out, all files and folders have very specific names unless otherwise noted. Wrongly named files and/or folders are a common reason of an error. Please ensure you're checking your work carefully in accordance to the examples provided. If a file or folder mentioned has not yet been created, please create it in it's appropriate directory. + +When creating a new file in a file manager or some text or code applications, the `.txt` extension is added automatically to the end of the file name. To ensure our files work as intended, be sure to remove `.txt`. Like names, the wrong file extension is also a common reason of an error. If you're using Acode, you'll notice `untitled.txt` is completely highlighted instead of just `untitled`. This is a common practice for naming programming language files. +::: + +The manifest file is the file Minecraft uses to identify your packs. Every pack has one (and only one) manifest. A folder with a correctly formatted manifest will show up in Minecraft. Before we begin adding content, we will ensure our "minimal" pack is visible. Manifests are written in the `JSON` programming language. If you're unfamiliar with JSON, you can learn more about it [here](/guide/understanding-json). + +Create a new text file in your addon's behaviour pack folder called `manifest.json`. To begin, copy and paste the following code into the `manifest.json` file. A full breakdown of the manifest file is provided after creating these files. + +BP/manifest.json + +```json +{ + "format_version": 2, + "header": { + "name": "pack.name", + "description": "pack.description", + "uuid": "...", + "version": [0, 0, 1], + "min_engine_version": [1, 16, 0] + }, + "modules": [ + { + "type": "data", + "uuid": "...", + "version": [0, 0, 1] + } + ] +} +``` + +Now create another `manifest.json` file in your addon's resource pack folder. Again, copy and paste the following code inside the new file. + +RP/manifest.json + +```json +{ + "format_version": 2, + "header" { + "name": "pack.name", + "description": "pack.description", + "uuid": "...", + "version": [0, 0, 1], + "min_engine_version": [1, 16, 0] + }, + "modules": [ + { + "type": "resources", + "uuid": "...", + "version": [0, 0, 1] + } + ] +} +``` + +## Manifest Breakdown + +- `format_version` defines the version the syntax your manifest is written in. Version 2 is the most recent stable version. Always use this version. +- `name` is name of your pack. We will be defining the this in "code form" later so they can easily be translated into other languages, should you create a pack with multiple languages. +- `description` is a short description about your pack that will show up under the `name` in-game. This will also be defined later in "code form". +- `uuid` is required to help identify your pack from other packs and will have a breakdown of it's own below. Once explained, you'll need to replace all of the `...` with them. +- `version` is literally the version of your addon. Upon completing your addon, you can always change this to `[1, 0, 0]`. However, it'll be easier to use the hotfix spot while making your changes on mobile. +- `min_engine_version` tells Minecraft what the minimum version it needs to be in order for your pack to work. For example, if your pack has a crafting recipe that involves concrete, your pack can't run on Minecraft 1.5 because concrete doesn't exist in that version. +- Under `modules`, you have the `type` field. This tells Minecraft what your pack is. So `data` in your BP tells the game that pack is a behaviour pack and `resources` in your RP tells the game that pack is a resource pack. + +## UUID Breakdown + +A UUID, or **U**niversally **U**nique **ID**entifier, both identifies your pack for other programs (Minecraft, for example) and separates your pack from someone else's pack for the program it's for. A version 4 UUID (UUID-4) is usually in the format `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` and made of a random string of letters and numbers. For example: `5c830391-0937-44d6-9774-406de66b6984`. + +You should **NEVER** use the same UUID twice! Use the [Online UUID Generator Tool](https://www.uuidgenerator.net/version4) to generate the UUID's needed for your manifest files. Every manifest file uses two different UUID's. So to ensure your packs will work correctly, get 4 different UUID's to replace all of the `...` in both manifests. When finished, each UUID entry should look similar like this: `"uuid": "5c830391-0937-44d6-9774-406de66b6984` + +## Pack Icon + +Notice how other packs have a icon? It's a image file which can quickly identify how your addon will appear in-game. Got a low-resolution square image as a PNG? You can use it! Otherwise, you can use this example icon. + + + +Download Image + +You must place a copy of your desired image in both the behaviour and resource packs. In order for the image to be read correctly, the name must be `pack_icon.png`. + +## Language Files + +Remember when we said we'll define the pack name and description in code form earlier? Now is that time as it's the last thing we need to do to setup your addon. You will need to create 4 new files and 2 new folders (2 files and 1 folder for each pack). You can You can learn more about how Minecraft handles localization [here](/concepts/text-and-translations). You can also format your definitions using the `§` symbol. You can view a list of colors and formats [here](https://htmlcolorcodes.com/minecraft-color-codes/). If you use any formatting, make sure you `§r`eset when changing formats: `§kl My pack l` will render "My pack" unreadable whereas `§kl §rMy pack §kl` can be read properly. + +BP/texts/en_US.lang + +``` +pack.name=§2My §lFIRST §r§2Addon's Behaviour Pack! +pack.description=This addon is made by a Wiki Contributor! +``` + +BP/texts/languages.json + +```json +["en_US"] +``` + +RP/texts/en_US.lang + +``` +pack.name=§2My §lFIRST §r§2Addon's Resource Pack! +pack.description=This addon is made by a Wiki Contributor! +``` + +RP/texts/languages.json + +```json +["en_US"] +``` + +## Importing Your Addon + +Now that your addon has all of the required content, we need to import it to Minecraft. To do this, we need to create a file with the extension `.mcaddon`. + +1. Open your preferred file manager and navigate to the folder containing your behaviour and resource packs. +2. Using multi-select, select both packs and create a ZIP file. +3. When asked for the name of the file, ensure that `.zip` is changed to `.mcaddon`. + ![](/assets/images/guide/project-setup-android/zip-addon.png) +4. When your file manager finishes, it should be a `MCADDON` file with Minecraft as it's icon. Tapping on this file should launch Minecraft. + +If done correctly, Minecraft will display a banner for both packs. First is `Importing...`. After should be `Successfully imported ""`. You can also go to `Settings > Storage` if you don't see the import messages to verify your packs were imported. If you do not see either pack, check out our [troubleshooting guide](/guide/troubleshooting). + +## Turn on Content Log + +:::warning +Content log is the most useful tool you have for debugging your addons. Please do not skip this step. +::: + +![](/assets/images/guide/content_log.png) + +Content Log is an extremely important debugging tool, which you should always have on. + +Turn on both content log settings in `settings > creator`. This will show you any errors in your add-on when you enter a world with it applied. You can also open the content log GUI in-game by pressing `ctrl+h`. Learn more about the content log [here](/guide/troubleshooting). + +## Creating your testing world + +Now we create a world to test your new add-on! + +1. Click "**Create new world**"; + +2. Ensure that the following settings are set. + + ![](/assets/images/guide/project-setup/settings_1.png) + ![](/assets/images/guide/project-setup/settings_2.png) + +3. Now activate your behavior pack, and your resource pack. You can do this by selecting the packs, and clicking 'apply'. + +4. Now click '**Create**'! + +## Final Notes + +**Here is how your project should look, after completing this page:** + +Remember that in future, we will represent `com.mojang/development_behavior_packs/guide_RP/` as `RP`, and `com.mojang/development_behavior_packs/guide_BP/` as `BP`. + + + +## What you have learned + +:::tip What you have learned: + +- What and where your `com.mojang` folder is and what it contains +- How to setup your mobile workspace +- What a `manifest.json` file is +- What are UUID's and how to use them +- How to create icons for your addons +- What a `.lang` file is + +::: + +## Your progress so far + + + +- [x] Setup your pack +- [ ] Create a custom item +- [ ] Create a custom entity +- [ ] Create a custom block + + diff --git a/docs/wiki/guide/project-setup.md b/docs/wiki/guide/project-setup.md new file mode 100644 index 00000000..f90ff437 --- /dev/null +++ b/docs/wiki/guide/project-setup.md @@ -0,0 +1,300 @@ +--- +title: Project Setup +category: Guide +description: How to setup your project +nav_order: 4 +prefix: '4. ' +mentions: + - SirLich + - sovledDev + - Joelant05 + - Dreamedc2015 + - BlueFrog130 + - sermah + - cda94581 + - MedicalJewel105 + - TheItsNameless + - ThijsHankelMC + - TheHyperWhale + - stirante + - ChibiMango + - Etanarvazac + - retr0cube + - ThomasOrs + - lescx +--- + +## The com.mojang folder + +The `com.mojang` folder is a special folder where Minecraft stores data (Addons, Worlds, Player info...). Minecraft understands this location, and all files we access or create will be placed somewhere in this folder! + +You should create a shortcut to the `com.mojang` folder on your Desktop or on your mobile device, so you can easily access it at any time. The exact location of the `com.mojang` folder will depend on your device OS. + +### Windows + +_Tip: You can type %appdata% into the searchbar to jump directly into the 'C:\Users\USERNAME\AppData\' folder._ + +`C:\Users\USERNAME\AppData\Local\Packages\Microsoft.MinecraftUWP_8wekyb3d8bbwe\LocalState\games\com.mojang` + +### Android + +Android 11 or older: `Phone > games > com.mojang` + +Android 12 and newer: `Phone > Android > data > com.mojang.minecraftpe > files > games > com.mojang` + +### ChromeOS + +Before you can see the `com.mojang` in your files, make sure to change the `File Storage Location` to `External` in your Minecraft Settings: + +- Go to `Minecraft Settings`. +- Navigate to `Settings > General > Storage`. +- Change the `File Storage Location` to `External`. + +After that you can access the `com.mojang` folder in your Android Subsystem: + +`My Files > Play Files > Android > data > com.mojang.minecraftpe > files > games > com.mojang` + +### iOS + +`My iDevice > Minecraft > games > com.mojang` + +### Development Packs + +We will develop our addon in `development_behavior_packs` and `development_resource_packs`. When you make changes within these folders, you can _exit and re-enter a world with the packs applied_, to automatically reload the content. This allows you to quickly test your addon without reloading Minecraft. + +`resource_packs` and `behavior_packs` on the other hand contain stable addons, including those imported via `.mcpack`. We can ignore these folders for now. + +## Your Workspace + +:::tip +Project setup is different for android and other platforms. Consider looking into our guide for android platforms. +::: + +Android guide + +:::tip +In this guide, BP refers to the folder you created in `development_behavior_packs` ("the behavior pack"), and RP refers to the folder you created in `development_resource_packs` ("the resource pack") +::: + +First of all, you will need to create the proper folders in suitable locations and set up your workspace. +_The remainder of this guide assumes you are using VSCode. You may also follow along with other editors._ + +Let's create your first add-on workspace in Visual Studio Code now. + +1. Open VSCode (_Visual Studio Code, the code editor_) +2. Create a folder named "`your_pack_name_RP`" in `development_resource_packs`. **I'll refer to this folder as `RP`** +3. Create a folder "`your_pack_name_BP`" in `development_behavior_packs`. **I'll refer to this folder as `BP`**. +4. Go to `File > Add folder to workspace...` and choose `BP`. Do the same with `RP`. +5. Press `File > Save Workspace as...` to save the workspace file to your Desktop. Whenever you're working on your addon, all you have to do is open the workspace by double-clicking, and you will get quick access to both BP and RP folders. + +## BP Manifest + +:::tip +In this guide, you will often be instructed to create files with specific names, placed in specific folders. If the folder doesn't exist yet, please create it! +::: + +:::warning +Wrongly named files/folders is a common source of errors. Please check your work carefully against the examples. +::: + +The manifest is a file that identifies your pack to Minecraft. Every pack has one manifest. A folder with a correctly formatted manifest will show up in Minecraft, and we consider this the "minimal" pack before we can add additional content. + +Manifest files are written in `json`. If this isn't familiar to you, you can learn more about json [here](/understanding-json). + +First, create a new file in your BP folder by right-clicking on the folder and selecting `New File`. Call the file `manifest.json`. To begin, you can copy paste the following code into the file. + +BP/manifest.json + +```json +{ + "format_version": 2, + "header": { + "name": "pack.name", + "description": "pack.description", + "uuid": "...", + "version": [1, 0, 0], + "min_engine_version": [1, 16, 0] + }, + "modules": [ + { + "type": "data", + "uuid": "...", + "version": [1, 0, 0] + } + ] +} +``` + +### Manifest Explained + +- "`format_version`" defines what version of manifest syntax you are using. Version 2 is the most recent stable version; use it. + +- "`name`" is the name of your behavior pack. "`description`" will show up under it in-game. We are defining these files in "code form" so we can translate them later into other languages. For more information about localization, look [here](/concepts/text-and-translations). + +- The "`UUID`" field is **essential**, and will be discussed in more detail below. + +- "`version`" defines the version of your add-on. When you import an add-on with a newer version on a device with an older version installed, the more recent version will overwrite the older one. You don't need to change the version if you have the add-on in `development_*_packs` folders and only use them on private worlds. + +- "`min_engine_version`" defines the minimum Minecraft client version that'll be able to read your add-on. + +- In "`modules`", the "`type`" is defined to be "`data`". This makes your pack a _Behavior Pack_. + +### UUID Explained + +A UUID (_Universally Unique Identifier_) identifies your pack for other programs (in this case, Minecraft) to read. It looks something like this: `5c830391-0937-44d6-9774-406de66b6984` + +**NEVER USE THE SAME UUID TWICE.** You can generate your own UUIDs [here](https://www.uuidgenerator.net/version4) or, if you use VSCode, you can install [this](https://marketplace.visualstudio.com/items?itemName=netcorext.uuid-generator) extension. Many other tools like _bridge._ generate UUIDS automatically. Every manifest file uses two different UUIDs. + +To ensure that your add-on will work correctly you should generate two new UUID's which you will paste into the BP `manifest.json` file, at each `"..."`. When you are finished, it should look something like this: + +`"uuid": "5c830391-0937-44d6-9774-406de66b6984"` + +## RP Manifest + +The next step is to create the `manifest.json` for the RP. The format for a resource-pack manifest is nearly identical to a BP manifests except that the `type` is `resources`, which marks the pack as a _Resource Pack_. + +Copy the following code into your newly created `RP/manifest.json` and insert your own UUIDs. + +RP/manifest.json + +```json +{ + "format_version": 2, + "header": { + "name": "pack.name", + "description": "pack.description", + "uuid": "...", + "version": [1, 0, 0], + "min_engine_version": [1, 16, 0] + }, + "modules": [ + { + "type": "resources", + "uuid": "...", + "version": [1, 0, 0] + } + ] +} +``` + +## Pack Icon + +The pack icon is an image file which identifies how your addon will look in-game. If you have a low-resolution square image, you can use it. Otherwise, download and use this example icon: + + + +Download Image + +You should place a copy of your desired image into both the RP and the BP. The image needs to be named `pack_icon.png` + +## Language Files + +The last thing to do is setup language support for your addon. You will need to create a language file for both the RP and the BP. You can learn more about how Minecraft handles localization [here](/concepts/text-and-translations). + +RP/texts/en_US.lang + +```json +pack.name=Wiki Resource Pack +pack.description=A Ghostly Guide +``` + +BP/texts/en_US.lang + +```json +pack.name=Wiki Behavior Pack +pack.description=A Ghostly Guide +``` + +RP/texts/languages.json + +```json +["en_US"] +``` + +BP/texts/languages.json + +```json +["en_US"] +``` + +## Checking your Work + +If you have done everything correctly, your packs should show up in Minecraft now! If you don't see your pack, you should follow the [troubleshooting guide.](/troubleshooting) + +![](/assets/images/guide/project-setup/active_pack.png) + +## Turn on Content Log + +:::warning +Content log is the most useful tool you have for debugging your addons. Please do not skip this step. +::: + +![](/assets/images/guide/content_log.png) + +Content Log is an extremely important debugging tool, which you should always have on. + +Turn on both content log settings in `settings > creator`. This will show you any errors in your add-on when you enter a world with it applied. You can open the content log GUI in-game by pressing `ctrl+h` or by pressing `Content Log History` in the creator settings panel. Learn more about the content log [here](/guide/troubleshooting). + +## Creating your testing world + +Now we create a world to test your new add-on! + +1. Click "**Create new world**"; + +2. Ensure that the following settings are set. + + ![](/assets/images/guide/project-setup/settings_1.png) + ![](/assets/images/guide/project-setup/settings_2.png) + +3. Now activate your behavior pack, and your resource pack. You can do this by selecting the packs, and clicking 'apply'. + +4. Now click '**Create**'! + +--- + +## Your progress so far + +**Here is how your project should look, after completing this page:** + +Remember that in future, we will represent `com.mojang/development_behavior_packs/guide_RP/` as `RP`, and `com.mojang/development_behavior_packs/guide_BP/` as `BP`. + + + +## What you have learned + +:::tip What you have learned: + +- What the com.mojang folder is, where it is and what folders it contains +- How to setup your workspace +- What a `manifest.json` file is +- How to use UUIDs +- How to create an icon for your addon +- What a `.lang` file is + +::: + +## Your progress so far + + + +- [x] Setup your pack +- [ ] Create a custom item +- [ ] Create a custom entity +- [ ] Create the entity's loot, spawn rules and a custom recipe + + diff --git a/docs/wiki/guide/software-preparation.md b/docs/wiki/guide/software-preparation.md new file mode 100644 index 00000000..75ab1a1f --- /dev/null +++ b/docs/wiki/guide/software-preparation.md @@ -0,0 +1,179 @@ +--- +title: Software and preparation +category: Guide +description: How to setup your developement environment +nav_order: 3 +prefix: '3. ' +mentions: + - SirLich + - Dreamedc2015 + - sermah + - cda94581 + - Joelant05 + - MedicalJewel105 + - TheItsNameless + - TheDoctor15 + - ChibiMango + - profeplaysminecraft + - solvedDev + - retr0cube + - SmokeyStack + - ThomasOrs +--- + +Before you can start creating addons, you first have to install the required tools and applications. While development will be easiest on Windows 10, we have provided mobile alternatives for both Android and iOS, where applicable. + +## Download Minecraft Bedrock Edition + +- [Windows 10](https://www.microsoft.com/en-us/p/minecraft-for-windows-10/9nblggh2jhxj?activetab=pivot:overviewtab) +- [Android](https://play.google.com/store/apps/details?id=com.mojang.minecraftpe&hl=en) +- [iOS](https://apps.apple.com/us/app/minecraft/id479516143) +- [Run MC on Linux](https://discord.gg/VJTZ3KaTx6) + +## Picking an Editor + +Addons can be created using any text editor, however it's much more comfortable to work in a dedicated editor. A good editor can give you code-completion, error-detection, and in-editor documentation. + +There are strong opinions about the best editor for beginners, but generally speaking you cannot go wrong selecting either VSCode, or bridge. If you are mobile, you will need to use a mobile alternative. + +### VSCode + +VSCode is a general purpose text-editor and IDE. With VSCode, you will be able to edit your addons in plain-text, guided along by a powerful array of extensions and addons. VSCode is a great option for programmers and advanced users. + +[⚙️Install VSCode](https://code.visualstudio.com/) + + + +Many packages exist for VSCode that make editing addons easier: + +- [Blockception's Minecraft Bedrock Development](https://marketplace.visualstudio.com/items?itemName=BlockceptionLtd.blockceptionvscodeminecraftbedrockdevelopmentextension) +- [.mcfunction support](https://marketplace.visualstudio.com/items?itemName=arcensoth.language-mcfunction) +- [.lang support](https://marketplace.visualstudio.com/items?itemName=zz5840.minecraft-lang-colorizer) +- [Bedrock Definitions](https://marketplace.visualstudio.com/items?itemName=destruc7i0n.vscode-bedrock-definitions) +- [Prettify-json](https://marketplace.visualstudio.com/items?itemName=mohsen1.prettify-json) +- [Spell Checker (for writing wiki)](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) +- [Snowstorm Particle Editor](https://marketplace.visualstudio.com/items?itemName=JannisX11.snowstorm) +- [UUID Generator](https://marketplace.visualstudio.com/items?itemName=netcorext.uuid-generator) + + + +### bridge. + +[bridge.](https://bridge-core.app/) is a light-weight, dedicated IDE for Minecraft addons. It features [innovative features](https://bridge-core.app/guide/features/) such as [entity and block previews](https://bridge-core.app/guide/features/index.html#file-previews), [rich auto-completions and file validations](https://bridge-core.app/guide/features/index.html#auto-completions-and-validation) and [advanced file creation with presets](https://bridge-core.app/guide/features/index.html#advanced-file-creation). +bridge. includes a regular text editor for experienced addon creators and a tree editor to make it easy for beginners to get started with editing JSON files. + +#### Next Steps +- [Read more on why you should use bridge.](https://bridge-core.app/guide/why-bridge) +- [Read our guide on getting started with bridge.](https://bridge-core.app/guide/index) +- [Try out bridge. online](https://editor.bridge-core.app/) + +### Mobile Editors + +#### Android +- [ACode Editor](https://play.google.com/store/apps/details?id=com.foxdebug.acodefree) +- [bridge. v2](https://bridge-core.app/) + +#### iOS +- [Kodex](https://apps.apple.com/us/app/kodex/id1038574481) +- [bridge. v2](https://bridge-core.app/) + +## Blockbench + +- [Blockbench](https://blockbench.net/) is a 'boxy 3D model editor' typically used to create Minecraft models, textures and animations. Also provides a web-browser version which is compatible with mobile. + +## Image Editors + +When choosing an image editor, it is important to keep in mind that the traditional Minecraft style is composed of simple 16X16 pixelart. There are plenty of powerful and free art programs available for you to use. However, many of these programs have more tools than you will need for Minecraft graphical design and these tools require time to learn. + +:::tip +Choose a program that feels comfortable and easy for you to use. Many Addon creators use different art programs for different tasks. (Example: One might use paint․net for most of the art, and piskel for Minecraft block animations). Choose what works best for you! +::: + +### Krita +Krita is a powerful open-source art programed with the goal of giving free powerful digital art tools to artists. Krita has more than enough features to cover your Minecraft needs and works on a MAC or PC. +**+ Pros:** Plenty of features including a pixel brush with an intuitive user interface. +**- Cons:** Requires a little time to become familar with the tools. + +[Download Krita](https://krita.org/en/) + +### GIMP +Gimp is similar to Krita in that it is a free and open source digital art program that has a vast arrays of tools. Where Krita focuses more on illustration, GIMP focuses more on image manipulation (think Photoshop). Gimp also works on MAC or PC. +**+ Pros:** GIMP has more than enough tools for editing Minecraft art +**- Cons:** The interface is not intuitive. Even though GIMP is powerful, it requires a steep learning curve. + +[Download Gimp](https://www.gimp.org/) + +### Paint․net +Paint․net is a simple yet powerful image editing and art software. Paint․net may not have a vast array of tools like Krita and GIMP, but it does offer simplicity and ease of use. +**+ Pros:** Easy to use and learn. +**- Cons:** Only works on Windows. + +[Download Paint.net](https://www.getpaint.net) + +### Pixilart +Pixilart is a web-based pixel art software. It is extremely simple to use since it is focused on pixel art. It also has a powerful resize option that may come in handy, so that you can resize your art without losing the pixelart details. + +**+ Pros:** Easy to use and learn. Curated specifically for pixel art. +**- Cons:** Must have internet connection. May be missing tools you want. + +[Use Pixilart](https://www.pixilart.com/) + +### Piskel +Piskel is a web-based pixel art software with a focus of making pixelated sprites (or video game character animations). This tool, similar to Pixilart, is simple to use. This is also a great tool for making flipbooks (Minecraft block or skin animations). + +**+ Pros:** Easy to use and learn. Perfect for flipbook animations +**- Cons:** Must have internet connection. Only offers the most basic tools. + +[Download Piskel](https://www.piskelapp.com/) + +### Libresprite + +LibreSprite is a free and open source program for creating and animating your sprites. Based on the last GPLv2 commit of aseprite. + +**+ Pros**: Basic & easy to use, customizable and curated for pixel artists. +**- Cons**: May not work on Mac, maintained only by a small community. + +## Additional Materials + +:::tip +This guide will walk you through the first stages of addon development, but it is not comprehensive! To learn more about addons, you will have to use and reference other sources of information, which we will link to here. +::: + +### Join the Discord + +The best place to get help with this guide is to join the [discord server](/discord). + +### Vanilla Packs + +Minecraft's vanilla files are a good source of reference material. You should download these packs, and store them on a convenient location on your computer. When you need an example of an item, or entity, or animation, you can reference these files for inspiration. + +- [Vanilla packs](https://github.com/Mojang/bedrock-samples/releases) + +### Documentation + +There are many good sources of Addon documentation. Familiarize yourself with all of them, and consider bookmarking them. + +- [bedrock.dev](https://bedrock.dev/): Reference documentation. +- [wiki.bedrock.dev](https://wiki.bedrock.dev/): Tutorials and guides. +- [MS Docs](https://docs.microsoft.com/en-us/minecraft/creator/): The official microsoft creator portal for addons. + +### Troubleshooting and Additional Help + +- If the json format is very tricky for you, consider reading the [understanding-json guide](/guide/understanding-json). +- If you get stuck with an odd error, consider reading the [troubleshooting guide](/guide/troubleshooting). +- If you still haven't found a solution, feel free to join our [Discord server](/discord). + +### Additional Links and Tools + +- You can explore additional tools [here](/meta/useful-links). + +## Your progress so far + + + +- [x] Installed the necessary software +- [x] Downloaded the Vanilla Example files +- [ ] Locate your `com.mojang` folder and create your addon's workspace. +- [ ] Create the manifest and pack icon for your first addon + + diff --git a/docs/wiki/guide/troubleshooting.md b/docs/wiki/guide/troubleshooting.md new file mode 100644 index 00000000..46265d86 --- /dev/null +++ b/docs/wiki/guide/troubleshooting.md @@ -0,0 +1,81 @@ +--- +title: Troubleshooting +category: Extra +description: A simple troubleshooting guide +prefix: 'c. ' +nav_order: 3 +tags: + - help +mentions: + - SirLich + - Joelant05 + - destruc7ion + - Dreamedc2015 + - MedicalJewel105 + - Luthorius + - SmokeyStack +--- + +Creating Addons for Bedrock Minecraft is a relatively straightforward process _once you get the hang of it_. The first time is usually a frustrating, bug-prone process. This document contains some tips and tricks for fixing those dastardly bugs, as well as best practice information. + +Please read the whole page, before jumping into troubleshooting tips for a specific domain. + +## Reload + +First, you should always reload Minecraft. That means fully closing the game and then reopening it. This can catch many errors, especially those related to assets that are accessed via a filepath, such as textures or loot tables. + +## The Environment + +The best way to prevent nasty bugs is by working in the right environment. You should review the [software preparation document](/guide/software-preparation) for editor recommendations. The most important part is getting a JSON-linter, ([or using an online json-linter](https://jsonlint.com/)), and storing your packs in `development_behavior_packs` and `development_resource_packs`. + +If you have your addons in the normal folders, you can run into "pack caching" issues, where you edit the files in one location, but the game is still using the old files. + +## Content Log + +:::warning Use the Content Log! +Content log is the best tool you have for debugging your addons. Please don't skip this step! +::: + +::: tip +Errors are not cleared between runs, so the errors you see in the content log may be _old_ errors from prior runs. +::: + +The 'Content Log' is a list of issues found in your pack. Minecraft will generate this list every time your load your world. It can catch issues such as: + - Wrong texture path + - Wrong spelled component + - Incorrect json structure + +Content log can be turned on in in `Settings > Creator`. The content log will show in-game on load up, and if more errors occur during gameplay. + +![](/assets/images/guide/content_log.png) + + +### Content Log File + +The content log is saved in `.txt` format inside your files: + + - *Windows*: `C:\Users\USERNAME\AppData\Local\Packages\Microsoft.MinecraftUWP_8wekyb3d8bbwe\LocalState\logs` + - *Android:* `/storage/emulated/0/Android/data/com.mojang.minecraftpe/files/games/com.mojang/logs` + + +## Using Vanilla Resources + +You should download the vanilla resource and behavior pack. You can find the vanilla resource and behavior pack [here](https://www.minecraft.net/en-us/addons/). You can compare against the vanilla files if you have any issues! + +## JSON-Schemas + +JSON-Schemas are a valuable tool for file validation. You can learn more about JSON-Schemas [here](/meta/using-schemas). + +# Troubleshooting your addon! + +## Entities + + Troubleshoot your entities. + +## Items + + Troubleshoot your items. + +## Blocks + + Troubleshoot your blocks. diff --git a/docs/wiki/guide/understanding-json.md b/docs/wiki/guide/understanding-json.md new file mode 100644 index 00000000..f475cba8 --- /dev/null +++ b/docs/wiki/guide/understanding-json.md @@ -0,0 +1,151 @@ +--- +title: Understanding JSON +category: Extra +description: A first peek into JSON +nav_order: 1 +prefix: 'a. ' +mentions: + - SirLich + - solvedDev + - Joelant05 + - Dreamedc2015 + - sermah + - cda94581 +--- + +::: tip +This is an appendix page. You can start the guide from the beginning [here](/guide/index). +::: + +JSON is a simple format for writing text files, in a way that is understandable to both Humans and Computers. Bedrock uses .json files as the "language" of Add-Ons, so you will need a solid understand of how to read and write json! If you have never heard of JSON before, you are encouraged to read through [this tutorial](https://www.digitalocean.com/community/tutorials/an-introduction-to-json). It will teach you everything you need to know about writing valid JSON files. + +## Valid JSON + +The important thing to remember when writing JSON is that it must be _completely error free_, or it won't work at all. Even one wrong character, or one extra comma will cause the entire file to fail. For this reason, it's super important you write valid JSON. + +We can use an online tool called [json lint](https://jsonlint.com/) to tell us whether our JSON is valid. Simply paste your code into the website, and press `Validate JSON`. You will get a response indicating whether your code is correct or not, as well as the location and type of any errors. + +## Data Structures + +In JSON, data can be written in a number of formats. Each format is specialized for the kind of data it wants to represent. Here are the structures we have available: + +| Name | Example | Explanation | +| ------ | -------- | -------------------------------------- | +| String | "hello!" | Words, or characters. Requires quotes. | +| Int | 15 | A number. No quotes. | +| Float | 1.2 | A fractional number. No quotes. | +| Bool | true | Either true or false. No quotes. | + +And now, in .json format: + +```json +{ + "my_string": "hello!", + "my_int": 15, + "my_float": 1.2, + "my_bool": true +} +``` + +In addition to these simple structures, we also have access to two special structures. Special structures are used to *nest* other data together. + +### Arrays + +Arrays are written as two square brackets `[]`. They represent a _list_. We can put _other data structures_ inside of the list. Each _element_ of the list should be separated by a comma. + +Some examples: + +| Structure | Comment | +| --------------- | ------------------------------------- | +| [1, 2, 3] | A list of integers. | +| ["Red", "blue"] | A list of strings. Notice the quotes! | + +And now, in .json format: + +```json +{ + "my_ints": [1, 2, 3], + "my_strings": ["Red", "blue"] +} +``` + +### Objects + +Objects are written as two curly-brackets `{}`. Objects are a special syntax which contains _named_ data structures. The name is called a `key`, and the structure is called a `value`. The examples earlier in this page was a *dictionary* containing examples of the other data types. + +This key-value syntax looks like this: `"": `. Notice the quotes around the key, and the colon. + +Here is an example of an object, which contains a few _key-value-pairs_. + + + +```json +{ + "a_list_of_integers": [1, 2, 3], + "is_json_cool": true +} +``` + +We need to separate each key-value pair with a comma. + +We call the key-value pairs of an object as its _child_ or as being _inside_ the object. + +## JSON Structure + +In Minecraft, JSON files always begin with an _object_, which you can remember is two curly brackets:`{}`. We call this the _top level object_. We write our code _inside_ of this object, in the form of key-value pairs. + +Here is an example of a simple json file, used for Minecraft addons: + + + +```json +{ + "format_version": "1.12.0", + "animations": { + "animation.car.wheel_spin": { + "loop": true, + "animation_length": 1.0, + "bones": { + "front_wheels": { + "rotation": ["q.modified_distance_moved * -30", 0, 0] + }, + "back_wheels": { + "rotation": ["q.modified_distance_moved * -30", 0, 0] + } + } + } + } +} +``` + +Take a careful look at the format. You will see that the entire structure is built out the data-structures that we have already learned. If you want to practice your json skills, try to answer these questions: + +- How many keys are there in the _top level object_. Can you name them? +- What is the value of `format_version`? +- What kind of data is stored in the `"loop"` key? (string, boolean, etc) + +## Troubleshooting Examples + +Here are a few examples, to help you understand feedback you might recieve on the discord or online. We tend to use technical jargon when talking about errors in JSON, so hopefully this section helps familizrize you with the terms: + +--- + +You wrote: `"format_version": 1.12` + +They said: "_The value for format_version is the wrong type. It should be a string._ + +Remember that `type` means one of the structures: `String`, `Int`, `Float`, `Array` or `Object`. If we examine our code, we will see that we put `format_version` to a `Float`, instead of a `String`. We can fix this problem by adding quotes around the `"1.12"`. + +--- + +You wrote: `[1 2 5 6]` + +They said: "_Your array is missing commas._" + +Remember that array elements need to be separated by commas. Your array should look like this: `[1, 2, 5, 6]` + +--- + +They said: _"You accidentally put the format version inside your description. It should go outside at the top level_". + +This means that the key-value pair for `"format_version"` as a _child_ of the description. You should copy/paste the key-value pair out from the description object, and place it at the top level. diff --git a/docs/wiki/items/attachables.md b/docs/wiki/items/attachables.md new file mode 100644 index 00000000..3986de00 --- /dev/null +++ b/docs/wiki/items/attachables.md @@ -0,0 +1,251 @@ +--- +title: Attachables +category: Documentation +tags: + - beginner +mentions: + - Sprunkles317 + - MedicalJewel105 + - AdamRaichu + - Luthorius + - TheItsNameless +--- + +::: tip +This document assumes you have a basic understanding of Molang, render controllers, animations, and client entity definitions. Ensure you are familiar with the basics of [client entities](/entities/entity-intro-rp)! +::: + +## Introduction + +When we design a custom item or block, Minecraft will build a model from a template so the item can be displayed when held. This takes the form of the item's sprite being an extruded texture mesh, or blocks displaying with their model. By using a system called **attachables** we can design our own models to be displayed when these items are held. + +Ever wanted sticks to look like spyglasses? Or to wield a big chainsaw with a spinning chain? Attachables are the way to accomplish that! + +This document covers **two different ways** to create attachables, depending on how the geometry being used is constructed. + +## Overview + +Attachables are a system of rendering entity models when an item or block is equipped. This means having the item held in the main hand, off hand, or armor slots. + +Attachable definitions are quite similar in design to client entity definitions; they let us define textures, materials, geometries, and animations to display the attachable. + +### File Structure + +The attachable definition goes within the 'attachables' folder. The file layout is otherwise identical to that of custom entities. + + + +### Attachable Definition + +Here's a basic example of an attachable. + +RP/attachables/stick.entity.json + +```json +{ + "format_version": "1.10.0", + "minecraft:attachable": { + "description": { + "identifier": "minecraft:stick", + "materials": { + "default": "entity", + "enchanted": "entity_alphatest_glint" + }, + "textures": { + "default": "textures/entity/steve", + "enchanted": "textures/misc/enchanted_item_glint" + }, + "geometry": { + "default": "geometry.wiki.steve_head" + }, + "animations": { + "hold_first_person": "animation.steve_head.hold_first_person", + "hold_third_person": "animation.steve_head.hold_third_person" + }, + "scripts": { + "animate": [ + { + "hold_first_person": "context.is_first_person == 1.0" + }, + { + "hold_third_person": "context.is_first_person == 0.0" + } + ] + }, + "render_controllers": [ + "controller.render.item_default" + ] + } + } +} +``` + +A few key things to point out with this attachable definition: + +- The identifier matches an existing block or item ID. This will activate the attachable when the item is equipped, and will replace the original model that appears when held. +- There is a material and texture listed for the enchantment glint. This is important to keep around if your item should have the glint when enchanted. + +Making attachables is a little more involved than making a client entity file. We need to properly rig the geometry's skeleton so that it looks correct when equipped. + +## Method 1 - Attached to the Skeleton + + + +In this first method we will construct the attachable using a copy of the player's skeleton, by attaching your model to one of the player's bones. + +This solution is ideal for models that are intended for scenarios involving only one type of mob/entity, especially players; and involving only one equipment slot. It is easy to view what the model will look like in Blockbench. + +### Setting up the Skeleton + +We need to reconstruct the player's skeleton in order for our model to be parented to the correct bone, otherwise it will not be parented to anything and will float freely on the player. + +With a text editor, take the bones from the provided player skeleton file and copy them to your geometry file, then set the `rightItem` bone as the parent to the cubes from your model. Save this geometry to your resource pack. + +For convenience, such a model has been prepared here. The cubes from the player's model have already been removed: +📄 Geometry File + +### Display Settings + +Having your model floating at the player's feet is not ideal. Our next step is to create animations so we can properly display the model on the player. + +Create two new animations, one for holding the item in first person and another for holding it in third person. Select your third-person animation, and position it however you want. Save this animation to your resource pack. + +Here is an example of such an animation. This also includes a first-person animation—the means of making one is detailed in the section below. +📄 Animation File + +### First-person Animations + +To more easily create first-person animations, we need to mimic how the arm is positioned in the first person. + +:::tip +To add animation for player's hands, you need to use player's animations, not attachables animations. +::: + +Use the following guide animation and import it into Blockbench. It applies a rotation of (95, -45, 115) and a translation of (13.5, -10, 12) to the right arm bone, perfectly mimicking how the arm is positioned in first-person. +📄 Attachable Guide File + +:::warning NOTE +This is where things get tricky. Both animations will need to be played simultaneously; your first-person animation, and the guide's first-person animation. + +Be sure you are editing your animation when making your changes. Select it first, then play the guide's first-person animation on top. +::: + +### Conclusion + +With this all set up, go through and delete the *cubes* from the player skeleton if there are any, but keep the bones. Check the model out in-game! + +## Method 2 - Bound to a Bone + + + +In this second method, the attachable geometry will be constructed using model binding. This allows a model to be directly attached to a bone within a mob's geometry corresponding to the slot it is equipped in. Minecraft employs model binding for its attachable items, including the trident, spyglass, bow, and shield. + +While this method allows the attachable to apply more dynamically to other mobs and equipment slots, model binding also has strange quirks, which will be illustrated below. Some developers may find this method trickier to get working. + +### Model Binding + +Our first step is to upgrade the model file format version to `"1.16.0"` if it is not already. If the model is a legacy file, then convert it before continuing; Blockbench has a tool to do this (File → Convert Project). + +Next up is modifying the root bone of our geometry to be bound to the equipment slot the item is placed in. Take note of line 4 in this excerpt from the skeleton head geometry file: + +RP/models/entity/skeleton_head.geo.json + +```json +// A bone +{ + "name": "skeleton_head", + "binding": "q.item_slot_to_bone_name(context.item_slot)", + "pivot": [0, 4, 0], + "cubes": [ + { + "origin": [-4, 0, -4], + "size": [8, 8, 8], + "uv": [0, 0] + } + ] +} +``` + +The `"parent"` key in a bone accepts a string, and whichever bone name is entered will be set as the parent to the current bone; the child bones keep their positions but move relative to the parent bone. + +The `"binding"` key on the other hand accepts Molang, and the pivot point of whichever bone name is entered is set as the *root position* that the child bone and its children should inherit. + +For the value of `"binding"` we are using the Molang query `q.item_slot_to_bone_name`, which converts a slot name to a bone name, with the contextual variable `context.item_slot` as an argument. This converts the name of the equipment slot this item resides in to its corresponding bone name in the player's geometry. The conversions are as follows: +- `'main_hand'` → "rightitem" +- `'off_hand'` → "leftitem" + +Apply the model binding to your bone, and save the geometry to your resource pack. + +An example model with this binding applied is provided here: +📄 Geometry File + +### Display Settings + +With that done, the next step is to set up animations to display the model in first person and third person. + +Create two new animations, one for holding the item in first person and another for holding it in third person. + +To make creating these animations easier, please do the following: + +- Download the following player skeleton model. We will use this as a visual aid for positioning your model. +📄 Player Skeleton File + +- With a text editor, add the bones and cubes from your model to the player skeleton model, then import the player skeleton model into Blockbench. +- Set your model's root bone(s) to be a child of the 'rightItem' bone in the player skeleton. +- Download the following animation file import the `wiki.third_person_guide` animation. This will be used later to make positioning easier. +📄 Attachable Guide File + +These guide animations have one notable feature: they apply a -24 offset to the y-position of the right item bone to counteract a similar -24 y-position offset Minecraft applies to bound bones. We are unsure at this time why this happens. + +:::warning NOTE +Similar to Method One, **two** animations will need to be played simultaneously for correct positioning. + +Be sure you are editing your animations when making your changes. Select it first, then play the guide animation on top. +::: + +Play both animations, and position your model however you want. Save the animations to your resource pack. + +An example animation file for this positioning: +📄 Animation File + +### First-person Animations + +Similar to the third-person animation, look in the Attachable Guide file and import the `wiki.first_person_guide` animation into Blockbench. Play both your animation and the guide's first-person animation together, then make your changes and save the file. + +## Example Pack + +Each of these methods have been compiled into an example pack you may reference, for if you are getting stuck or simply want to see a working example. + +💾 Example Pack diff --git a/docs/wiki/items/custom-armor.md b/docs/wiki/items/custom-armor.md new file mode 100644 index 00000000..88431112 --- /dev/null +++ b/docs/wiki/items/custom-armor.md @@ -0,0 +1,562 @@ +--- +title: Custom Armor +category: Tutorials +tags: + - experimental +mentions: + - SirLich + - Dreamedc2015 + - sermah + - yanasakana + - Joelant05 + - MedicalJewel105 + - aexer0e + - Brougud + - XxPoggyisLitxX + - LeGend077 + - SmokeyStack +--- + +::: tip +It is highly recommended that you look over [the BlockBench modelling and texturing](/guide/blockbench) section in the beginners guides before tackling these sections. +::: + +Making custom armors is surprisingly easy to do, you need to do a bit of fiddling around as there are a few files that need to be added and there can be a little bit of texturing involved but you can do as much or as little as you want here. + +## Chest Piece + +Create a chest piece: + +BP/items/my_chest.json + +```json +{ + "format_version": "1.16.100", + "minecraft:item": { + "description": { + "identifier": "wiki:my_chest", + // Notice we give it the equipment category + "category": "equipment" + }, + "components": { + // Make sure it appears within the chestplate category + "minecraft:creative_category": { + "parent": "itemGroup.name.chestplate" + }, + // The icon we want to use in our INVENTORY + "minecraft:icon": { + "texture": "my_chest" + }, + // We give it a name + "minecraft:display_name": { + "value": "My Custom Armor" + }, + // We dont want it to stack + "minecraft:max_stack_size": 1, + // We make sure it can only receive enchantments for chest pieces + "minecraft:enchantable": { + "value": 10, + "slot": "armor_torso" + }, + // This tells it how much protection it should give + "minecraft:armor": { + "protection": 5 + }, + // We want it to be repairable, and what to use to repair it + "minecraft:repairable": { + "repair_items": [ + { + "items": ["minecraft:stick"], + "repair_amount": "context.other->q.remaining_durability + 0.05 * context.other->q.max_durability" + // Some complicated molang; just copy it + } + ] + }, + // Mark it as a wearable and that it goes in the chest slot + "minecraft:wearable": { + "dispensable": true, + "slot": "slot.armor.chest" + }, + // Provide its durability + "minecraft:durability": { + "max_durability": 200 + } + } + } +} +``` + +At this point you could just go and add an item texture into your `RP/textures/item_texture.json` with the key `my_chest` and you are on your way. We have attached a default item texture for your armor here if you want to just follow along. + +![](/assets/images/tutorials/custom-armor/custom_chestplate.png) + +Download texture here + +## Adding attachables and textures + +At this point your item would appear in game and would be wearable but it would not have any appearance. This is because we need to tell it how to handle the attachable equipment and give it a texture to show. + +To start with you need to create an `attachables` folder in your RP (you may already have one). + +RP/attachables/my_chest.json + +```json +{ + "format_version": "1.8.0", + "minecraft:attachable": { + "description": { + "identifier": "wiki:my_chest", + // These 2 are default and are required + "materials": { + "default": "armor", + "enchanted": "armor_enchanted" + }, + "textures": { + // This is our CUSTOM armor texture we need to make next + "default": "textures/models/armor/custom_main", + // This texture doesn't actually exist in our RP + // but it will blow up without it so leave it in + "enchanted": "textures/misc/enchanted_item_glint" + }, + // We tell it what geometry to use for the chestplate + "geometry": { + "default": "geometry.player.armor.chestplate" + }, + // We tell it to hide the chest layer as we will be showing our armor on top + "scripts": { + "parent_setup": "v.chest_layer_visible = 0.0;" + }, + // We tell it what controller to use (default armor one) + "render_controllers": ["controller.render.armor"] + } + } +} +``` + +At this point we need to make sure we create a texture for our model, these live in `RP/textures/models/armor`. We however actually need 2 textures, as one is for the main armor as if it is being worn all together, and one is for the legs which when worn alone will often cover some of the boot area. + +If you do not feel creative we have provided a recoloured diamond armour skin for use with this tutorial. So just `Save As` and plop them in the folder. + +![](/assets/images/tutorials/custom-armor/custom_main.png) + +Download texture here + +![](/assets/images/tutorials/custom-armor/custom_legs.png) + +Download texture here + +> In the real world you would probably want to use `BlockBench` or some photo editing program to edit the textures and ideally see how they look on a model before you add them into the addon. +> If you now go into the game and check what you have produced you should be able to wear your chest piece and pat yourself on the back for a job well done. + +![](/assets/images/tutorials/custom-armor/armor-item-image.jpg) +![](/assets/images/tutorials/custom-armor/armor-model-image.jpg) + +## Leggings + +So while the chest piece alone is great, you probably want a whole set, so from here if you make another item json for the boots like so. + +BP/items/my_leggings.json + +```json +{ + "format_version": "1.16.100", + "minecraft:item": { + "description": { + "identifier": "wiki:my_leggings", + "category": "equipment" + }, + "components": { + // We give it the leggings category this time + "minecraft:creative_category": { + "parent": "itemGroup.name.leggings" + }, + // Give it an applicable ITEM texture + "minecraft:icon": { + "texture": "my_leggings" + }, + "minecraft:display_name": { + "value": "My Custom Leggings" + }, + "minecraft:max_stack_size": 1, + // Make sure the enchantments are for legs + "minecraft:enchantable": { + "value": 10, + "slot": "armor_legs" + }, + "minecraft:armor": { + "protection": 3 + }, + "minecraft:repairable": { + "repair_items": [ + { + "items": ["minecraft:stick"], + "repair_amount": "context.other->q.remaining_durability + 0.05 * context.other->q.max_durability" + } + ] + }, + // Make sure the wearable slot is legs + "minecraft:wearable": { + "dispensable": true, + "slot": "slot.armor.legs" + }, + "minecraft:durability": { + "max_durability": 200 + } + } + } +} +``` + +This is great and like before you will need to add your own item texture, although here is one if you just want to continue. + +![](/assets/images/tutorials/custom-armor/custom_leggings.png) + +Download texture here + +Once we are done here we need to create the attachables file like this: + +RP/attachables/my_leggings.json + +```json +{ + "format_version": "1.8.0", + "minecraft:attachable": { + "description": { + "identifier": "wiki:my_leggings", + // Notice this is the same as before + "materials": { + "default": "armor", + "enchanted": "armor_enchanted" + }, + "textures": { + // Same as before + "enchanted": "textures/misc/enchanted_item_glint", + // This one is different as we are using the legging specific texture + "default": "textures/models/armor/custom_legs" + }, + // Tell it to use leggings geom + "geometry": { + "default": "geometry.humanoid.armor.leggings" + }, + // Hide legs layer as we will be rendering over it + "scripts": { + "parent_setup": "v.leg_layer_visible = 0.0;" + }, + // Same as before + "render_controllers": ["controller.render.armor"] + } + } +} +``` + +Given that we have already put in the textures needed we can run it and see our legs straight away. + +## Helmet + +This is just like the chest piece, just we change some of the categories and slots like so. + +BP/items/my_helm.json + +```json +{ + "format_version": "1.16.100", + "minecraft:item": { + "description": { + "identifier": "wiki:my_helm", + "category": "equipment" + }, + "components": { + // Helmet category + "minecraft:creative_category": { + "parent": "itemGroup.name.helmet" + }, + "minecraft:icon": { + "texture": "my_helm" + }, + "minecraft:display_name": { + "value": "My Custom Helmet" + }, + "minecraft:max_stack_size": 1, + // Helm enchantment slot + "minecraft:enchantable": { + "value": 10, + "slot": "armor_head" + }, + "minecraft:armor": { + "protection": 3 + }, + "minecraft:repairable": { + "repair_items": [ + { + "items": ["minecraft:stick"], + "repair_amount": "context.other->q.remaining_durability + 0.05 * context.other->q.max_durability" + } + ] + }, + // Wearable head slot + "minecraft:wearable": { + "dispensable": true, + "slot": "slot.armor.head" + }, + "minecraft:durability": { + "max_durability": 200 + } + } + } +} +``` + +As you can see not much has changed, we just update the categories/slots to the correct ones for helms and then we add the attachables file (here is the item texture if you need it). + +![](/assets/images/tutorials/custom-armor/custom_helmet.png) + +Download texture here + +RP/attachables/my_helm.json + +```json +{ + "format_version": "1.8.0", + "minecraft:attachable": { + "description": { + "identifier": "wiki:my_helm", + // These 2 are default and are required + "materials": { + "default": "armor", + "enchanted": "armor_enchanted" + }, + "textures": { + // This is our CUSTOM armor texture we need to make next + "default": "textures/models/armor/custom_main", + // This texture doesn't actually exist in our RP + // but it will blow up without it so leave it in + "enchanted": "textures/misc/enchanted_item_glint" + }, + // We tell it what geometry to use for the helmet + "geometry": { + "default": "geometry.player.armor.helmet" + }, + // We tell it to hide the helmet layer as we will be showing our armor on top + "scripts": { + "parent_setup": "v.chest_layer_visible = 0.0;" + }, + // We tell it what controller to use (default armor one) + "render_controllers": ["controller.render.armor"] + } + } +} +``` + +There you go, you now have 3/4 of a complete set, we may as well go through the boots as well so you know all the categories etc. + +## Boots + +You already know the pattern so lets make the item and attachable json files. + +BP/items/my_boots.json + +```json +{ + "format_version": "1.16.100", + "minecraft:item": { + "description": { + "identifier": "wiki:my_boots", + "category": "equipment" + }, + "components": { + // Boots category + "minecraft:creative_category": { + "parent": "itemGroup.name.boots" + }, + "minecraft:icon": { + "texture": "my_boots" + }, + "minecraft:display_name": { + "value": "My Custom Boots" + }, + "minecraft:max_stack_size": 1, + // Enchantable Feet + "minecraft:enchantable": { + "value": 10, + "slot": "armor_feet" + }, + "minecraft:armor": { + "protection": 3 + }, + "minecraft:repairable": { + "repair_items": [ + { + "items": ["minecraft:stick"], + "repair_amount": "context.other->q.remaining_durability + 0.05 * context.other->q.max_durability" + } + ] + }, + // Feet slot + "minecraft:wearable": { + "dispensable": true, + "slot": "slot.armor.feet" + }, + "minecraft:durability": { + "max_durability": 200 + } + } + } +} +``` + +The custom boots texture if you need it. + +![](/assets/images/tutorials/custom-armor/custom_boots.png) + +Download texture here + +RP/attachables/my_boots.json + +```json +{ + "format_version": "1.8.0", + "minecraft:attachable": { + "description": { + "identifier": "wiki:my_boots", + // These 2 are default and are required + "materials": { + "default": "armor", + "enchanted": "armor_enchanted" + }, + "textures": { + // This is our CUSTOM armor texture we need to make next + "default": "textures/models/armor/custom_main", + // This texture doesn't actually exist in our RP + // but it will blow up without it so leave it in + "enchanted": "textures/misc/enchanted_item_glint" + }, + // We tell it what geometry to use for the boots + "geometry": { + "default": "geometry.player.armor.boots" + }, + // We tell it to hide the boots layer as we will be showing our armor on top + "scripts": { + "parent_setup": "v.chest_layer_visible = 0.0;" + }, + // We tell it what controller to use (default armor one) + "render_controllers": ["controller.render.armor"] + } + } +} +``` + +Thats it, you now have a whole suit of custom armor you can swagger around in, and use this as a basis to make whatever other armors you want in the game. + +> It is worth noting that we have used 2 separate textures here, and you could potentially use a texture per attachable, but each new texture consumes memory so its best to use as few as possible. +> So this is what you should end up with, and as a bonus there is one more section on making set effects using filters, which is a bit more advanced but its a fun thing to do. + +![](/assets/images/tutorials/custom-armor/custom-set-image.jpg) + +## Bonus - Making Set Effects + +This is a bit more advanced but lets say you want your custom armor to act like it's a set from an RPG game. We can add some code to check if we have the set equipped and do some great stuff with it. + +Note that for effects you can use tick.json and functions with hasitem selector argument to avoid using player.json. + +In this example we will just add a chance to teleport the attacker somewhere nearby and put a blurb on the console for flavour. + +As we want this to trigger when the player is hit we need to add some logic to the `player.json` file. This is a huge file and we unfortunately need to make sure it has all the default content in there as well due to the way it will overwrite the default player components etc. + +So rather than include the whole `player.json` I will just include the parts you will need to add to your `components` and `events` sections. If you have no idea what the `player.json` is then look in the vanilla behavior pack and look for it and just copy it over into your project. + +So first of all lets put in the damage sensor component (which goes in your component section) which listens for when you take damage and lets you raise an event from it. + +BP/entities/player.json#components + +```json +"minecraft:damage_sensor": { + "triggers": { + "on_damage": { + "filters": { + "all_of": [ + { + "test": "has_equipment", + "subject": "self", + // Domain is the body part in this case + "domain": "head", + "operator": "==", + // The item identifier we want to check + "value": "wiki:my_helm" + }, + { + "test": "has_equipment", + "subject": "self", + "domain": "torso", + "operator": "==", + // Worth noting you can omit prefix for minecraft internal items i.e stick + "value": "wiki:my_chest" + }, + { + "test": "has_equipment", + "subject": "self", + "domain": "leg", + "operator": "==", + "value": "wiki:my_leggings" + }, + { + "test": "has_equipment", + "subject": "self", + "domain": "feet", + "operator": "==", + "value": "wiki:my_boots" + } + ] + }, + // If all the triggers match in the filter raise the event + "event": "wiki:armor_sets.my_custom.taken_damage" + }, + // This means if it matches the check it still applies damage + // Can be good to ignore team damage or similar scenarios + "deals_damage": true + } +} +``` + +As you can see from the comments, there is a lot there but really all we are doing is listening out for something then making sure we only filter the results we care about then relay on an event. + +> The event can be called anything but it is often better to have it more specific, incase you end up having multiple similar events etc, also it can help finding if you have multiple sections to it, i.e I could search on "armour_sets" and find all events related to it. +> Then once you are done, in the same file we decide what we want to do with the event, which we put into our `events` section. + +BP/entities/player.json#events + +```json +"wiki:armor_sets.my_custom.taken_damage": { + "randomize": [ + { + "weight": 1, + // We do a sequence here as we want to apply one command + // on one entity and the other on ourselves + "sequence": [ + { + // This will take the attacker/other because it was in context + // at time of raising the event in the damage_sensor + "run_command": { + // Teleport the entity away from us + "command": "spreadplayers ~~ 5 20 @s", + // Run the command on the attacker not us + "target": "other" + } + }, + { + "run_command": { + "command": "tellraw @s{\"rawtext\":[{\"text\":\"§aYour Armor Glows And The Enemy Vanishes\"}]}" + } + } + ] + }, + { + // Dummy weighting so it happens semi frequently + "weight": 20 + } + ] +} +``` + +Thats it, you can rejig the bits how you see fit but ultimately you have all the pieces to apply effects to armor and check for if you have the whole set applied or check for other equipment. + +You can also change the equipment checks from self to other and check if whoever is attacking you has something equipped or even check if you are attacking a sort of block/entity and do different effects based on that. We haven't touched on that directly here but there is a good enough starting point to get you on your way and let you be creative with things. diff --git a/docs/wiki/items/custom-weapon.md b/docs/wiki/items/custom-weapon.md new file mode 100644 index 00000000..228c313d --- /dev/null +++ b/docs/wiki/items/custom-weapon.md @@ -0,0 +1,277 @@ +--- +title: Custom Weapons +category: Tutorials +tags: + - experimental +mentions: + - SirLich + - solvedDev + - MedicalJewel105 + - aexer0e + - PepijnMC + - ThomasOrs + - Xterionix +--- + +Making a custom weapon is pretty simple since the 1.16.100 changes, as these allow you to simply define an item entry for it in your `BP/items` folder and provide a corresponding texture in the `RP/textures/items` folder with a bit of config and you have a fully working weapon that you can customize however you see fit. + +## Custom Sword Item + +Like with the other item tutorials we will start by making a simple custom sword like so. + +BP/items/my_sword.json + +```json +{ + "format_version": "1.16.100", + "minecraft:item": { + "description": { + "identifier": "wiki:my_sword", + // Notice we give it the equipment category + "category": "equipment" + }, + "components": { + // This allows us to have the sword in the creative category of swords + "minecraft:creative_category": { + "parent": "itemGroup.name.sword" + }, + "minecraft:max_stack_size": 1, + // This is a new change as we want it to be equippable in the hand + "minecraft:hand_equipped": true, + "minecraft:durability": { + "max_durability": 600 + }, + // Give it however much damage you want + "minecraft:damage": 10, + // We also let it be enchantable in the "sword" slot + "minecraft:enchantable": { + "value": 10, + "slot": "sword" + }, + // This texture is used for both inventory and the hand model + "minecraft:icon": { + "texture": "my_sword" + }, + "minecraft:display_name": { + "value": "My Custom Sword" + }, + // Allow the sword to be repaired with sticks + "minecraft:repairable": { + "repair_items": [ + { + "items": ["minecraft:stick"], + "repair_amount": "context.other->q.remaining_durability + 0.05 * context.other->q.max_durability" + } + ] + } + } + } +} +``` + +So at a bare minimum that is enough to get a sword put into the game, we still need to register the icon with the RP but thats not a massive issue as all we need to do is go to our RP folder and enter it in like so. + +RP/textures/item_texture.json + +```json +{ + "resource_pack_name": "vanilla", + "texture_name": "atlas.items", + "texture_data": { + "my_sword": { + // Make sure you have put an icon texture called my_sword.png here + "textures": "textures/items/my_sword" + } + } +} +``` + +Here is an example texture if you do not have your own to use, just `Save As` and plop it in the `RP/textures/items` directory. + +![](/assets/images/tutorials/custom-weapons/my_sword.png) + +Download texture here + +## In-game + +So now we have a BP containing our items json data and an RP containing the texture, we can make a new level, and make sure we include our BP/RP, however we **also need to enable the Holiday Creator Features** under experimental gameplay. + +Once you have done all the above, go into creative mode and you should be able to find your sword by its name, or under the sword category as shown. + +![](/assets/images/tutorials/custom-weapons/custom_sword.jpg) + +Then if you put it in your hands you should see it in the game like this. + +![](/assets/images/tutorials/custom-weapons/held_sword.jpg) + +Now that wasn't too hard was it! and you can make as many custom swords as you want now, however there is far more fun stuff you can do from here if you feel up for it. + +## Tool-like Functionality + +You can also mix and match other components like `minecraft:digger` to allow you to go through web or bamboo quicker like this: + +BP/items/my_sword.json#components + +```json +"minecraft:digger": { + "use_efficiency": true, + "destroy_speeds": [ + { + "block": "minecraft:web", + "speed": 15 + }, + { + "block": "minecraft:bamboo", + "speed": 10 + } + ], + "on_dig":{ + "event": "wiki:my_sword.on_dig_damage" + //Needed to change sword durability + } +} +``` + +Also add an event: + +BP/items/my_sword.json + +```json +"events": { + "wiki:my_sword.on_dig_damage": { + "damage":{ + //This part of event will make sword take damage when it was used to dig block + "type":"durability", + "target":"self", + //By using "self" you define item as target to take damage + "amount":1 + } + } +} +``` + +You can also give it a default mining speed by adding `"minecraft:mining_speed": 1.5`, which would give it a generic mining speed letting you use your weapon like a pickaxe. +(It is currently broken) + +## Damage Tooltip + +The above was a bare bones approach, but you probably want to be able to show the damage a sword does when the user hovers over it. + +To do this you need to add the `"minecraft:weapon": {}` component, even if its just empty this is enough to MC to know internally to treat your popup like a weapon popup when mouse over-ing. + +So if you add the above component to your item json file when you mouse over your sword you will now see **+10 Attack Damage** listed in its tooltip. + +> You may be thinking "why didn't you just add this above?" and the answer is because we will build off this component to add more cool stuff in the next section, so I wanted to keep it separate. + +## Unique ability & durability + +At this point you could call it a day, but what if you wanted to make a sword that could inflict status effects, or teleport an enemy when they attacked you? + +Assuming you wanted to do something like this we will need to build off the `minecraft:weapon` component and raise an event when the weapon hits an entity. + +BP/items/my_sword.json#components + +```json +"minecraft:weapon": { + "on_hurt_entity": { + "event": "wiki:my_sword.hurt_entity" + } +} +``` + +Once we add that then every time you hurt an entity it will raise the event `wiki:my_sword.hurt_entity`. You can name this whatever you want, but if you end up with lots of events its recommended to have some level of namespacing, so in this scenario `example` is my main namespace, `my_sword` is the item I want it to apply on and `hurt_entity` is the related event on that item. + +> I could just as easily call the event **"space-noodle"** and it would work fine, but you want it to be easily searchable and self explaining, so keep that in mind + +Now that we have an event being raised we can do what we want with it. In this example I am going to do 3 things: +1. Teleport the player with 25% chance. +2. Output a message letting the player know that something happened. +3. Damage the sword. + +So if you go back into your my_sword.json and after your `components` section add a new section like so. + +BP/items/my_sword.json + +```json +"events": { + "wiki:my_sword.hurt_entity": { + "sequence":[ + //Sequence is needed to run two or more parts of event + { + "randomize": [ + { + // Weights are relative, so this has 1 + "weight": 1, + // Teleport the HOLDER (you) within an 8x8x8 range + "teleport": { + "target": "holder", + "max_range": [8,8,8] + }, + // Then tell some green text + "run_command":{ + "command":[ + "tellraw @s{\"rawtext\":[{\"text\":\"§aYour Sword Glows§r\"}]}" + ] + } + }, + { + // We have another dummy random element here which contains the max weight + "weight": 3 + } + ] + }, + { + // I think you haven't forgot what this do + "damage":{ + "type":"durability", + "target":"self", + "amount":1 + } + } + ] + } +} +``` + +That was a bit to bite off, but as explained above this lets us randomly **1/4** of the time trigger a teleportation of the sword holder and show a text command when it happens. + +You can do whatever you want here and get super creative, set enemies on fire, or spawn enemies or blocks etc. There is so much you can do with this basic approach to creating weapons! + +> It's worth noting here that the dummy element is needed to scale the weightings, so we have one element with a weight of **1** and a 2nd one with a weight of **4** so this gives us the **1 in 4** chance of it proccing. If we were to have gone with the dummy element having a weight of **100** then we would have a **1 in 100** chance of proccing. If we didn't have a 2nd dummy element then the first weight would be ignored and it would happen 100% of the time. + +## Anything Else? + +You should probably make a recipe for it, which is covered in previous chapters, as there isn't anything really new in there, but incase you are unsure here is an example one to make the sword with ender eyes and ender pearls. + +BP/recipes/my_sword.json + +```json +{ + "format_version": "1.12.0", + "minecraft:recipe_shaped": { + "description": { + "identifier": "wiki:my_sword" + }, + "tags": ["crafting_table"], + "pattern": ["e", "E", "#"], + "key": { + "#": { + "item": "minecraft:stick" + }, + "E": { + "item": "minecraft:ender_eye" + }, + "e": { + "item": "minecraft:ender_pearl" + } + }, + "result": { + "item": "wiki:my_sword" + } + } +} +``` + +![](/assets/images/tutorials/custom-weapons/sword_recipe.jpg) + +If you whack that in then you can now craft your sword in the game and hopefully go off and make any other custom swords you fancy or even bows or tridents. diff --git a/docs/wiki/items/enchantments.md b/docs/wiki/items/enchantments.md new file mode 100644 index 00000000..48e30a78 --- /dev/null +++ b/docs/wiki/items/enchantments.md @@ -0,0 +1,54 @@ +--- +title: Enchantments +category: Documentation +nav_order: 5 +tags: + - Stable + - Last updated for Version 1.18.10 +mentions: + - Ciosciaa + - MedicalJewel105 + - SmokeyStack +--- + +Enchantment identifiers are used in the `/enchant` command and in item functions and conditions. + +| Name | Identifier | Maximum Level | Treasure | Curse | +| ----------------------- | ----------------------- | ------------- | -------- | ----- | +| Silk Touch | `silk_touch` | 1 | ❌ | ❌ | +| Fortune | `fortune` | 3 | ❌ | ❌ | +| Efficiency | `efficiency` | 5 | ❌ | ❌ | +| Luck of the Sea | `luck_of_the_sea` | 3 | ❌ | ❌ | +| Lure | `lure` | 3 | ❌ | ❌ | +| Sharpness | `sharpness` | 5 | ❌ | ❌ | +| Smite | `smite` | 5 | ❌ | ❌ | +| Bane of Arthropods | `bane_of_arthropods` | 5 | ❌ | ❌ | +| Fire Aspect | `fire_aspect` | 2 | ❌ | ❌ | +| Knockback | `knockback` | 2 | ❌ | ❌ | +| Looting | `looting` | 3 | ❌ | ❌ | +| Power | `power` | 5 | ❌ | ❌ | +| Flame | `flame` | 1 | ❌ | ❌ | +| Punch | `punch` | 2 | ❌ | ❌ | +| Infinity | `infinity` | 1 | ❌ | ❌ | +| Multishot | `multishot` | 1 | ❌ | ❌ | +| Piercing | `piercing` | 4 | ❌ | ❌ | +| Quick Charge | `quick_charge` | 3 | ❌ | ❌ | +| Impaling | `impaling` | 5 | ❌ | ❌ | +| Riptide | `riptide` | 3 | ❌ | ❌ | +| Loyalty | `loyalty` | 3 | ❌ | ❌ | +| Channeling | `channeling` | 1 | ❌ | ❌ | +| Protection | `protection` | 4 | ❌ | ❌ | +| Projectile Protection | `projectile_protection` | 4 | ❌ | ❌ | +| Fire Protection | `fire_protection` | 4 | ❌ | ❌ | +| Blast Protection | `blast_protection` | 4 | ❌ | ❌ | +| Feather Falling | `feather_falling` | 4 | ❌ | ❌ | +| Thorns | `thorns` | 3 | ❌ | ❌ | +| Frost Walker | `frost_walker` | 2 | ✅ | ❌ | +| Respiration | `respiration` | 3 | ❌ | ❌ | +| Aqua Affinity | `aqua_affinity` | 1 | ❌ | ❌ | +| Curse of Binding | `curse_of_binding` | 1 | ✅ | ✅ | +| Depth Strider | `depth_strider` | 3 | ❌ | ❌ | +| Soul Speed | `soul_speed` | 3 | ✅ | ❌ | +| Unbreaking | `unbreaking` | 3 | ❌ | ❌ | +| Mending | `mending` | 1 | ✅ | ❌ | +| Curse of Vanishing | `curse_of_vanishing` | 1 | ✅ | ✅ | diff --git a/docs/wiki/items/equipped-item-commands.md b/docs/wiki/items/equipped-item-commands.md new file mode 100644 index 00000000..1532f677 --- /dev/null +++ b/docs/wiki/items/equipped-item-commands.md @@ -0,0 +1,260 @@ +--- +title: Run Commands with Equipped Items +category: Tutorials +tags: + - experimental + - intermediate +mentions: + - Chikorita-Lover + - MedicalJewel105 + - Luthorius + - TheItsNameless +--- + +## Introduction + +A common concept for add-ons is implementing new armor sets with unique effects, just like the turtle shell and netherite armor. While items have a knockback resistance component, they don't have a component for inflicting mob effects, emitting particles, etc. under certain conditions. However, using server animations, Molang and item tags, this can easily be done! + +Keep in mind that this requires modifying the player behavior, which is a common theme for many add-ons; thus, your add-on may not be compatible with others if you wish to do this. + +> However some people found a way not to use player.json. They replace it with dummy entity-rider. Try experimenting yourself! + +The use of Holiday Creator Features is also required to add item tags and easily equip our item in armor or off-hand slots. + +## Server Animation + +The first step will be to create a server animation, which is a file that runs commands or events at certain keyframes. While client animations are in the resource pack, server animations are in the behavior pack. You can read a bit more [here](/entities/timers#animation-based-timers). We can start by using the following as a template: + +BP/animations/player.json + +```json +{ + "format_version": "1.10.0", + "animations": { + "animation.player.emerald_armor": { + "timeline": { + "0.0": [] + }, + "animation_length": 0.05, + "loop": true + } + } +} +``` + +Let's go over what's in this template and what everything does: + +- `animation.player.emerald_armor` is our animation's identifier; you can change this to something else, such as `animation.player.phantom_armor`. +- `timeline` runs commands and events at given keyframes. +- `animation_length` is how long the animation lasts; we'll use 0.05 seconds, as that's the length of an in-game tick. +- `loop` is quite straight-forward; setting it to true makes the animation loop. + +We can add commands to the `0.0` array in our timeline to execute, such as an `/effect` command, like such: + +BP/animations/player.json#timeline + +```json +{ + "0.0": [ + "/effect @s speed 1 0" + ] +} +``` + +We're not limited to `/effect`, of course. If you want to use some other command, such as `/function` or `/particle`, go right ahead! + +After this, we're finished in our server animation, and we'll head into the behavior file for our item for a quick addition. + +## Item Behavior + +To actually check if our item is equipped, we can use a Molang query that checks for item tags. + +You can skip this section if: + +- You want check for a vanilla item instead, such as an iron armor piece through the `minecraft:iron_tier` tag +- You want to check for the item via `q.is_item_name_any`, which checks for an item identifier in any slot + +In our item's behavior, we'll have to add a tag to `components`. For example, if we wanted to add the `example:emerald_tier` tag, we would add the `tag:example:emerald_tier` component: + +BP/items/my_item.json#components + +```json +"tag:example:emerald_tier": {} +``` + +That's it, now your item has whatever tag you assigned it! You can add more tags if you want, but this is all we need for what we're doing. + +## Player Behavior + +Finally, we need to modify the player's behavior to run the server animation. We'll be working entirely within `description`. + +First, we need to set a short name for our animation. If you have any experience with client animations, this process will be quite similar. Add `animations` to `description`, and set a short name, like such: + +BP/entities/player.json#description + +```json +{ + "identifier": "minecraft:player", + "is_spawnable": false, + "is_summonable": false, + "is_experimental": false, + "animations": { + "emerald_armor": "animation.player.emerald_armor" + } +} +``` + +Now with a short name set, we can run our animation. + +Add `scripts` to `description`, and set a Molang query to run. To check for the item, we can use one of the following: + +- `q.is_item_name_any`, to check for a given item identifier in any slot. This example will check for `example:totem_of_retreat` in either hand: +``` +q.is_item_name_any('slot.weapon.mainhand',0,'example:totem_of_retreat') || q.is_item_name_any('slot.weapon.offhand',0,'example:totem_of_retreat') +``` + +- `q.equipped_item_any_tag`, to check for at least one of any given tag in a given slot. This example will allow an emerald- or phantom- tier armor piece to be used: +``` +q.equipped_item_any_tag('slot.armor.head','example:emerald_tier','example:phantom_tier') +``` + +- `q.equipped_item_all_tags`, to check for all given tags in a given slot. This example will only allow an armor piece that's both emerald- and ancient- tier: +``` +q.equipped_item_all_tags('slot.armor.head','example:ancient_tier','example:emerald_tier') +``` + +Let's take a look at an example using `q.equipped_item_any_tag`: + +BP/entities/player.json#description + +```json +{ + "identifier": "minecraft:player", + "is_spawnable": false, + "is_summonable": false, + "is_experimental": false, + "animations": { + "emerald_armor": "animation.player.emerald_armor" + }, + "scripts": { + "animate": [ + { + "emerald_armor": "q.equipped_item_any_tag('slot.armor.head','example:emerald_tier')" + } + ] + } +} +``` + +This example will run a server animation with the `emerald_armor` short name if an emerald-tier item is equipped in the helmet slot. You can change the Molang field to match your item tag, use a different query, or add additional queries. + +You can view a list of additional slot identifiers at the [Minecraft Wiki](https://minecraft.wiki/w/Slot#Bedrock_Edition). + +## Conclusion + +With the server animation, player behavior, and item tag all set up, your equipped item can now run commands! This technique allows for greater item customization than being restricted to item components. If you want to add more to the effect or add-on, check the next section; otherwise, congratulations, you're finished! + +## Additions + +### Multiple Required Items + +If you want to run a command when multiple of the armor set's pieces are equipped, we can expand our Molang from before: + +BP/entities/player.json#scripts + +```json +"animate": [ + { + "emerald_armor": "q.equipped_item_any_tag('slot.armor.head','example:emerald_tier') && q.equipped_item_any_tag('slot.armor.chest','example:emerald_tier') && q.equipped_item_any_tag('slot.armor.legs','example:emerald_tier') && q.equipped_item_any_tag('slot.armor.feet','example:emerald_tier')" + } +] +``` + +This example will check for emerald-tier armor in all four armor slots, and run the animation if they're all equipped. + +### Further Conditions + +The turtle shell doesn't always inflict Water Breathing, but instead only for 10 seconds when a player first enters water. If we want our emerald armor to only run our animation when we have lower health, we can add another query to our Molang: + +BP/entities/player.json#scripts + +```json +"animate": [ + { + "emerald_armor": "q.equipped_item_any_tag('slot.armor.head','example:emerald_tier') && q.health <= 5" + } +] +``` + +This example will run the animation with 2.5 hearts or less remaining, allowing players to make a quick getaway when they're in danger. + +We can also apply this to requiring multiple armor pieces, with even longer Molang: + +BP/entities/player.json#scripts + +```json +{ + "animate": [ + { + "emerald_armor": "q.equipped_item_any_tag('slot.armor.head','example:emerald_tier') && q.equipped_item_any_tag('slot.armor.chest','example:emerald_tier') && q.equipped_item_any_tag('slot.armor.legs','example:emerald_tier') && q.equipped_item_any_tag('slot.armor.feet','example:emerald_tier') && q.health <= 5" + } + ] +} +``` + +You can view a list of documented Molang queries at [bedrock.dev](https://bedrock.dev/docs/stable/Molang#List%20of%20Entity%20Queries). + +### Multiple Items with Effects + +If you want to add more items with unique effects, fret not; this is easily done. You can either create a new server animation file, or add on to the file from before, like such: + +BP/animations/player.json + +```json +{ + "format_version": "1.10.0", + "animations": { + "animation.player.emerald_armor": { + "timeline": { + "0.0": ["..."] + }, + "animation_length": 0.05, + "loop": true + }, + "animation.player.phantom_armor": { + "timeline": { + "0.0": ["..."] + }, + "animation_length": 0.05, + "loop": true + } + } +} +``` + +In our player behavior, you'll have to add on to `animations` and `scripts` as well. + +BP/entities/player.json#description + +```json +{ + "identifier": "minecraft:player", + "is_spawnable": false, + "is_summonable": false, + "is_experimental": false, + "animations": { + "emerald_armor": "animation.player.emerald_armor", + "phantom_armor": "animation.player.phantom_armor" + }, + "scripts": { + "animate": [ + { + "emerald_armor": "q.equipped_item_any_tag('slot.armor.head','example:emerald_tier')" + }, + { + "phantom_armor": "q.equipped_item_any_tag('slot.armor.head','example:phantom_tier')" + } + ] + } +} +``` diff --git a/docs/wiki/items/index.md b/docs/wiki/items/index.md new file mode 100644 index 00000000..ca56b417 --- /dev/null +++ b/docs/wiki/items/index.md @@ -0,0 +1,10 @@ +--- +title: Items +categories: + - title: General + color: blue + - title: Tutorials + color: green + - title: Documentation + color: red +--- diff --git a/docs/wiki/items/item-components.md b/docs/wiki/items/item-components.md new file mode 100644 index 00000000..9edc87a4 --- /dev/null +++ b/docs/wiki/items/item-components.md @@ -0,0 +1,510 @@ +--- +title: Item Components +description: Item components are used to change how your item appears and functions in the world. +category: General +nav_order: 2 +mentions: + - SmokeyStack + - QuazChick +--- + +:::tip FORMAT & MIN ENGINE VERSION `1.20.50` +Using the latest format version when creating custom items provides access to fresh features and improvements. The wiki aims to share up-to-date information about custom items, and currently targets format version `1.20.50`. +::: + +## Applying Components + +Item components are used to change how your item appears and functions in the world. They are applied in the `components` child of `minecraft:item`. + +BP/items/custom_item.json + +```json +{ + "format_version": "1.20.50", + "minecraft:item": { + "description": { + "identifier": "wiki:custom_item", + "menu_category": { + "category": "items" + } + }, + "components": { + "minecraft:icon": { + "texture": "custom_item" + } + } + } +} +``` + +## Allow Off Hand + +Determines whether an item can be placed in the off-hand slot of the inventory. + +minecraft:item > components + +```json +"minecraft:allow_off_hand": { + "value": true +} +``` + +## Block Placer + +Sets the item as a Planter item component for blocks. Items with this component will place a block when used. + +minecraft:item > components + +```json +"minecraft:block_placer":{ + "block": "seeds", + "use_on": [ + "dirt", + "grass" + ] +} +``` + +## Can Destroy In Creative + +Determines if an item will break blocks in Creative Mode while swinging. + +minecraft:item > components + +```json +"minecraft:can_destroy_in_creative": { + "value": true +} +``` + +## Cooldown + +Sets an items "Cool down" time. After using an item, it becomes unusable for the duration specified by the 'duration' setting of this component. + +minecraft:item > components + +```json +"minecraft:cooldown":{ + "category" : "attack", + "duration" : 0.2 +} +``` + +## Damage + +Determines how much extra damage an item does on attack. + +minecraft:item > components + +```json +"minecraft:damage": { + "value": 10 +} +``` + +## Digger + +Allows a creator to determine how quickly an item can dig specific blocks. + +minecraft:item > components + +```json +"minecraft:digger": { + "use_efficiency": true, + "destroy_speeds": [ + { + "block": { + "tags": "q.any_tag('stone', 'metal')" // Note that not all blocks have tags; listing many blocks may be necessary + }, + "speed": 6 + } + ] +} +``` + +## Display Name + +Sets the item display name within Minecraft: Bedrock Edition. This component may also be used to pull from the localization file by referencing a key from it. + +### Example + +minecraft:item > components + +```json +"minecraft:display_name":{ + "value": "secret_weapon" +} +``` + +### Example Using Localization Key + +minecraft:item > components + +```json +"minecraft:display_name":{ + "value": "item.snowball.name" +} +``` + +## Durability + +Sets how much damage the item can take before breaking, and allows the item to be combined at an anvil, grindstone, or crafting table. + +minecraft:item > components + +```json +"minecraft:durability":{ + "damage_chance": { + "min": 10, + "max": 50 + }, + "max_durability": 36 +} +``` + +## Enchantable + +Determines what enchantments can be applied to the item. Not all enchantments will have an effect on all item components. + +minecraft:item > components + +```json +"minecraft:enchantable": { + "slot": "bow", + "value": 10 +} +``` + +### Enchantable Slots +Note: The "all" enchantable slot allows you to apply any enchantment that you want to the item, just like an enchanted book. + +| Slot Name | +| ------------- | +| armor_feet | +| armor_torso | +| armor_head | +| armor_legs | +| axe | +| bow | +| cosmetic_head | +| crossbow | +| elytra | +| fishing_rod | +| flintsteel | +| hoe | +| pickaxe | +| shears | +| shield | +| shovel | +| sword | +| all | + + +## Entity Placer + +Allows an item to place entities into the world. Additionally, in version 1.19.80 and above, the component allows the item to set the spawn type of a monster spawner. + +minecraft:item > components + +```json +"minecraft:entity_placer":{ + "entity": "minecraft:spider", + "dispense_on": ["minecraft:web"], + "use_on": ["minecraft:web"] +} +``` + +## Food + +Sets the item as a food component, allowing it to be edible to the player. + +:::tip +The `minecraft:food` must have the `minecraft:use_modifiers` component in order to function properly. +::: + +minecraft:item > components + +```json +"minecraft:food":{ + "can_always_eat": false, + "nutrition" : 3, + "effects" : [ + { + "name": "poison", + "chance": 1.0, + "duration": 5, + "amplifier": 0 + } + ], + "saturation_modifier": "normal", + "using_converts_to": "bowl" +} +``` + +## Fuel + +Allows this item to be used as fuel in a furnace to 'cook' other items. + +minecraft:item > components + +```json +"minecraft:fuel":{ + "duration": 3.0 +} +``` + +## Glint + +Determines whether the item has the enchanted glint render effect on it. + +minecraft:item > components + +```json +"minecraft:glint": false +``` + +## Hand Equipped + +Determines if an item is rendered like a tool while in-hand. + +minecraft:item > components + +```json +"minecraft:hand_equipped": { + "value": true +} +``` + +## Hover Text Color + +Determines the color of the item name when hovering over it. + +minecraft:item > components + +```json +"minecraft:hover_text_color": "green" +``` + +## Icon + +Sets the icon item component. Determines the icon to represent the item in the UI and elsewhere. + +minecraft:item > components + +```json +"minecraft:icon":{ + "texture": "oak_slab" +} +``` + +## Interact Button + +Is a boolean or string that determines if the interact button is shown in touch controls, and what text is displayed on the button. When set to 'true', the default 'Use Item' text will be used. + +minecraft:item > components + +```json +"minecraft:interact_button": "Use This Custom Item" // Can be a string or a boolean value. +``` + +## Liquid Clipped + +Determines whether an item interacts with liquid blocks on use. + +minecraft:item > components + +```json +"minecraft:liquid_clipped": { + "value": true +} +``` + +## Max Stack Size + +Determines how many of an item can be stacked together. + +minecraft:item > components + +```json +"minecraft:max_stack_size": { + "value": 64 +} +``` + +## Projectile + +Compels the item to shoot, similarly to an arrow. Items with `minecraft:projectile` can be shot from dispensers or used as ammunition for items with the `minecraft:shooter` item component. Additionally, this component sets the entity that is spawned for items that also contain the `minecraft:throwable` component. + +minecraft:item > components + +```json +"minecraft:projectile":{ + "minimum_critical_power": 1.25, + "projectile_entity": "arrow" +} +``` + +## Record + +Used by record items to play music. + +minecraft:item > components + +```json +"minecraft:record": { + "comparator_signal": 1, + "duration": 5, + "sound_event": "ambient.tame" +} +``` + +### Sound Event + +Listed [here](https://learn.microsoft.com/en-us/minecraft/creator/reference/content/itemreference/examples/itemcomponents/minecraft_record?view=minecraft-bedrock-stable) are the available sounds + +## Repairable + +Defines the items that can be used to repair a defined item, and the amount of durability each item restores upon repair. Each entry needs to define a list of strings for 'items' that can be used for the repair and an optional 'repair_amount' for how much durability is repaired. + +minecraft:item > components + +```json +"minecraft:repairable":{ + "on_repaired": "minecraft:celebrate", + "repair_items": ["anvil"] +} +``` + +## Shooter + +Compels an item to shoot projectiles, similarly to a bow or crossbow. Must have the `minecraft:use_modifiers` component in order to function properly. + +:::tip +Ammunition used by `minecraft:shooter` must have the `minecraft:projectile` component in order to function properly. +::: + +minecraft:item > components + +```json +"minecraft:shooter": { + "ammunition": [ + { + "item": "custom_projectile", + "use_offhand": true, + "search_inventory": true, + "use_in_creative": true + } + ], + "max_draw_duration": 1.0, + "scale_power_by_draw_duration": true, + "charge_on_draw": false +} +``` + +## Should Despawn + +Determines if an item should despawn while floating in the world. + +minecraft:item > components + +```json +"minecraft:should_despawn": { + "value": true +} +``` + +## Stacked By Data + +Determines if the same item with different aux values can stack. Additionally, this component defines whether the item actors can merge while floating in the world. + +minecraft:item > components + +```json +"minecraft:stacked_by_data": { + "value": true +} +``` + +## Tags + +Determines which tags are included on a given item. + +minecraft:item > components + +```json +"minecraft:tags": { + "tags": [ + "custom_tag" + ] +} +``` + +## Throwable + +Sets the throwable item component. + +minecraft:item > components + +```json +"minecraft:throwable":{ + "do_swing_animation" : false, + "launch_power_scale" : 1.0, + "max_draw_duration" : 0.0, + "max_launch_power" : 1.0, + "min_draw_duration" : 0.0, + "scale_power_by_draw_duration" : false +} +``` + +## Use Animation + +Determines which animation plays when using an item. + +minecraft:item > components + +```json +"minecraft:use_animation": "eat" +``` + +## Use Modifiers + +Determines how long an item takes to use in combination with components such as Shooter, Throwable, or Food. + +minecraft:item > components + +```json +"minecraft:use_modifiers": { + "use_duration": 1.6, + "movement_modifier": 0.35 +} +``` + +## Wearable + +Sets the wearable item component. + +minecraft:item > components + +```json +"minecraft:wearable":{ + "dispensable" : true, + "slot": "slot.chest" +} +``` + +### Slots +| Slot Name | +| -------------------- | +| slot.weapon.mainhand | +| slot.weapon.offhand | +| slot.armor.head | +| slot.armor.chest | +| slot.armor.legs | +| slot.armor.feet | +| slot.hotbar | +| slot.inventory | +| slot.enderchest | +| slot.saddle | +| slot.armor | +| slot.chest | +| slot.equippable | diff --git a/docs/wiki/items/item-identifiers.md b/docs/wiki/items/item-identifiers.md new file mode 100644 index 00000000..27255a92 --- /dev/null +++ b/docs/wiki/items/item-identifiers.md @@ -0,0 +1,138 @@ +--- +title: Vanilla Item Identifiers +category: Documentation +tags: + - deprecated +mentions: + - TheDoctor15 + - Medicaljewel105 + - Luthorius + - epxzzy + - SmokeyStack +--- + +:::danger +This method no longer works after 1.18.30. +::: + +An `identifier` is a required parameter that sits inside the description of the item's behaviour file. +It accepts Vanilla Minecraft names, like so, `:`, which will apply certain hardcoded item behaviours, depending on the identifier used. + +BP/items/custom_item.json#minecraft:item + +```json +"description": { + "identifier": "wiki:totem_of_undying", + "category": "items" +} +``` + +:::warning +Not every Vanilla Identifier and their behaviours are documented. The following list may be missing important points about the known Identifiers that do affect items. + +Consider experimenting with them. +::: + +## Known Identifier Effects + +The namespace is allowed to be changed, learn more about namespaces [here](/concepts/namespaces). + +### namespace:banner + +- The item icon and model will be changed to that of the Vanilla Banner. + +--- + +### namespace:bow + +- Adds a small increasing zoom on use, for the zoom to work it requires the item to be usable. + +--- + +### namespace:crossbow + +- The item will be rotated horizontally on your arm. + +--- + +### namespace:diamond + +- Is accepted as a valid item to change the effect given off by a Beacon. + +--- + +### namespace:emerald + +- Is accepted as a valid item to change the effect given off by a Beacon. + +--- + +### namespace:filled_map + +- Will add the holding map animation. +- Can be put in a cartography table. + +--- + +### namespace:gold_ingot + +- Is accepted as a valid item to change the effect given off by a Beacon. + +--- + +### namespace:iron_ingot + +- Is accepted as a valid item to change the effect given off by a Beacon. + +--- + +### namespace:lapis_lazuli + +- Makes the Item usable with Enchantment Tables, to enchant your items in place of Lapis Lazuli. + +--- + +### namespace:lead + +- Will behave like a Lead. + +--- + +### namespace:map + +- Will use the holding map animation. + +--- + +### namespace:netherite_ingot + +- Is accepted in custom Smithing Recipes as the secondary item. +- Is accepted as a valid item to change the effect given off by a Beacon. + +--- + +### namespace:shield + +- The item icon will be permanently changed to that of the Vanilla Shield. +- Adds the shield animation and behavior. + +--- + +### namespace:spyglass + +- Makes it zoom-able like a spyglass, for the zoom to work it requires the item to be usable. + +--- + +### namespace:skull + +- The item icon will be changed to that of the Vanilla Skull. +- The item will be able to put on a armorstand and a player, the model and textures of the skull will be applied only then. + +--- + +### namespace:totem_of_undying + +- Will behave like a Totem of Undying. + +--- diff --git a/docs/wiki/items/item-tags.md b/docs/wiki/items/item-tags.md new file mode 100644 index 00000000..7b1ed8a7 --- /dev/null +++ b/docs/wiki/items/item-tags.md @@ -0,0 +1,125 @@ +--- +title: Item Tags +category: General +nav_order: 3 +mentions: + - Xterionix + - SmokeyStack +--- + +Item tags can be used to ensure that a item meets certain conditions. + +## Applying Tags + +### From 1.20.50 and onwards + + + +```json +{ + "format_version": "1.20.50", + "minecraft:item": { + "description": { + "identifier": "example:my_item" + }, + "components": { + "minecraft:tags": { + "tags": [ + "example:my_tag" + ] + } + } + } +} +``` + +### Before 1.20.50 + + + +```json +{ + "format_version": "1.16.100", + "minecraft:item": { + "description": { + "identifier": "example:my_item" + }, + "components": { + "tag:example:my_tag": {} + } + } +} +``` + +## Testing for Tags + +Tags can be queried with: + +- `q.all_tags` +- `q.any_tag` +- `q.equipped_item_all_tags` +- `q.equipped_item_any_tag` + +## Lists of Vanilla Item Tags + +Vanilla tags can be applied to custom items, and some vanilla items are tagged internally. + +| Tag | Items | +|------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| minecraft:arrow | minecraft:arrow | +| minecraft:banner | minecraft:banner | +| minecraft:boat | minecraft:birch_boat, minecraft:bamboo_raft, minecraft:cherry_chest_boat, minecraft:mangrove_boat, minecraft:bamboo_chest_raft, minecraft:jungle_chest_boat, minecraft:oak_boat, minecraft:oak_chest_boat, minecraft:dark_oak_chest_boat, minecraft:cherry_boat, minecraft:mangrove_chest_boat, minecraft:acacia_boat, minecraft:acacia_chest_boat, minecraft:jungle_boat, minecraft:spruce_chest_boat, minecraft:dark_oak_boat, minecraft:boat, minecraft:spruce_boat, minecraft:birch_chest_boat, minecraft:chest_boat | +| minecraft:boats | minecraft:birch_boat, minecraft:bamboo_raft, minecraft:cherry_chest_boat, minecraft:mangrove_boat, minecraft:bamboo_chest_raft, minecraft:jungle_chest_boat, minecraft:oak_boat, minecraft:oak_chest_boat, minecraft:dark_oak_chest_boat, minecraft:cherry_boat, minecraft:mangrove_chest_boat, minecraft:acacia_boat, minecraft:acacia_chest_boat, minecraft:jungle_boat, minecraft:spruce_chest_boat, minecraft:dark_oak_boat, minecraft:boat, minecraft:spruce_boat, minecraft:birch_chest_boat, minecraft:chest_boat | +| minecraft:bookshelf_books | minecraft:writable_book, minecraft:book, minecraft:enchanted_book | +| minecraft:chainmail_tier | minecraft:chainmail_leggings, minecraft:chainmail_helmet, minecraft:chainmail_chestplate, minecraft:chainmail_boots | +| minecraft:coals | minecraft:coal, minecraft:charcoal | +| minecraft:crimson_stems | minecraft:stripped_crimson_stem, minecraft:stripped_crimson_hyphae, minecraft:crimson_stem, minecraft:crimson_hyphae | +| minecraft:decorated_pot_sherds | minecraft:friend_pottery_sherd, minecraft:archer_pottery_sherd, minecraft:burn_pottery_sherd, minecraft:heart_pottery_sherd, minecraft:arms_up_pottery_sherd, minecraft:brick, minecraft:danger_pottery_sherd, minecraft:heartbreak_pottery_sherd, minecraft:shelter_pottery_sherd, minecraft:explorer_pottery_sherd, minecraft:prize_pottery_sherd, minecraft:skull_pottery_sherd, minecraft:sheaf_pottery_sherd, minecraft:angler_pottery_sherd, minecraft:blade_pottery_sherd, minecraft:brewer_pottery_sherd, minecraft:howl_pottery_sherd, minecraft:miner_pottery_sherd, minecraft:mourner_pottery_sherd, minecraft:plenty_pottery_sherd, minecraft:snort_pottery_sherd | +| minecraft:diamond_tier | minecraft:diamond_chestplate, minecraft:diamond_boots, minecraft:diamond_helmet, minecraft:diamond_pickaxe, minecraft:diamond_leggings, minecraft:diamond_sword, minecraft:diamond_axe, minecraft:diamond_shovel, minecraft:diamond_hoe | +| minecraft:digger | minecraft:wooden_pickaxe, minecraft:golden_pickaxe, minecraft:netherite_hoe, minecraft:wooden_shovel, minecraft:wooden_hoe, minecraft:golden_axe, minecraft:iron_axe, minecraft:netherite_pickaxe, minecraft:iron_hoe, minecraft:wooden_axe, minecraft:stone_hoe, minecraft:stone_shovel, minecraft:stone_axe, minecraft:diamond_pickaxe, minecraft:netherite_axe, minecraft:diamond_axe, minecraft:stone_pickaxe, minecraft:iron_pickaxe, minecraft:iron_shovel, minecraft:golden_shovel, minecraft:diamond_shovel, minecraft:netherite_shovel, minecraft:golden_hoe, minecraft:diamond_hoe | +| minecraft:door | minecraft:wooden_door, minecraft:iron_door, minecraft:warped_door, minecraft:dark_oak_door, minecraft:crimson_door, minecraft:acacia_door, minecraft:jungle_door, minecraft:spruce_door, minecraft:birch_door, minecraft:mangrove_door, minecraft:cherry_door, minecraft:bamboo_door | +| minecraft:golden_tier | minecraft:golden_pickaxe, minecraft:golden_axe, minecraft:golden_chestplate, minecraft:golden_leggings, minecraft:golden_sword, minecraft:golden_helmet, minecraft:golden_boots, minecraft:golden_shovel, minecraft:golden_hoe | +| minecraft:hanging_actor | minecraft:painting | +| minecraft:hanging_sign | minecraft:warped_hanging_sign, minecraft:crimson_hanging_sign, minecraft:acacia_hanging_sign, minecraft:bamboo_hanging_sign, minecraft:dark_oak_hanging_sign, minecraft:jungle_hanging_sign, minecraft:cherry_hanging_sign, minecraft:oak_hanging_sign, minecraft:birch_hanging_sign, minecraft:mangrove_hanging_sign, minecraft:spruce_hanging_sign | +| minecraft:horse_armor | minecraft:diamond_horse_armor, minecraft:iron_horse_armor, minecraft:leather_horse_armor, minecraft:golden_horse_armor | +| minecraft:iron_tier | minecraft:iron_boots, minecraft:iron_axe, minecraft:iron_hoe, minecraft:iron_leggings, minecraft:iron_chestplate, minecraft:iron_sword, minecraft:iron_helmet, minecraft:iron_pickaxe, minecraft:iron_shovel | +| minecraft:is_armor | minecraft:iron_boots, minecraft:turtle_helmet, minecraft:chainmail_leggings, minecraft:diamond_chestplate, minecraft:diamond_boots, minecraft:leather_boots, minecraft:golden_chestplate, minecraft:netherite_helmet, minecraft:golden_leggings, minecraft:iron_leggings, minecraft:diamond_helmet, minecraft:iron_chestplate, minecraft:chainmail_helmet, minecraft:leather_helmet, minecraft:chainmail_chestplate, minecraft:elytra, minecraft:netherite_chestplate, minecraft:netherite_leggings, minecraft:netherite_boots, minecraft:leather_leggings, minecraft:chainmail_boots, minecraft:iron_helmet, minecraft:golden_helmet, minecraft:leather_chestplate, minecraft:diamond_leggings, minecraft:golden_boots | +| minecraft:is_axe | minecraft:golden_axe, minecraft:iron_axe, minecraft:wooden_axe, minecraft:stone_axe minecraft:netherite_axe, minecraft:diamond_axe | +| minecraft:is_cooked | minecraft:cooked_porkchop, minecraft:rabbit_stew, minecraft:cooked_salmon, minecraft:cooked_cod, minecraft:cooked_chicken, minecraft:cooked_beef, minecraft:cooked_mutton, minecraft:cooked_rabbit | +| minecraft:is_fish | minecraft:salmon, minecraft:cooked_salmon, minecraft:pufferfish, minecraft:cooked_cod, minecraft:tropical_fish, minecraft:cod | +| minecraft:is_food | minecraft:cookie, minecraft:sweet_berries, minecraft:cooked_porkchop, minecraft:carrot, minecraft:enchanted_golden_apple, minecraft:golden_carrot, minecraft:golden_apple, minecraft:beetroot_soup, minecraft:rabbit_stew, minecraft:chicken, minecraft:porkchop, minecraft:beef, minecraft:bread, minecraft:beetroot, minecraft:potato, minecraft:dried_kelp, minecraft:cooked_chicken, minecraft:apple, minecraft:melon_slice, minecraft:mutton, minecraft:rabbit, minecraft:rotten_flesh, minecraft:cooked_beef, minecraft:cooked_mutton, minecraft:cooked_rabbit, minecraft:mushroom_stew, minecraft:baked_potato, minecraft:pumpkin_pie | +| minecraft:is_hoe | minecraft:netherite_hoe, minecraft:wooden_hoe, minecraft:iron_hoe, minecraft:stone_hoe, minecraft:golden_hoe, minecraft:diamond_hoe | +| minecraft:is_meat | minecraft:cooked_porkchop, minecraft:rabbit_stew, minecraft:chicken, minecraft:porkchop, minecraft:beef, minecraft:cooked_chicken, minecraft:mutton, minecraft:rabbit, minecraft:rotten_flesh, minecraft:cooked_beef, minecraft:cooked_mutton, minecraft:cooked_rabbit | +| minecraft:is_minecart | minecraft:tnt_minecart, minecraft:command_block_minecart, minecraft:chest_minecart, minecraft:minecart, minecraft:hopper_minecart | +| minecraft:is_pickaxe | minecraft:wooden_pickaxe, minecraft:golden_pickaxe, minecraft:netherite_pickaxe, minecraft:diamond_pickaxe, minecraft:stone_pickaxe, minecraft:iron_pickaxe | +| minecraft:is_shovel | minecraft:wooden_shovel, minecraft:stone_shovel, minecraft:iron_shovel, minecraft:golden_shovel, minecraft:diamond_shovel, minecraft:netherite_shovel | +| minecraft:is_sword | minecraft:netherite_sword, minecraft:stone_sword, minecraft:iron_sword, minecraft:golden_sword, minecraft:wooden_sword, minecraft:diamond_sword | +| minecraft:is_tool | minecraft:wooden_pickaxe, minecraft:golden_pickaxe, minecraft:netherite_sword, minecraft:netherite_hoe, minecraft:wooden_shovel, minecraft:wooden_hoe, minecraft:stone_sword, minecraft:golden_axe, minecraft:iron_axe, minecraft:netherite_pickaxe, minecraft:iron_hoe, minecraft:wooden_axe, minecraft:iron_sword, minecraft:stone_hoe, minecraft:stone_shovel, minecraft:golden_sword, minecraft:stone_axe, minecraft:diamond_pickaxe, minecraft:netherite_axe, minecraft:wooden_sword, minecraft:diamond_sword, minecraft:diamond_axe, minecraft:stone_pickaxe, minecraft:iron_pickaxe, minecraft:iron_shovel, minecraft:golden_shovel, minecraft:diamond_shovel, minecraft:netherite_shovel, minecraft:golden_hoe, minecraft:diamond_hoe | +| minecraft:is_trident | minecraft:trident | +| minecraft:leather_tier | minecraft:leather_boots, minecraft:leather_helmet, minecraft:leather_leggings, minecraft:leather_chestplate | +| minecraft:lectern_books | minecraft:writable_book | +| minecraft:logs | minecraft:dark_oak_log, minecraft:warped_stem, minecraft:stripped_warped_stem, minecraft:mangrove_log, minecraft:jungle_log, minecraft:birch_log, minecraft:stripped_crimson_stem, minecraft:stripped_jungle_log, minecraft:stripped_crimson_hyphae, minecraft:oak_log, minecraft:wood, minecraft:warped_hyphae, minecraft:stripped_oak_log, minecraft:stripped_cherry_wood, minecraft:stripped_mangrove_wood, minecraft:stripped_cherry_log, minecraft:stripped_warped_hyphae, minecraft:crimson_stem, minecraft:stripped_birch_log, minecraft:crimson_hyphae, minecraft:stripped_dark_oak_log, minecraft:stripped_acacia_log, minecraft:stripped_mangrove_log, minecraft:stripped_spruce_log, minecraft:spruce_log, minecraft:acacia_log, minecraft:mangrove_wood, minecraft:cherry_log, minecraft:cherry_wood, minecraft:log, minecraft:log2 | +| minecraft:logs_that_burn | minecraft:dark_oak_log, minecraft:mangrove_log, minecraft:jungle_log, minecraft:birch_log, minecraft:stripped_jungle_log, minecraft:oak_log, minecraft:wood, minecraft:stripped_oak_log, minecraft:stripped_cherry_wood, minecraft:stripped_mangrove_wood, minecraft:stripped_cherry_log, minecraft:stripped_birch_log, minecraft:stripped_dark_oak_log, minecraft:stripped_acacia_log, minecraft:stripped_mangrove_log, minecraft:stripped_spruce_log, minecraft:spruce_log, minecraft:acacia_log, minecraft:mangrove_wood, minecraft:cherry_log, minecraft:cherry_wood, minecraft:log, minecraft:log2 | +| minecraft:mangrove_logs | minecraft:mangrove_log, minecraft:stripped_mangrove_wood, minecraft:stripped_mangrove_log, minecraft:mangrove_wood | +| minecraft:music_disc | minecraft:music_disc_strad, minecraft:music_disc_11, minecraft:music_disc_mellohi, minecraft:music_disc_otherside, minecraft:music_disc_wait, minecraft:music_disc_relic, minecraft:music_disc_5, minecraft:music_disc_stal, minecraft:music_disc_pigstep, minecraft:music_disc_blocks, minecraft:music_disc_cat, minecraft:music_disc_far, minecraft:music_disc_13, minecraft:music_disc_chirp, minecraft:music_disc_mall, minecraft:music_disc_ward | +| minecraft:netherite_tier | minecraft:netherite_sword, minecraft:netherite_hoe, minecraft:netherite_pickaxe, minecraft:netherite_helmet, minecraft:netherite_chestplate, minecraft:netherite_leggings, minecraft:netherite_boots, minecraft:netherite_axe, minecraft:netherite_shovel | +| minecraft:planks | minecraft:dark_oak_planks, minecraft:spruce_planks, minecraft:oak_planks, minecraft:birch_planks, minecraft:acacia_planks, minecraft:bamboo_planks, minecraft:jungle_planks, minecraft:warped_planks, minecraft:mangrove_planks, minecraft:cherry_planks, minecraft:crimson_planks, minecraft:planks | +| minecraft:sand | minecraft:sand | +| minecraft:sign | minecraft:oak_sign, minecraft:jungle_sign, minecraft:warped_hanging_sign, minecraft:cherry_sign, minecraft:birch_sign, minecraft:crimson_hanging_sign, minecraft:acacia_hanging_sign, minecraft:bamboo_hanging_sign, minecraft:dark_oak_hanging_sign, minecraft:acacia_sign, minecraft:jungle_hanging_sign, minecraft:spruce_sign, minecraft:dark_oak_sign, minecraft:cherry_hanging_sign, minecraft:oak_hanging_sign, minecraft:mangrove_sign, minecraft:birch_hanging_sign, minecraft:mangrove_hanging_sign, minecraft:bamboo_sign, minecraft:crimson_sign, minecraft:warped_sign, minecraft:spruce_hanging_sign | +| minecraft:soul_fire_base_blocks | minecraft:soul_sand, minecraft:soul_soil | +| minecraft:spawn_egg | minecraft:blaze_spawn_egg, minecraft:piglin_brute_spawn_egg, minecraft:ghast_spawn_egg, minecraft:bee_spawn_egg, minecraft:hoglin_spawn_egg, minecraft:wolf_spawn_egg, minecraft:rabbit_spawn_egg, minecraft:drowned_spawn_egg, minecraft:ender_dragon_spawn_egg, minecraft:glow_squid_spawn_egg, minecraft:fox_spawn_egg, minecraft:pig_spawn_egg, minecraft:piglin_spawn_egg, minecraft:ravager_spawn_egg, minecraft:endermite_spawn_egg, minecraft:frog_spawn_egg, minecraft:elder_guardian_spawn_egg, minecraft:iron_golem_spawn_egg, minecraft:axolotl_spawn_egg, minecraft:panda_spawn_egg, minecraft:spider_spawn_egg, minecraft:strider_spawn_egg, minecraft:chicken_spawn_egg, minecraft:cod_spawn_egg, minecraft:shulker_spawn_egg, minecraft:pillager_spawn_egg, minecraft:slime_spawn_egg, minecraft:salmon_spawn_egg, minecraft:creeper_spawn_egg, minecraft:polar_bear_spawn_egg, minecraft:llama_spawn_egg, minecraft:goat_spawn_egg, minecraft:trader_llama_spawn_egg, minecraft:wither_spawn_egg, minecraft:parrot_spawn_egg, minecraft:horse_spawn_egg, minecraft:sniffer_spawn_egg, minecraft:husk_spawn_egg, minecraft:bat_spawn_egg, minecraft:turtle_spawn_egg, minecraft:sheep_spawn_egg, minecraft:tropical_fish_spawn_egg, minecraft:evoker_spawn_egg, minecraft:vex_spawn_egg, minecraft:skeleton_horse_spawn_egg, minecraft:tadpole_spawn_egg, minecraft:cow_spawn_egg, minecraft:villager_spawn_egg, minecraft:cat_spawn_egg, minecraft:warden_spawn_egg, minecraft:skeleton_spawn_egg, minecraft:cave_spider_spawn_egg, minecraft:magma_cube_spawn_egg, minecraft:zombie_pigman_spawn_egg, minecraft:pufferfish_spawn_egg, minecraft:wandering_trader_spawn_egg, minecraft:dolphin_spawn_egg, minecraft:spawn_egg, minecraft:ocelot_spawn_egg, minecraft:mooshroom_spawn_egg, minecraft:donkey_spawn_egg, minecraft:mule_spawn_egg, minecraft:zombie_horse_spawn_egg, minecraft:enderman_spawn_egg, minecraft:silverfish_spawn_egg, minecraft:wither_skeleton_spawn_egg, minecraft:stray_spawn_egg, minecraft:zombie_spawn_egg, minecraft:squid_spawn_egg, minecraft:witch_spawn_egg, minecraft:guardian_spawn_egg, minecraft:zoglin_spawn_egg, minecraft:allay_spawn_egg, minecraft:camel_spawn_egg, minecraft:vindicator_spawn_egg, minecraft:zombie_villager_spawn_egg, minecraft:phantom_spawn_egg, minecraft:snow_golem_spawn_egg | +| minecraft:stone_bricks | minecraft:stonebrick | +| minecraft:stone_crafting_materials | minecraft:cobbled_deepslate, minecraft:cobblestone, minecraft:blackstone | +| minecraft:stone_tier | minecraft:stone_sword, minecraft:stone_hoe, minecraft:stone_shovel, minecraft:stone_axe, minecraft:stone_pickaxe | +| minecraft:stone_tool_materials | minecraft:cobbled_deepslate, minecraft:cobblestone, minecraft:blackstone | +| minecraft:transform_materials | minecraft:netherite_ingot | +| minecraft:transform_templates | minecraft:netherite_upgrade_smithing_template | +| minecraft:transformable_items | minecraft:diamond_chestplate, minecraft:diamond_boots, minecraft:diamond_helmet, minecraft:diamond_pickaxe, minecraft:diamond_leggings, minecraft:golden_boots, minecraft:diamond_sword, minecraft:diamond_axe, minecraft:diamond_shovel, minecraft:diamond_hoe | +| minecraft:transformable_items | minecraft:gold_ingot, minecraft:redstone, minecraft:diamond, minecraft:netherite_ingot, minecraft:copper_ingot, minecraft:lapis_lazuli, minecraft:emerald, minecraft:iron_ingot, minecraft:amethyst_shard, minecraft:quartz | +| minecraft:trim_templates | minecraft:eye_armor_trim_smithing_template, minecraft:raiser_armor_trim_smithing_template, minecraft:sentry_armor_trim_smithing_template, minecraft:host_armor_trim_smithing_template, minecraft:snout_armor_trim_smithing_template, minecraft:spire_armor_trim_smithing_template, minecraft:wayfinder_armor_trim_smithing_template, minecraft:ward_armor_trim_smithing_template, minecraft:vex_armor_trim_smithing_template, minecraft:wild_armor_trim_smithing_template, minecraft:coast_armor_trim_smithing_template, minecraft:dune_armor_trim_smithing_template, minecraft:shaper_armor_trim_smithing_template, minecraft:silence_armor_trim_smithing_template, minecraft:tide_armor_trim_smithing_template, minecraft:rib_armor_trim_smithing_template | +| minecraft:trimmable_armors | minecraft:iron_boots, minecraft:turtle_helmet, minecraft:chainmail_leggings, minecraft:diamond_chestplate, minecraft:diamond_boots, minecraft:leather_boots, minecraft:golden_chestplate, minecraft:netherite_helmet, minecraft:golden_leggings, minecraft:iron_leggings, minecraft:diamond_helmet, minecraft:iron_chestplate, minecraft:chainmail_helmet, minecraft:leather_helmet, minecraft:chainmail_chestplate, minecraft:netherite_chestplate, minecraft:netherite_leggings, minecraft:netherite_boots, minecraft:leather_leggings, minecraft:chainmail_boots, minecraft:iron_helmet, minecraft:golden_helmet, minecraft:leather_chestplate, minecraft:diamond_leggings, minecraft:golden_boots | +| minecraft:vibration_damper | minecraft:white_wool, minecraft:green_wool, minecraft:magenta_wool, minecraft:gray_wool, minecraft:orange_wool, minecraft:orange_carpet, minecraft:gray_carpet, minecraft:red_carpet, minecraft:cyan_carpet, minecraft:light_gray_wool, minecraft:red_wool, minecraft:pink_wool, minecraft:brown_wool, minecraft:purple_carpet, minecraft:light_blue_carpet, minecraft:white_carpet, minecraft:black_wool, minecraft:wool, minecraft:light_blue_wool, minecraft:light_gray_carpet, minecraft:yellow_wool, minecraft:lime_wool, minecraft:cyan_wool, minecraft:black_carpet, minecraft:blue_wool, minecraft:purple_wool, minecraft:pink_carpet, minecraft:brown_carpet, minecraft:green_carpet, minecraft:yellow_carpet, minecraft:lime_carpet, minecraft:blue_carpet, minecraft:magenta_carpet, minecraft:carpet | +| minecraft:warped_stems | minecraft:warped_stem, minecraft:stripped_warped_stem, minecraft:warped_hyphae, minecraft:stripped_warped_hyphae | +| minecraft:wooden_slabs | minecraft:warped_slab, minecraft:wooden_slab, minecraft:crimson_slab, minecraft:bamboo_slab, minecraft:mangrove_slab, minecraft:cherry_slab | +| minecraft:wooden_tier | minecraft:wooden_pickaxe, minecraft:wooden_shovel, minecraft:wooden_hoe, minecraft:wooden_axe, minecraft:wooden_sword | +| minecraft:wool | minecraft:white_wool, minecraft:green_wool, minecraft:magenta_wool, minecraft:gray_wool, minecraft:orange_wool, minecraft:light_gray_wool, minecraft:red_wool, minecraft:pink_wool, minecraft:brown_wool, minecraft:black_wool, minecraft:wool, minecraft:light_blue_wool, minecraft:yellow_wool, minecraft:lime_wool, minecraft:cyan_wool, minecraft:blue_wool, minecraft:purple_wool | diff --git a/docs/wiki/items/items-intro.md b/docs/wiki/items/items-intro.md new file mode 100644 index 00000000..2a0fee34 --- /dev/null +++ b/docs/wiki/items/items-intro.md @@ -0,0 +1,156 @@ +--- +title: Intro to Items +description: A "Hello world" guide in making items. Learn the item format and how to create basic custom items. +category: General +nav_order: 1 +tags: + - guide + - beginner +mentions: + - SirLich + - solvedDev + - Joelant05 + - yanasakana + - destruc7ion + - aexer0e + - stirante + - ChibiMango + - MedicalJewel105 + - Sprunkles317 + - mark-wiemer + - TheItsNameless + - s1050613 + - SmokeyStack +--- + +Minecraft Bedrock allows us to add custom items into our world with various vanilla-like properties + +This tutorial will cover how to create basic items for the stable version of Minecraft. + +## Registering Items + +Item definitions are structured similarly to entities: they contain a description and a list of components that defines the item's behavior. + +Below is the **minimum** behavior-side code to get a custom item into the creative inventory. + +BP/items/custom_item.json + +```json +{ + "format_version": "1.20.50", + "minecraft:item": { + "description": { + "identifier": "wiki:custom_item", + "menu_category": { + "category": "construction" + } + }, + "components": {} // Must be here, even if empty! + } +} +``` + +### Item Description + +- Defines the item's identifier - a unique ID in the format of `namespace:identifier`. +- Configures which `menu_category` the item is placed into. + - Also takes the optional parameters `group` and `is_hidden_in_commands`. + +## Adding Components + +Right now, our custom item is using the default component values (which can be found [here](/items/item-components)). + +Let's configure our own functionality! + +BP/items/custom_item.json + +```json +{ + "format_version": "1.20.50", + "minecraft:item": { + "description": { + "identifier": "wiki:custom_item", + "menu_category": { + "category": "construction" + } + }, + "components": { + "minecraft:damage": { + "value": 10 + }, + "minecraft:durability":{ + "max_durability": 36 + }, + "minecraft:hand_equipped": { + "value": true + } + } + } +} +``` + +Browse more item components [here](/items/item-components)! + +## Applying Textures + +We need to create a texture shortname to link it to an image in `RP/textures/item_texture.json`. + +RP/textures/item_texture.json + +```json +{ + "resource_pack_name": "wiki", + "texture_name": "atlas.items", + "texture_data": { + "custom_item": { + "textures": "textures/items/custom_item" + } + } +} +``` + +In our item file, we will add the `minecraft:icon` component to apply the texture. + +BP/items/custom_item.json + +```json +{ + "format_version": "1.20.50", + "minecraft:item": { + "description": { + "identifier": "wiki:custom_item", + "menu_category": { + "category": "construction" + } + }, + "components": { + "minecraft:icon": { + "texture": "custom_item" + } + } + } +} +``` + +## Defining Names + +Finally, we will give our item a name. Additionally, you can use the [Display Name](/items/item-components#display_name) component. + +RP/texts/en_US.lang + +```c +tile.wiki:custom_item.name=Custom Item +``` + +## Result + +In this page, you've learnt about the following: + + + +- [x] Basic features of items +- [x] How to apply a texture +- [x] How to link textures using shortnames in `item_textures.json` +- [x] How to define names in the language file + + \ No newline at end of file diff --git a/docs/wiki/items/numerical-item-ids.md b/docs/wiki/items/numerical-item-ids.md new file mode 100644 index 00000000..926e46ea --- /dev/null +++ b/docs/wiki/items/numerical-item-ids.md @@ -0,0 +1,1422 @@ +--- +title: Numerical Item IDs +category: Documentation +--- + +::: tip +This page is a more up-to-date version of [this page](https://learn.microsoft.com/en-us/minecraft/creator/reference/content/addonsreference/examples/addonitems), and is current as of version 1.20.51. +::: + +## Overview + +Item IDs (not to be confused with type IDs) are an older system which are mainly used to render items with [JSON UI](/json-ui/json-ui-documentation#item-id-aux-item-id-aux) nowadays. All items & blocks (Even custom ones!) have their own unique ID. + +## ID Formatting +- Vanilla items & blocks have IDs from `-743` to `721`. +- All custom blocks have *increasingly negative* IDs, starting from an ID of `-744`. These do not interfere with vanilla IDs in any way. Note that custom blocks do not currently render with their IDs. It is unknown if this is a bug or not. +- All non-experimental items (1.10 format) have *increasingly positive* IDs, starting from an ID of `722`. These do not interfere with vanilla IDs in any way. +- All experimental items (1.16.100 format) have *increasingly positive* IDs, starting from an ID of 257. These **WILL SHIFT VANILLA IDs** that are higher than 256. For example, `'minecraft:apple'` (ID of `257`) will be moved up to an ID of `258` if you have one experimental item. + +## Vanilla ID List +Note for this list that a namespace of `minecraft:` is assumed for all items & blocks. + +| Name | ID | +| ----------------- | :--: | +| dark_oak_planks | -743 | +| acacia_planks | -742 | +| jungle_planks | -741 | +| birch_planks | -740 | +| spruce_planks | -739 | +| black_terracotta | -738 | +| red_terracotta | -737 | +| green_terracotta | -736 | +| brown_terracotta | -735 | +| blue_terracotta | -734 | +| purple_terracotta | -733 | +| cyan_terracotta | -732 | +| light_gray_terracotta | -731 | +| gray_terracotta | -730 | +| pink_terracotta | -729 | +| lime_terracotta | -728 | +| yellow_terracotta | -727 | +| light_blue_terracotta | -726 | +| magenta_terracotta | -725 | +| orange_terracotta | -724 | +| black_concrete_powder | -723 | +| red_concrete_powder | -722 | +| green_concrete_powder | -721 | +| brown_concrete_powder | -720 | +| blue_concrete_powder | -719 | +| purple_concrete_powder | -718 | +| cyan_concrete_powder | -717 | +| light_gray_concrete_powder | -716 | +| gray_concrete_powder | -715 | +| pink_concrete_powder | -714 | +| lime_concrete_powder | -713 | +| yellow_concrete_powder | -712 | +| light_blue_concrete_powder | -711 | +| magenta_concrete_powder | -710 | +| orange_concrete_powder | -709 | +| black_stained_glass | -687 | +| red_stained_glass | -686 | +| green_stained_glass | -685 | +| brown_stained_glass | -684 | +| blue_stained_glass | -683 | +| purple_stained_glass | -682 | +| cyan_stained_glass | -681 | +| light_gray_stained_glass | -680 | +| gray_stained_glass | -679 | +| pink_stained_glass | -678 | +| lime_stained_glass | -677 | +| yellow_stained_glass | -676 | +| light_blue_stained_glass | -675 | +| magenta_stained_glass | -674 | +| orange_stained_glass | -673 | +| black_stained_glass_pane | -657 | +| red_stained_glass_pane | -656 | +| green_stained_glass_pane | -655 | +| brown_stained_glass_pane | -654 | +| blue_stained_glass_pane | -653 | +| purple_stained_glass_pane | -652 | +| cyan_stained_glass_pane | -651 | +| light_gray_stained_glass_pane | -650 | +| gray_stained_glass_pane | -649 | +| pink_stained_glass_pane | -648 | +| lime_stained_glass_pane | -647 | +| yellow_stained_glass_pane | -646 | +| light_blue_stained_glass_pane | -645 | +| magenta_stained_glass_pane | -644 | +| orange_stained_glass_pane | -643 | +| black_concrete | -642 | +| red_concrete | -641 | +| green_concrete | -640 | +| brown_concrete | -639 | +| blue_concrete | -638 | +| purple_concrete | -637 | +| cyan_concrete | -636 | +| light_gray_concrete | -635 | +| gray_concrete | -634 | +| pink_concrete | -633 | +| lime_concrete | -632 | +| yellow_concrete | -631 | +| light_blue_concrete | -630 | +| magenta_concrete | -629 | +| orange_concrete | -628 | +| black_shulker_box | -627 | +| red_shulker_box | -626 | +| green_shulker_box | -625 | +| brown_shulker_box | -624 | +| blue_shulker_box | -623 | +| purple_shulker_box | -622 | +| cyan_shulker_box | -621 | +| light_gray_shulker_box | -620 | +| gray_shulker_box | -619 | +| pink_shulker_box | -618 | +| lime_shulker_box | -617 | +| yellow_shulker_box | -616 | +| light_blue_shulker_box | -615 | +| magenta_shulker_box | -614 | +| orange_shulker_box | -613 | +| pitcher_plant | -612 | +| black_carpet | -611 | +| red_carpet | -610 | +| green_carpet | -609 | +| brown_carpet | -608 | +| blue_carpet | -607 | +| purple_carpet | -606 | +| cyan_carpet | -605 | +| light_gray_carpet | -604 | +| gray_carpet | -603 | +| pink_carpet | -602 | +| lime_carpet | -601 | +| yellow_carpet | -600 | +| light_blue_carpet | -599 | +| magenta_carpet | -598 | +| orange_carpet | -597 | +| sniffer_egg | -596 | +| dead_horn_coral | -589 | +| dead_fire_coral | -588 | +| dead_bubble_coral | -587 | +| dead_brain_coral | -586 | +| dead_tube_coral | -585 | +| horn_coral | -584 | +| fire_coral | -583 | +| bubble_coral | -582 | +| brain_coral | -581 | +| calibrated_sculk_sensor | -580 | +| spruce_fence | -579 | +| jungle_fence | -578 | +| dark_oak_fence | -577 | +| birch_fence | -576 | +| acacia_fence | -575 | +| pitcher_crop | -574 | +| suspicious_gravel | -573 | +| dark_oak_log | -572 | +| jungle_log | -571 | +| birch_log | -570 | +| spruce_log | -569 | +| torchflower | -568 | +| torchflower_crop | -567 | +| pink_wool | -566 | +| magenta_wool | -565 | +| purple_wool | -564 | +| blue_wool | -563 | +| light_blue_wool | -562 | +| cyan_wool | -561 | +| green_wool | -560 | +| lime_wool | -559 | +| yellow_wool | -558 | +| orange_wool | -557 | +| red_wool | -556 | +| brown_wool | -555 | +| black_wool | -554 | +| gray_wool | -553 | +| light_gray_wool | -552 | +| decorated_pot | -551 | +| pink_petals | -549 | +| cherry_leaves | -548 | +| cherry_sapling | -547 | +| cherry_wood | -546 | +| stripped_cherry_wood | -545 | +| cherry_wall_sign | -544 | +| cherry_trapdoor | -543 | +| cherry_standing_sign | -542 | +| cherry_stairs | -541 | +| cherry_double_slab | -540 | +| cherry_slab | -539 | +| cherry_pressure_plate | -538 | +| cherry_planks | -537 | +| cherry_log | -536 | +| stripped_cherry_log | -535 | +| cherry_hanging_sign | -534 | +| cherry_fence_gate | -533 | +| cherry_fence | -532 | +| cherry_door | -531 | +| cherry_button | -530 | +| suspicious_sand | -529 | +| stripped_bamboo_block | -528 | +| bamboo_block | -527 | +| chiseled_bookshelf | -526 | +| bamboo_mosaic_double_slab | -525 | +| bamboo_mosaic_slab | -524 | +| bamboo_mosaic_stairs | -523 | +| bamboo_hanging_sign | -522 | +| bamboo_double_slab | -521 | +| bamboo_trapdoor | -520 | +| bamboo_wall_sign | -519 | +| bamboo_standing_sign | -518 | +| bamboo_door | -517 | +| bamboo_fence_gate | -516 | +| bamboo_fence | -515 | +| bamboo_pressure_plate | -514 | +| bamboo_slab | -513 | +| bamboo_stairs | -512 | +| bamboo_button | -511 | +| bamboo_planks | -510 | +| bamboo_mosaic | -509 | +| mangrove_hanging_sign | -508 | +| warped_hanging_sign | -507 | +| crimson_hanging_sign | -506 | +| dark_oak_hanging_sign | -505 | +| acacia_hanging_sign | -504 | +| jungle_hanging_sign | -503 | +| birch_hanging_sign | -502 | +| spruce_hanging_sign | -501 | +| oak_hanging_sign | -500 | +| mangrove_double_slab | -499 | +| stripped_mangrove_wood | -498 | +| mangrove_wood | -497 | +| mangrove_trapdoor | -496 | +| mangrove_wall_sign | -495 | +| mangrove_standing_sign | -494 | +| mangrove_door | -493 | +| mangrove_fence_gate | -492 | +| mangrove_fence | -491 | +| mangrove_pressure_plate | -490 | +| mangrove_slab | -489 | +| mangrove_stairs | -488 | +| mangrove_button | -487 | +| mangrove_planks | -486 | +| stripped_mangrove_log | -485 | +| mangrove_log | -484 | +| muddy_mangrove_roots | -483 | +| mangrove_roots | -482 | +| mud_brick_wall | -481 | +| mud_brick_stairs | -480 | +| mud_brick_double_slab | -479 | +| mud_brick_slab | -478 | +| packed_mud | -477 | +| mud_bricks | -475 | +| mangrove_propagule | -474 | +| mud | -473 | +| mangrove_leaves | -472 | +| ochre_froglight | -471 | +| verdant_froglight | -470 | +| pearlescent_froglight | -469 | +| frog_spawn | -468 | +| reinforced_deepslate | -466 | +| client_request_placeholder_block | -465 | +| sculk_shrieker | -461 | +| sculk_catalyst | -460 | +| sculk_vein | -459 | +| sculk | -458 | +| infested_deepslate | -454 | +| raw_gold_block | -453 | +| raw_copper_block | -452 | +| raw_iron_block | -451 | +| waxed_oxidized_double_cut_copper_slab | -450 | +| waxed_oxidized_cut_copper_slab | -449 | +| waxed_oxidized_cut_copper_stairs | -448 | +| waxed_oxidized_cut_copper | -447 | +| waxed_oxidized_copper | -446 | +| black_candle_cake | -445 | +| red_candle_cake | -444 | +| green_candle_cake | -443 | +| brown_candle_cake | -442 | +| blue_candle_cake | -441 | +| purple_candle_cake | -440 | +| cyan_candle_cake | -439 | +| light_gray_candle_cake | -438 | +| gray_candle_cake | -437 | +| pink_candle_cake | -436 | +| lime_candle_cake | -435 | +| yellow_candle_cake | -434 | +| light_blue_candle_cake | -433 | +| magenta_candle_cake | -432 | +| orange_candle_cake | -431 | +| white_candle_cake | -430 | +| candle_cake | -429 | +| black_candle | -428 | +| red_candle | -427 | +| green_candle | -426 | +| brown_candle | -425 | +| blue_candle | -424 | +| purple_candle | -423 | +| cyan_candle | -422 | +| light_gray_candle | -421 | +| gray_candle | -420 | +| pink_candle | -419 | +| lime_candle | -418 | +| yellow_candle | -417 | +| light_blue_candle | -416 | +| magenta_candle | -415 | +| orange_candle | -414 | +| white_candle | -413 | +| candle | -412 | +| glow_lichen | -411 | +| cracked_deepslate_bricks | -410 | +| cracked_deepslate_tiles | -409 | +| deepslate_copper_ore | -408 | +| deepslate_emerald_ore | -407 | +| deepslate_coal_ore | -406 | +| deepslate_diamond_ore | -405 | +| lit_deepslate_redstone_ore | -404 | +| deepslate_redstone_ore | -403 | +| deepslate_gold_ore | -402 | +| deepslate_iron_ore | -401 | +| deepslate_lapis_ore | -400 | +| deepslate_brick_double_slab | -399 | +| deepslate_tile_double_slab | -398 | +| polished_deepslate_double_slab | -397 | +| cobbled_deepslate_double_slab | -396 | +| chiseled_deepslate | -395 | +| deepslate_brick_wall | -394 | +| deepslate_brick_stairs | -393 | +| deepslate_brick_slab | -392 | +| deepslate_bricks | -391 | +| deepslate_tile_wall | -390 | +| deepslate_tile_stairs | -389 | +| deepslate_tile_slab | -388 | +| deepslate_tiles | -387 | +| polished_deepslate_wall | -386 | +| polished_deepslate_stairs | -385 | +| polished_deepslate_slab | -384 | +| polished_deepslate | -383 | +| cobbled_deepslate_wall | -382 | +| cobbled_deepslate_stairs | -381 | +| cobbled_deepslate_slab | -380 | +| cobbled_deepslate | -379 | +| deepslate | -378 | +| smooth_basalt | -377 | +| cave_vines_head_with_berries | -376 | +| cave_vines_body_with_berries | -375 | +| waxed_weathered_double_cut_copper_slab | -374 | +| waxed_exposed_double_cut_copper_slab | -373 | +| waxed_double_cut_copper_slab | -372 | +| oxidized_double_cut_copper_slab | -371 | +| weathered_double_cut_copper_slab | -370 | +| exposed_double_cut_copper_slab | -369 | +| double_cut_copper_slab | -368 | +| waxed_weathered_cut_copper_slab | -367 | +| waxed_exposed_cut_copper_slab | -366 | +| waxed_cut_copper_slab | -365 | +| oxidized_cut_copper_slab | -364 | +| weathered_cut_copper_slab | -363 | +| exposed_cut_copper_slab | -362 | +| cut_copper_slab | -361 | +| waxed_weathered_cut_copper_stairs | -360 | +| waxed_exposed_cut_copper_stairs | -359 | +| waxed_cut_copper_stairs | -358 | +| oxidized_cut_copper_stairs | -357 | +| weathered_cut_copper_stairs | -356 | +| exposed_cut_copper_stairs | -355 | +| cut_copper_stairs | -354 | +| waxed_weathered_cut_copper | -353 | +| waxed_exposed_cut_copper | -352 | +| waxed_cut_copper | -351 | +| oxidized_cut_copper | -350 | +| weathered_cut_copper | -349 | +| exposed_cut_copper | -348 | +| cut_copper | -347 | +| waxed_weathered_copper | -346 | +| waxed_exposed_copper | -345 | +| waxed_copper | -344 | +| oxidized_copper | -343 | +| weathered_copper | -342 | +| exposed_copper | -341 | +| copper_block | -340 | +| glow_frame | -339 | +| flowering_azalea | -338 | +| azalea | -337 | +| small_dripleaf_block | -336 | +| moss_carpet | -335 | +| tinted_glass | -334 | +| tuff | -333 | +| small_amethyst_bud | -332 | +| medium_amethyst_bud | -331 | +| large_amethyst_bud | -330 | +| amethyst_cluster | -329 | +| budding_amethyst | -328 | +| amethyst_block | -327 | +| calcite | -326 | +| azalea_leaves_flowered | -325 | +| azalea_leaves | -324 | +| big_dripleaf | -323 | +| cave_vines | -322 | +| spore_blossom | -321 | +| moss_block | -320 | +| hanging_roots | -319 | +| dirt_with_roots | -318 | +| dripstone_block | -317 | +| lightning_rod | -312 | +| copper_ore | -311 | +| pointed_dripstone | -308 | +| sculk_sensor | -307 | +| powder_snow | -306 | +| unknown | -305 | +| quartz_bricks | -304 | +| cracked_nether_bricks | -303 | +| chiseled_nether_bricks | -302 | +| stripped_warped_hyphae | -301 | +| stripped_crimson_hyphae | -300 | +| crimson_hyphae | -299 | +| warped_hyphae | -298 | +| polished_blackstone_wall | -297 | +| polished_blackstone_button | -296 | +| polished_blackstone_pressure_plate | -295 | +| polished_blackstone_double_slab | -294 | +| polished_blackstone_slab | -293 | +| polished_blackstone_stairs | -292 | +| polished_blackstone | -291 | +| soul_campfire | -290 | +| crying_obsidian | -289 | +| nether_gold_ore | -288 | +| twisting_vines | -287 | +| chain | -286 | +| polished_blackstone_brick_double_slab | -285 | +| polished_blackstone_brick_slab | -284 | +| blackstone_double_slab | -283 | +| blackstone_slab | -282 | +| gilded_blackstone | -281 | +| cracked_polished_blackstone_bricks | -280 | +| chiseled_polished_blackstone | -279 | +| polished_blackstone_brick_wall | -278 | +| blackstone_wall | -277 | +| blackstone_stairs | -276 | +| polished_blackstone_brick_stairs | -275 | +| polished_blackstone_bricks | -274 | +| blackstone | -273 | +| respawn_anchor | -272 | +| ancient_debris | -271 | +| netherite_block | -270 | +| soul_lantern | -269 | +| soul_torch | -268 | +| warped_double_slab | -267 | +| crimson_double_slab | -266 | +| warped_slab | -265 | +| crimson_slab | -264 | +| warped_pressure_plate | -263 | +| crimson_pressure_plate | -262 | +| warped_button | -261 | +| crimson_button | -260 | +| warped_fence_gate | -259 | +| crimson_fence_gate | -258 | +| warped_fence | -257 | +| crimson_fence | -256 | +| warped_stairs | -255 | +| crimson_stairs | -254 | +| warped_wall_sign | -253 | +| crimson_wall_sign | -252 | +| warped_standing_sign | -251 | +| crimson_standing_sign | -250 | +| warped_trapdoor | -247 | +| crimson_trapdoor | -246 | +| warped_door | -245 | +| crimson_door | -244 | +| warped_planks | -243 | +| crimson_planks | -242 | +| stripped_warped_stem | -241 | +| stripped_crimson_stem | -240 | +| target | -239 | +| nether_sprouts | -238 | +| soul_fire | -237 | +| soul_soil | -236 | +| polished_basalt | -235 | +| basalt | -234 | +| warped_nylium | -233 | +| crimson_nylium | -232 | +| weeping_vines | -231 | +| shroomlight | -230 | +| warped_fungus | -229 | +| crimson_fungus | -228 | +| warped_wart_block | -227 | +| warped_stem | -226 | +| crimson_stem | -225 | +| warped_roots | -224 | +| crimson_roots | -223 | +| lodestone | -222 | +| honeycomb_block | -221 | +| honey_block | -220 | +| beehive | -219 | +| bee_nest | -218 | +| sticky_piston_arm_collision | -217 | +| wither_rose | -216 | +| light_block | -215 | +| lit_blast_furnace | -214 | +| composter | -213 | +| wood | -212 | +| jigsaw | -211 | +| campfire | -209 | +| lantern | -208 | +| sweet_berry_bush | -207 | +| bell | -206 | +| loom | -204 | +| barrel | -203 | +| smithing_table | -202 | +| fletching_table | -201 | +| cartography_table | -200 | +| lit_smoker | -199 | +| smoker | -198 | +| stonecutter_block | -197 | +| blast_furnace | -196 | +| grindstone | -195 | +| lectern | -194 | +| darkoak_wall_sign | -193 | +| darkoak_standing_sign | -192 | +| acacia_wall_sign | -191 | +| acacia_standing_sign | -190 | +| jungle_wall_sign | -189 | +| jungle_standing_sign | -188 | +| birch_wall_sign | -187 | +| birch_standing_sign | -186 | +| smooth_quartz_stairs | -185 | +| red_nether_brick_stairs | -184 | +| smooth_stone | -183 | +| spruce_wall_sign | -182 | +| spruce_standing_sign | -181 | +| normal_stone_stairs | -180 | +| mossy_cobblestone_stairs | -179 | +| end_brick_stairs | -178 | +| smooth_sandstone_stairs | -177 | +| smooth_red_sandstone_stairs | -176 | +| mossy_stone_brick_stairs | -175 | +| polished_andesite_stairs | -174 | +| polished_diorite_stairs | -173 | +| polished_granite_stairs | -172 | +| andesite_stairs | -171 | +| diorite_stairs | -170 | +| granite_stairs | -169 | +| double_stone_block_slab4 | -168 | +| double_stone_block_slab3 | -167 | +| stone_block_slab4 | -166 | +| scaffolding | -165 | +| bamboo_sapling | -164 | +| bamboo | -163 | +| stone_block_slab3 | -162 | +| barrier | -161 | +| bubble_column | -160 | +| turtle_egg | -159 | +| air | -158 | +| conduit | -157 | +| sea_pickle | -156 | +| carved_pumpkin | -155 | +| spruce_pressure_plate | -154 | +| jungle_pressure_plate | -153 | +| dark_oak_pressure_plate | -152 | +| birch_pressure_plate | -151 | +| acacia_pressure_plate | -150 | +| spruce_trapdoor | -149 | +| jungle_trapdoor | -148 | +| dark_oak_trapdoor | -147 | +| birch_trapdoor | -146 | +| acacia_trapdoor | -145 | +| spruce_button | -144 | +| jungle_button | -143 | +| dark_oak_button | -142 | +| birch_button | -141 | +| acacia_button | -140 | +| dried_kelp_block | -139 | +| kelp | -138 | +| coral_fan_hang3 | -137 | +| coral_fan_hang2 | -136 | +| coral_fan_hang | -135 | +| coral_fan_dead | -134 | +| coral_fan | -133 | +| coral_block | -132 | +| tube_coral | -131 | +| seagrass | -130 | +| element_118 | -129 | +| element_117 | -128 | +| element_116 | -127 | +| element_115 | -126 | +| element_114 | -125 | +| element_113 | -124 | +| element_112 | -123 | +| element_111 | -122 | +| element_110 | -121 | +| element_109 | -120 | +| element_108 | -119 | +| element_107 | -118 | +| element_106 | -117 | +| element_105 | -116 | +| element_104 | -115 | +| element_103 | -114 | +| element_102 | -113 | +| element_101 | -112 | +| element_100 | -111 | +| element_99 | -110 | +| element_98 | -109 | +| element_97 | -108 | +| element_96 | -107 | +| element_95 | -106 | +| element_94 | -105 | +| element_93 | -104 | +| element_92 | -103 | +| element_91 | -102 | +| element_90 | -101 | +| element_89 | -100 | +| element_88 | -99 | +| element_87 | -98 | +| element_86 | -97 | +| element_85 | -96 | +| element_84 | -95 | +| element_83 | -94 | +| element_82 | -93 | +| element_81 | -92 | +| element_80 | -91 | +| element_79 | -90 | +| element_78 | -89 | +| element_77 | -88 | +| element_76 | -87 | +| element_75 | -86 | +| element_74 | -85 | +| element_73 | -84 | +| element_72 | -83 | +| element_71 | -82 | +| element_70 | -81 | +| element_69 | -80 | +| element_68 | -79 | +| element_67 | -78 | +| element_66 | -77 | +| element_65 | -76 | +| element_64 | -75 | +| element_63 | -74 | +| element_62 | -73 | +| element_61 | -72 | +| element_60 | -71 | +| element_59 | -70 | +| element_58 | -69 | +| element_57 | -68 | +| element_56 | -67 | +| element_55 | -66 | +| element_54 | -65 | +| element_53 | -64 | +| element_52 | -63 | +| element_51 | -62 | +| element_50 | -61 | +| element_49 | -60 | +| element_48 | -59 | +| element_47 | -58 | +| element_46 | -57 | +| element_45 | -56 | +| element_44 | -55 | +| element_43 | -54 | +| element_42 | -53 | +| element_41 | -52 | +| element_40 | -51 | +| element_39 | -50 | +| element_38 | -49 | +| element_37 | -48 | +| element_36 | -47 | +| element_35 | -46 | +| element_34 | -45 | +| element_33 | -44 | +| element_32 | -43 | +| element_31 | -42 | +| element_30 | -41 | +| element_29 | -40 | +| element_28 | -39 | +| element_27 | -38 | +| element_26 | -37 | +| element_25 | -36 | +| element_24 | -35 | +| element_23 | -34 | +| element_22 | -33 | +| element_21 | -32 | +| element_20 | -31 | +| element_19 | -30 | +| element_18 | -29 | +| element_17 | -28 | +| element_16 | -27 | +| element_15 | -26 | +| element_14 | -25 | +| element_13 | -24 | +| element_12 | -23 | +| element_11 | -22 | +| element_10 | -21 | +| element_9 | -20 | +| element_8 | -19 | +| element_7 | -18 | +| element_6 | -17 | +| element_5 | -16 | +| element_4 | -15 | +| element_3 | -14 | +| element_2 | -13 | +| element_1 | -12 | +| blue_ice | -11 | +| stripped_oak_log | -10 | +| stripped_dark_oak_log | -9 | +| stripped_acacia_log | -8 | +| stripped_jungle_log | -7 | +| stripped_birch_log | -6 | +| stripped_spruce_log | -5 | +| prismarine_bricks_stairs | -4 | +| dark_prismarine_stairs | -3 | +| prismarine_stairs | -2 | +| stone | 1 | +| grass | 2 | +| dirt | 3 | +| cobblestone | 4 | +| oak_planks | 5 | +| sapling | 6 | +| bedrock | 7 | +| flowing_water | 8 | +| water | 9 | +| flowing_lava | 10 | +| lava | 11 | +| sand | 12 | +| gravel | 13 | +| gold_ore | 14 | +| iron_ore | 15 | +| coal_ore | 16 | +| oak_log | 17 | +| leaves | 18 | +| sponge | 19 | +| glass | 20 | +| lapis_ore | 21 | +| lapis_block | 22 | +| dispenser | 23 | +| sandstone | 24 | +| noteblock | 25 | +| bed | 26 | +| golden_rail | 27 | +| detector_rail | 28 | +| sticky_piston | 29 | +| web | 30 | +| tallgrass | 31 | +| deadbush | 32 | +| piston | 33 | +| piston_arm_collision | 34 | +| white_wool | 35 | +| element_0 | 36 | +| yellow_flower | 37 | +| red_flower | 38 | +| brown_mushroom | 39 | +| red_mushroom | 40 | +| gold_block | 41 | +| iron_block | 42 | +| double_stone_block_slab | 43 | +| stone_block_slab | 44 | +| brick_block | 45 | +| tnt | 46 | +| bookshelf | 47 | +| mossy_cobblestone | 48 | +| obsidian | 49 | +| torch | 50 | +| fire | 51 | +| mob_spawner | 52 | +| oak_stairs | 53 | +| chest | 54 | +| redstone_wire | 55 | +| diamond_ore | 56 | +| diamond_block | 57 | +| crafting_table | 58 | +| wheat | 59 | +| farmland | 60 | +| furnace | 61 | +| lit_furnace | 62 | +| standing_sign | 63 | +| wooden_door | 64 | +| ladder | 65 | +| rail | 66 | +| stone_stairs | 67 | +| wall_sign | 68 | +| lever | 69 | +| stone_pressure_plate | 70 | +| iron_door | 71 | +| wooden_pressure_plate | 72 | +| redstone_ore | 73 | +| lit_redstone_ore | 74 | +| unlit_redstone_torch | 75 | +| redstone_torch | 76 | +| stone_button | 77 | +| snow_layer | 78 | +| ice | 79 | +| snow | 80 | +| cactus | 81 | +| clay | 82 | +| reeds | 83 | +| jukebox | 84 | +| oak_fence | 85 | +| pumpkin | 86 | +| netherrack | 87 | +| soul_sand | 88 | +| glowstone | 89 | +| portal | 90 | +| lit_pumpkin | 91 | +| cake | 92 | +| unpowered_repeater | 93 | +| powered_repeater | 94 | +| invisible_bedrock | 95 | +| trapdoor | 96 | +| monster_egg | 97 | +| stonebrick | 98 | +| brown_mushroom_block | 99 | +| red_mushroom_block | 100 | +| iron_bars | 101 | +| glass_pane | 102 | +| melon_block | 103 | +| pumpkin_stem | 104 | +| melon_stem | 105 | +| vine | 106 | +| fence_gate | 107 | +| brick_stairs | 108 | +| stone_brick_stairs | 109 | +| mycelium | 110 | +| waterlily | 111 | +| nether_brick | 112 | +| nether_brick_fence | 113 | +| nether_brick_stairs | 114 | +| nether_wart | 115 | +| enchanting_table | 116 | +| brewing_stand | 117 | +| cauldron | 118 | +| end_portal | 119 | +| end_portal_frame | 120 | +| end_stone | 121 | +| dragon_egg | 122 | +| redstone_lamp | 123 | +| lit_redstone_lamp | 124 | +| dropper | 125 | +| activator_rail | 126 | +| cocoa | 127 | +| sandstone_stairs | 128 | +| emerald_ore | 129 | +| ender_chest | 130 | +| tripwire_hook | 131 | +| trip_wire | 132 | +| emerald_block | 133 | +| spruce_stairs | 134 | +| birch_stairs | 135 | +| jungle_stairs | 136 | +| command_block | 137 | +| beacon | 138 | +| cobblestone_wall | 139 | +| flower_pot | 140 | +| carrots | 141 | +| potatoes | 142 | +| wooden_button | 143 | +| skull | 144 | +| anvil | 145 | +| trapped_chest | 146 | +| light_weighted_pressure_plate | 147 | +| heavy_weighted_pressure_plate | 148 | +| unpowered_comparator | 149 | +| powered_comparator | 150 | +| daylight_detector | 151 | +| redstone_block | 152 | +| quartz_ore | 153 | +| hopper | 154 | +| quartz_block | 155 | +| quartz_stairs | 156 | +| double_wooden_slab | 157 | +| wooden_slab | 158 | +| stained_hardened_clay | 159 | +| stained_glass_pane | 160 | +| leaves2 | 161 | +| acacia_log | 162 | +| acacia_stairs | 163 | +| dark_oak_stairs | 164 | +| slime | 165 | +| iron_trapdoor | 167 | +| prismarine | 168 | +| sea_lantern | 169 | +| hay_block | 170 | +| white_carpet | 171 | +| hardened_clay | 172 | +| coal_block | 173 | +| packed_ice | 174 | +| double_plant | 175 | +| standing_banner | 176 | +| wall_banner | 177 | +| daylight_detector_inverted | 178 | +| red_sandstone | 179 | +| red_sandstone_stairs | 180 | +| double_stone_block_slab2 | 181 | +| stone_block_slab2 | 182 | +| spruce_fence_gate | 183 | +| birch_fence_gate | 184 | +| jungle_fence_gate | 185 | +| dark_oak_fence_gate | 186 | +| acacia_fence_gate | 187 | +| repeating_command_block | 188 | +| chain_command_block | 189 | +| hard_glass_pane | 190 | +| hard_stained_glass_pane | 191 | +| chemical_heat | 192 | +| spruce_door | 193 | +| birch_door | 194 | +| jungle_door | 195 | +| acacia_door | 196 | +| dark_oak_door | 197 | +| grass_path | 198 | +| frame | 199 | +| chorus_flower | 200 | +| purpur_block | 201 | +| colored_torch_rg | 202 | +| purpur_stairs | 203 | +| colored_torch_bp | 204 | +| undyed_shulker_box | 205 | +| end_bricks | 206 | +| frosted_ice | 207 | +| end_rod | 208 | +| end_gateway | 209 | +| allow | 210 | +| deny | 211 | +| border_block | 212 | +| magma | 213 | +| nether_wart_block | 214 | +| red_nether_brick | 215 | +| bone_block | 216 | +| structure_void | 217 | +| shulker_box | 218 | +| purple_glazed_terracotta | 219 | +| white_glazed_terracotta | 220 | +| orange_glazed_terracotta | 221 | +| magenta_glazed_terracotta | 222 | +| light_blue_glazed_terracotta | 223 | +| yellow_glazed_terracotta | 224 | +| lime_glazed_terracotta | 225 | +| pink_glazed_terracotta | 226 | +| gray_glazed_terracotta | 227 | +| silver_glazed_terracotta | 228 | +| cyan_glazed_terracotta | 229 | +| blue_glazed_terracotta | 231 | +| brown_glazed_terracotta | 232 | +| green_glazed_terracotta | 233 | +| red_glazed_terracotta | 234 | +| black_glazed_terracotta | 235 | +| concrete | 236 | +| concrete_powder | 237 | +| chemistry_table | 238 | +| underwater_torch | 239 | +| chorus_plant | 240 | +| stained_glass | 241 | +| camera | 242 | +| podzol | 243 | +| beetroot | 244 | +| stonecutter | 245 | +| glowingobsidian | 246 | +| netherreactor | 247 | +| info_update | 248 | +| info_update2 | 249 | +| moving_block | 250 | +| observer | 251 | +| structure_block | 252 | +| hard_glass | 253 | +| hard_stained_glass | 254 | +| reserved6 | 255 | +| apple | 257 | +| golden_apple | 259 | +| enchanted_golden_apple | 260 | +| mushroom_stew | 261 | +| bread | 262 | +| porkchop | 263 | +| cooked_porkchop | 264 | +| cod | 265 | +| salmon | 266 | +| tropical_fish | 267 | +| pufferfish | 268 | +| cooked_cod | 269 | +| cooked_salmon | 270 | +| dried_kelp | 271 | +| cookie | 272 | +| melon_slice | 273 | +| beef | 274 | +| cooked_beef | 275 | +| chicken | 276 | +| cooked_chicken | 277 | +| rotten_flesh | 278 | +| spider_eye | 279 | +| carrot | 280 | +| potato | 281 | +| baked_potato | 282 | +| poisonous_potato | 283 | +| golden_carrot | 284 | +| pumpkin_pie | 285 | +| beetroot | 286 | +| beetroot_soup | 287 | +| sweet_berries | 288 | +| rabbit | 289 | +| cooked_rabbit | 290 | +| rabbit_stew | 291 | +| wheat_seeds | 292 | +| pumpkin_seeds | 293 | +| melon_seeds | 294 | +| nether_wart | 295 | +| beetroot_seeds | 296 | +| torchflower_seeds | 297 | +| pitcher_pod | 298 | +| iron_shovel | 299 | +| iron_pickaxe | 300 | +| iron_axe | 301 | +| flint_and_steel | 302 | +| bow | 303 | +| arrow | 304 | +| coal | 305 | +| charcoal | 306 | +| diamond | 307 | +| iron_ingot | 308 | +| gold_ingot | 309 | +| iron_sword | 310 | +| wooden_sword | 311 | +| wooden_shovel | 312 | +| wooden_pickaxe | 313 | +| wooden_axe | 314 | +| stone_sword | 315 | +| stone_shovel | 316 | +| stone_pickaxe | 317 | +| stone_axe | 318 | +| diamond_sword | 319 | +| diamond_shovel | 320 | +| diamond_pickaxe | 321 | +| diamond_axe | 322 | +| stick | 323 | +| bowl | 324 | +| golden_sword | 325 | +| golden_shovel | 326 | +| golden_pickaxe | 327 | +| golden_axe | 328 | +| string | 329 | +| feather | 330 | +| gunpowder | 331 | +| wooden_hoe | 332 | +| stone_hoe | 333 | +| iron_hoe | 334 | +| diamond_hoe | 335 | +| golden_hoe | 336 | +| wheat | 337 | +| leather_helmet | 338 | +| leather_chestplate | 339 | +| leather_leggings | 340 | +| leather_boots | 341 | +| chainmail_helmet | 342 | +| chainmail_chestplate | 343 | +| chainmail_leggings | 344 | +| chainmail_boots | 345 | +| iron_helmet | 346 | +| iron_chestplate | 347 | +| iron_leggings | 348 | +| iron_boots | 349 | +| diamond_helmet | 350 | +| diamond_chestplate | 351 | +| diamond_leggings | 352 | +| diamond_boots | 353 | +| golden_helmet | 354 | +| golden_chestplate | 355 | +| golden_leggings | 356 | +| golden_boots | 357 | +| shield | 358 | +| flint | 359 | +| painting | 360 | +| oak_sign | 361 | +| wooden_door | 362 | +| bucket | 363 | +| milk_bucket | 364 | +| water_bucket | 365 | +| lava_bucket | 366 | +| cod_bucket | 367 | +| salmon_bucket | 368 | +| tropical_fish_bucket | 369 | +| pufferfish_bucket | 370 | +| powder_snow_bucket | 371 | +| axolotl_bucket | 372 | +| minecart | 373 | +| saddle | 374 | +| iron_door | 375 | +| redstone | 376 | +| snowball | 377 | +| oak_boat | 378 | +| birch_boat | 379 | +| jungle_boat | 380 | +| spruce_boat | 381 | +| acacia_boat | 382 | +| dark_oak_boat | 383 | +| leather | 384 | +| kelp | 385 | +| brick | 386 | +| clay_ball | 387 | +| sugar_cane | 388 | +| paper | 389 | +| book | 390 | +| slime_ball | 391 | +| chest_minecart | 392 | +| egg | 393 | +| compass | 394 | +| fishing_rod | 395 | +| clock | 396 | +| glowstone_dust | 397 | +| black_dye | 398 | +| red_dye | 399 | +| green_dye | 400 | +| brown_dye | 401 | +| blue_dye | 402 | +| purple_dye | 403 | +| cyan_dye | 404 | +| light_gray_dye | 405 | +| gray_dye | 406 | +| pink_dye | 407 | +| lime_dye | 408 | +| yellow_dye | 409 | +| light_blue_dye | 410 | +| magenta_dye | 411 | +| orange_dye | 412 | +| white_dye | 413 | +| bone_meal | 414 | +| cocoa_beans | 415 | +| ink_sac | 416 | +| lapis_lazuli | 417 | +| bone | 418 | +| sugar | 419 | +| cake | 420 | +| bed | 421 | +| repeater | 422 | +| filled_map | 423 | +| shears | 424 | +| ender_pearl | 425 | +| blaze_rod | 426 | +| ghast_tear | 427 | +| gold_nugget | 428 | +| potion | 429 | +| glass_bottle | 430 | +| fermented_spider_eye | 431 | +| blaze_powder | 432 | +| magma_cream | 433 | +| brewing_stand | 434 | +| cauldron | 435 | +| ender_eye | 436 | +| glistering_melon_slice | 437 | +| chicken_spawn_egg | 438 | +| cow_spawn_egg | 439 | +| pig_spawn_egg | 440 | +| sheep_spawn_egg | 441 | +| wolf_spawn_egg | 442 | +| mooshroom_spawn_egg | 443 | +| creeper_spawn_egg | 444 | +| enderman_spawn_egg | 445 | +| silverfish_spawn_egg | 446 | +| skeleton_spawn_egg | 447 | +| slime_spawn_egg | 448 | +| spider_spawn_egg | 449 | +| zombie_spawn_egg | 450 | +| zombie_pigman_spawn_egg | 451 | +| villager_spawn_egg | 452 | +| squid_spawn_egg | 453 | +| ocelot_spawn_egg | 454 | +| witch_spawn_egg | 455 | +| bat_spawn_egg | 456 | +| ghast_spawn_egg | 457 | +| magma_cube_spawn_egg | 458 | +| blaze_spawn_egg | 459 | +| cave_spider_spawn_egg | 460 | +| horse_spawn_egg | 461 | +| rabbit_spawn_egg | 462 | +| endermite_spawn_egg | 463 | +| guardian_spawn_egg | 464 | +| stray_spawn_egg | 465 | +| husk_spawn_egg | 466 | +| wither_skeleton_spawn_egg | 467 | +| donkey_spawn_egg | 468 | +| mule_spawn_egg | 469 | +| skeleton_horse_spawn_egg | 470 | +| zombie_horse_spawn_egg | 471 | +| shulker_spawn_egg | 472 | +| npc_spawn_egg | 473 | +| elder_guardian_spawn_egg | 474 | +| polar_bear_spawn_egg | 475 | +| llama_spawn_egg | 476 | +| vindicator_spawn_egg | 477 | +| evoker_spawn_egg | 478 | +| vex_spawn_egg | 479 | +| zombie_villager_spawn_egg | 480 | +| parrot_spawn_egg | 481 | +| tropical_fish_spawn_egg | 482 | +| cod_spawn_egg | 483 | +| pufferfish_spawn_egg | 484 | +| salmon_spawn_egg | 485 | +| drowned_spawn_egg | 486 | +| dolphin_spawn_egg | 487 | +| turtle_spawn_egg | 488 | +| phantom_spawn_egg | 489 | +| agent_spawn_egg | 490 | +| cat_spawn_egg | 491 | +| panda_spawn_egg | 492 | +| fox_spawn_egg | 493 | +| pillager_spawn_egg | 494 | +| wandering_trader_spawn_egg | 495 | +| ravager_spawn_egg | 496 | +| bee_spawn_egg | 497 | +| strider_spawn_egg | 498 | +| hoglin_spawn_egg | 499 | +| piglin_spawn_egg | 500 | +| zoglin_spawn_egg | 501 | +| piglin_brute_spawn_egg | 502 | +| sniffer_spawn_egg | 503 | +| axolotl_spawn_egg | 504 | +| goat_spawn_egg | 505 | +| glow_squid_spawn_egg | 506 | +| iron_golem_spawn_egg | 507 | +| snow_golem_spawn_egg | 508 | +| ender_dragon_spawn_egg | 509 | +| wither_spawn_egg | 510 | +| glow_ink_sac | 511 | +| copper_ingot | 512 | +| raw_iron | 513 | +| raw_gold | 514 | +| raw_copper | 515 | +| experience_bottle | 516 | +| fire_charge | 517 | +| writable_book | 518 | +| written_book | 519 | +| emerald | 520 | +| frame | 521 | +| flower_pot | 522 | +| empty_map | 523 | +| skull | 524 | +| carrot_on_a_stick | 525 | +| nether_star | 526 | +| firework_rocket | 527 | +| firework_star | 528 | +| enchanted_book | 529 | +| comparator | 530 | +| netherbrick | 531 | +| quartz | 532 | +| tnt_minecart | 533 | +| hopper_minecart | 534 | +| hopper | 535 | +| rabbit_foot | 536 | +| rabbit_hide | 537 | +| leather_horse_armor | 538 | +| iron_horse_armor | 539 | +| golden_horse_armor | 540 | +| diamond_horse_armor | 541 | +| music_disc_13 | 542 | +| music_disc_cat | 543 | +| music_disc_blocks | 544 | +| music_disc_chirp | 545 | +| music_disc_far | 546 | +| music_disc_mall | 547 | +| music_disc_mellohi | 548 | +| music_disc_stal | 549 | +| music_disc_strad | 550 | +| music_disc_ward | 551 | +| music_disc_11 | 552 | +| music_disc_wait | 553 | +| trident | 554 | +| lead | 555 | +| name_tag | 556 | +| prismarine_crystals | 557 | +| mutton | 558 | +| cooked_mutton | 559 | +| armor_stand | 560 | +| spruce_door | 561 | +| birch_door | 562 | +| jungle_door | 563 | +| acacia_door | 564 | +| dark_oak_door | 565 | +| chorus_fruit | 566 | +| popped_chorus_fruit | 567 | +| dragon_breath | 568 | +| splash_potion | 569 | +| lingering_potion | 570 | +| command_block_minecart | 571 | +| elytra | 572 | +| prismarine_shard | 573 | +| shulker_shell | 574 | +| banner | 575 | +| totem_of_undying | 576 | +| iron_nugget | 577 | +| nautilus_shell | 578 | +| heart_of_the_sea | 579 | +| scute | 580 | +| turtle_helmet | 581 | +| phantom_membrane | 582 | +| crossbow | 583 | +| spruce_sign | 584 | +| birch_sign | 585 | +| jungle_sign | 586 | +| acacia_sign | 587 | +| dark_oak_sign | 588 | +| flower_banner_pattern | 589 | +| creeper_banner_pattern | 590 | +| skull_banner_pattern | 591 | +| mojang_banner_pattern | 592 | +| field_masoned_banner_pattern | 593 | +| bordure_indented_banner_pattern | 594 | +| piglin_banner_pattern | 595 | +| globe_banner_pattern | 596 | +| campfire | 597 | +| suspicious_stew | 598 | +| honeycomb | 599 | +| honey_bottle | 600 | +| camera | 601 | +| compound | 602 | +| ice_bomb | 603 | +| bleach | 604 | +| rapid_fertilizer | 605 | +| balloon | 606 | +| medicine | 607 | +| sparkler | 608 | +| glow_stick | 609 | +| lodestone_compass | 610 | +| netherite_sword | 611 | +| netherite_shovel | 612 | +| netherite_pickaxe | 613 | +| netherite_axe | 614 | +| netherite_hoe | 615 | +| netherite_ingot | 616 | +| netherite_helmet | 617 | +| netherite_chestplate | 618 | +| netherite_leggings | 619 | +| netherite_boots | 620 | +| netherite_scrap | 621 | +| crimson_sign | 622 | +| warped_sign | 623 | +| crimson_door | 624 | +| warped_door | 625 | +| warped_fungus_on_a_stick | 626 | +| chain | 627 | +| music_disc_pigstep | 628 | +| nether_sprouts | 629 | +| soul_campfire | 630 | +| glow_frame | 631 | +| amethyst_shard | 632 | +| spyglass | 633 | +| music_disc_otherside | 634 | +| goat_horn | 635 | +| frog_spawn_egg | 636 | +| tadpole_spawn_egg | 637 | +| tadpole_bucket | 638 | +| allay_spawn_egg | 639 | +| warden_spawn_egg | 640 | +| mangrove_door | 641 | +| mangrove_sign | 642 | +| mangrove_boat | 643 | +| music_disc_5 | 644 | +| disc_fragment_5 | 645 | +| oak_chest_boat | 646 | +| birch_chest_boat | 647 | +| jungle_chest_boat | 648 | +| spruce_chest_boat | 649 | +| acacia_chest_boat | 650 | +| dark_oak_chest_boat | 651 | +| mangrove_chest_boat | 652 | +| chest_boat | 653 | +| recovery_compass | 654 | +| echo_shard | 655 | +| trader_llama_spawn_egg | 656 | +| cherry_boat | 657 | +| cherry_chest_boat | 658 | +| cherry_sign | 659 | +| bamboo_sign | 660 | +| bamboo_raft | 661 | +| bamboo_chest_raft | 662 | +| camel_spawn_egg | 663 | +| angler_pottery_sherd | 664 | +| archer_pottery_sherd | 665 | +| arms_up_pottery_sherd | 666 | +| blade_pottery_sherd | 667 | +| brewer_pottery_sherd | 668 | +| burn_pottery_sherd | 669 | +| danger_pottery_sherd | 670 | +| explorer_pottery_sherd | 671 | +| friend_pottery_sherd | 672 | +| heart_pottery_sherd | 673 | +| heartbreak_pottery_sherd | 674 | +| howl_pottery_sherd | 675 | +| miner_pottery_sherd | 676 | +| mourner_pottery_sherd | 677 | +| plenty_pottery_sherd | 678 | +| prize_pottery_sherd | 679 | +| sheaf_pottery_sherd | 680 | +| shelter_pottery_sherd | 681 | +| skull_pottery_sherd | 682 | +| snort_pottery_sherd | 683 | +| brush | 684 | +| netherite_upgrade_smithing_template | 685 | +| sentry_armor_trim_smithing_template | 686 | +| dune_armor_trim_smithing_template | 687 | +| coast_armor_trim_smithing_template | 688 | +| wild_armor_trim_smithing_template | 689 | +| ward_armor_trim_smithing_template | 690 | +| eye_armor_trim_smithing_template | 691 | +| vex_armor_trim_smithing_template | 692 | +| tide_armor_trim_smithing_template | 693 | +| snout_armor_trim_smithing_template | 694 | +| rib_armor_trim_smithing_template | 695 | +| spire_armor_trim_smithing_template | 696 | +| silence_armor_trim_smithing_template | 697 | +| wayfinder_armor_trim_smithing_template | 698 | +| raiser_armor_trim_smithing_template | 699 | +| shaper_armor_trim_smithing_template | 700 | +| host_armor_trim_smithing_template | 701 | +| music_disc_relic | 702 | +| terracotta | 703 | +| wool | 704 | +| carpet | 705 | +| log | 706 | +| fence | 707 | +| planks | 708 | +| coral | 709 | +| log2 | 710 | +| concrete | 711 | +| concrete_powder | 712 | +| stained_glass | 713 | +| stained_glass_pane | 714 | +| dyed_shulker_box | 715 | +| boat | 716 | +| dye | 717 | +| banner_pattern | 718 | +| spawn_egg | 719 | +| end_crystal | 720 | +| glow_berries | 721 | \ No newline at end of file diff --git a/docs/wiki/items/spawning-items.md b/docs/wiki/items/spawning-items.md new file mode 100644 index 00000000..03eaeb38 --- /dev/null +++ b/docs/wiki/items/spawning-items.md @@ -0,0 +1,176 @@ +--- +title: Spawning Items +category: Tutorials +tags: + - intermediate +mentions: + - SirLich + - Joelant05 + - Dreamedc2015 + - yanasakana + - MedicalJewel105 + - aexer0e + - Xterionix +--- + +It is fairly common to want to spawn an item in the world, as if dropped. This page will walk through how to accomplish this through various methods, including Entity Deaths, Interactions, and an all-purpose method. + +## /loot + +The simplest method of spawning items to date is by using /loot. Formatted as such: +``` +/loot spawn ~ ~ ~ loot "entities/cow" +``` + +BP/loot_tables/entities/cow.json + +```json +"minecraft:loot": { + "table": "loot_tables/entities/cow.json" +} +``` + +## Entity Deaths + +Another simple method of spawning items - and generally the most common one - is dropping items upon an entity's death. This is done by adding the `minecraft:loot` component to the entity and linking it to the respective loot table (`forium` in the following example) containing items you wish to be dropped. + +BP/entities/my_entity.json#components + +```json +"minecraft:loot": { + "table": "loot_tables/entities/forium.json" +} +``` + +## Dummy Entity Deaths + +We can use `minecraft:loot` on a [dummy entity](/entities/dummy-entities) that dies when we spawn it to create a `drop_entity`. This entity can be summoned like `/summon wiki:drop_entity` to spawn the items. This is useful for scenarios where death particles or sounds are not an issue. + +Behaviors: + +BP/entities/my_entity.json + +```json +{ + "format_version": "1.16.0", + "minecraft:entity": { + "description": { + "identifier": "wiki:drop_entity", + "is_spawnable": true, + "is_summonable": true, + "is_experimental": false + }, + + "components": { + // Causes the entity to die when spawned + "minecraft:health": { + "value": 0 + }, + "minecraft:loot": { + "table": "loot_tables/entities/some_loot.json" + } + } + } +} +``` + +## Interactions + +Here is an example of an entity called "box" which will drop its contents upon interaction. The table in `spawn_items` is linked to the loot table with the items desired to be dropped. In this particular case, the event `break_box` is also called when the entity is interacted with, adding a component group that removes the box. + +Note that if the entity is not removed upon interaction, it can be interacted with again and will spawn the items. If the entity should persist after the interaction, the `cooldown` parameter may be added to the entity to prevent interaction for a specified amount of time. Alternatively, an event may be called to remove the component group containing this `minecraft:interact` component. + +BP/entities/my_entity.json#components + +```json +"minecraft:interact": { + "interactions": [ + { + "on_interact": { + "filters": { + "test": "is_family", + "subject": "other", + "value": "player" + }, + "event": "break_box", + "target": "self" + }, + "swing": true, + "spawn_items": { + "table": "loot_tables/entities/box.json" + } + } + ] +} +``` + +## All-Purpose Method + +This is a method that can be used for virtually any scenario: entity deaths, animation-based interactions, general item drops. This method was created in particular for dropping items without any death animation, sound, or particles. + +Several parts are required to set up the item dropping: a new entity with behavior, a corresponding animation controller, the resources for an invisible entity (refer to Dummy Entities tutorial), and a loot table. To spawn the items after it is set up, the entity is spawned where the items are to be dropped. If multiple items are desired, component groups with spawn events may be set up for each item. + +### Behavior + +The items are spawned using the `minecraft:behavior.drop_item_for` component in conjunction with the `minecraft:navigation.walk` component, the latter being required for the former to work. Note that the `time_of_day_range` parameter in the following is not initialized to how it is defined below despite the documentation listing it as such, and this is necessary for proper function. The parameter `max_dist` must be increased to an appropriate value if the items are desired to be dropped when the player is very far away. + +This behavior appears to push the mob back when the items are dropped. Thus it is essential to summon the entity slightly above the ground (or teleport it up in the following animation controller) to avoid the items spawning a few blocks away from the spawn location. Decreasing the size of the collision box may also help. + +BP/entities/my_entity.json#components + +```json +"minecraft:navigation.walk": {}, +"minecraft:behavior.drop_item_for": { + "priority": 1, + "max_dist": 16, + "loot_table": "loot_tables/entities/forium.json", + "time_of_day_range": [0.0, 1.0] +} +``` + +### Animation Controller + +**The following animation controller must be linked to the entity** to remove it upon summoning. Alternatively, an animation with a timeline can be used. If you are unsure how to do this, refer to the Entity Commands tutorial. + +Teleporting the entity into the void causes no death animation, sound, or particles. Two transitions are used to ensure it is not killed in the same tick it spawns. + +BP/animation_controllers/my_entity.ac.json + +```json +{ + "format_version": "1.10.0", + "animation_controllers": { + "controller.animation.drop_items.die": { + "initial_state": "spawn", + "states": { + "spawn": { + "transitions": [ + { + "delay": "1" + } + ] + }, + "delay": { + "transitions": [ + { + "die": "1" + } + ] + }, + "die": { + "on_entry": ["/tp @s ~ -200 ~"] + } + } + } + } +} +``` + +## Structure Method + +There is also one interesting method of spawning items - via structure. +You can fill a structure with `structure_void` (so air doesn't replace blocks when structure loaded) and drop an item into it. +This method allows us to keep item data (such as durability). +Then you can load this structure whenever and wherever you want. + +![](/assets/images/items/spawning-items/structure-method.png) diff --git a/docs/wiki/items/spear.md b/docs/wiki/items/spear.md new file mode 100644 index 00000000..a0915bb4 --- /dev/null +++ b/docs/wiki/items/spear.md @@ -0,0 +1,402 @@ +--- +title: Custom Spear +category: Tutorials +tags: + - scripting +mentions: + - XxPoggyisLitxX + - SirLich + - TheItsNamless + - ThomasOrs + - kumja1 +hidden: true +--- + +::: tip +It's highly recommended that you have a basic understanding of JavaScript and Script-API. +::: + +::: warning +It's highly recommended that you have made the basic textures and models for this guide.. +::: + +Before we start, let's make sure you have your file structure set up: + + + +Making custom spears is a really simple task. It was not simple for Koala Boy though. There are some scripting involved, but it doesn't do the main behaviors. + +## Item + +It can go without saying that you'd obviously need an item to make a spear, however we don't use some "basic" behaviors. Let's get an item file and let's add the following components. Let's start with the main components: + +BP/items/spear.json + +```json +{ + //Use duration is the max time we can use the item. + "minecraft:use_duration": 3600, + //This component is what gives our spear the ability to 'draw' it like a bow + "minecraft:throwable": { + "min_draw_duration": 2, + "max_draw_duration": 4, + "scale_power_by_draw_duration": true + }, + //What projectile to shoot when draw is complete + "minecraft:projectile": { + "projectile_entity": "wiki:thrown_iron_spear", + "minimum_critical_power": 1.0 + }, + //Durability of the spear. + "minecraft:durability": { + "max_durability": 125 + } +} +``` + +## Spear Projectile + +We can safely say that we got the important components for our spear. Next we move over to the projectile. This projectile will be a simple entity, with some added components and a runtime identifier to get the correct behaviors. + + + +BP/entities/spear.json + +```json +{ + "format_version": "1.12.0", + "minecraft:entity": { + "description": { + "identifier": "wiki:thrown_iron_spear", + "is_spawnable": false, + "is_summonable": true, + "is_experimental": false, + "runtime_identifier": "minecraft:snowball" + }, + "component_groups": { + "wiki:give": { + "minecraft:instant_despawn": {} + } + }, + "components": { + "minecraft:conditional_bandwidth_optimization": { + "default_values": { + "max_dropped_ticks": 10, + "max_optimized_distance": 100, + "use_motion_prediction_hints": true + } + }, + "minecraft:hurt_on_condition": { + "damage_conditions": [ + { + "cause": "lava", + "damage_per_tick": 4, + "filters": { + "operator": "==", + "subject": "self", + "test": "in_lava", + "value": true + } + } + ] + }, + "minecraft:physics": {}, + "minecraft:projectile": { + "anchor": 1, + "gravity": 0.05, + "hit_sound": "bow.hit", + "offset": [ + 0, + -0.1, + 0 + ], + "on_hit": { + "definition_event": { + "event_trigger": { + "event": "example:foo", + "target": "self" + } + }, + "impact_damage": { + "damage": 7, + "destroy_on_hit": false, + "knockback": true, + "power_multiplier": 0.97, + "semi_random_diff_damage": false + }, + "stick_in_ground": { + "shake_time": 0.35 + } + }, + "power": 3, + "should_bounce": true, + "stop_on_hurt": true + }, + "minecraft:pushable": { + "is_pushable": false, + "is_pushable_by_piston": true + } + } + } +} +``` + + +Here we got our simple projectile entity. We are missing one part to make this a useful projectile. There is no way for our player to pick it up from the ground. In order to do this, we need events and entity sensors: + +BP/entities/spear.json + +```json +{ + "components": { + //Entity sensor detects if the projectile is on the ground, and if the player is near the entity. + //This will run an event when it's true + "minecraft:entity_sensor": { + "event": "wiki:give", + "event_filters": { + "all_of": [ + { + "subject": "other", + "test": "is_family", + "value": "player" + }, + { + "subject": "self", + "test": "on_ground", + "value": true + } + ] + }, + "minimum_count": 1, + "relative_range": false, + "sensor_range": 0.7 + } + }, + "events": { + /* + This event will despawn our projectile, and give our player a tag, which we will use in our script. + */ + "wiki:give": { + "sequence": [ + { + "add": { + "component_groups": [ + "wiki:give" + ] + } + }, + { + "randomize": [ + { + "run_command": { + "command": [ + "playsound random.pop @p", + "tag @p add iron_spear" + ] + }, + "weight": 90 + } + ] + } + ] + } + } +} +``` + +Once we're done with out projectile entity, it's time to go to Resource Packs. + +## Client Entity + +We will be using a basic client entity file for our projectile with added code. + + + +RP/entities/spear.json + +```json +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "wiki:thrown_iron_spear", + "materials": { + "default": "entity_alphatest" + }, + "textures": { + "default": "textures/entity/iron_spear" + }, + "animations": { + "move": "animation.weapon.default_thrown" + }, + "scripts": { + "animate": [ + "move" + ] + }, + "geometry": { + "default": "geometry.stone_spear" + }, + "render_controllers": [ + "controller.render.default" + ] + } + } +} +``` + + +Inside our client entity file, you might have noticed that there is animations bound to it. This animation will make our projectile rotate as it flies. + +:::warning +Make sure your entity model is modeled like the image bellow! +::: + +![](/assets/images/items/spears/spear_model.png) + +## Animation + +The animation we use for our projectile isn't you normal entity animation. This one uses [molang](https://bedrock.dev/docs/stable/Molang) to define rotations. + +BP/animations/spear.json + +```json +{ + "format_version": "1.8.0", + "animations": { + "animation.weapon.default_thrown": { + "loop": true, + "bones": { + "body": { + //This is some molang stuff. The animation uses this to rotate the model based on its current angle. + "rotation": ["-q.target_x_rotation", "-q.body_y_rotation", 0] + } + } + } + } +} +``` + +## Attachable + +We will be using the Trident Attachable because it comes with item positions and use animations already. It should look like this: + +BP/attachables/spear.json + +```json +{ + "format_version": "1.10.0", + "minecraft:attachable": { + "description": { + "identifier": "wiki:iron_spear", + "materials": { + "default": "entity_alphatest", + "enchanted": "entity_alphatest_glint" + }, + "textures": { + "default": "textures/entity/iron_spear", + "enchanted": "textures/misc/enchanted_item_glint" + }, + "geometry": { + "default": "geometry.stone_spear_item" + }, + "animations": { + "wield": "controller.animation.trident.wield", + "wield_first_person": "animation.trident.wield_first_person", + "wield_first_person_raise": "animation.trident.wield_first_person_raise", + "wield_first_person_raise_shake": "animation.trident.wield_first_person_raise_shake", + "wield_first_person_riptide": "animation.trident.wield_first_person_riptide", + "wield_third_person": "animation.trident.wield_third_person", + "wield_third_person_raise": "animation.trident.wield_third_person_raise" + }, + "scripts": { + "pre_animation": [ + "v.charge_amount = math.clamp((q.main_hand_item_max_duration - (q.main_hand_item_use_duration - q.frame_alpha + 1.0)) / 10.0, 0.0, 1.0f);" + ], + "animate": [ + "wield" + ] + }, + "render_controllers": [ + "controller.render.item_default" + ] + } + } +} +``` + +## Script + +Now that we've setup our spear, there is no way to damage the spear when it's thrown. To do this, we will make use of Script-API. + +The script is really simple, and wouldn't require much brain power. + +```js +import { world, ItemStack } from "@minecraft/server" +import { system } from "@minecraft/server"; +//This prevents world crash +system.beforeEvents.watchdogTerminate.subscribe(data => { + data.cancel = true; +}); + +world.afterEvents.itemReleaseUse.subscribe(ev => { + //This is for multiplayer support + for (const player of world.getPlayers()){ + //Basic variables to get the player inventory and held item. + let inv = player.getComponent( 'inventory' ).container + //Our itemStack to save our item. This also saves item data. + const itemStack = inv.getItem(player.selectedSlot); + //If the item we're holding is our spear, we run code. + if (itemStack?.typeId === 'wiki:iron_spear') { + var container = player.getComponent('inventory').container + //The new item to be given. + var newItem = new ItemStack("wiki:iron_spear"); + var oldItem = container?.getItem(player.selectedSlot) + //Here's that tag! + player.removeTag("iron_spear") + } + //We subscribe a tick event to detect when we have the tag and if the item has durability less than the max. + let e = system.runInterval(() => { + if(player.hasTag("iron_spear") && itemStack?.typeId === 'wiki:iron_spear' && itemStack?.getComponent("durability").damage <= 125) { + player.removeTag("iron_spear") + //This gives our saved item (newItem) +1 durability each time we pick it up. + newItem.getComponent("durability").damage = oldItem.getComponent("durability").damage + 1; + container.setItem(player.selectedSlot, newItem); + //When we don't have the tag, we stop the tick event. + if(!player.hasTag("iron_spear")){ + system.clearRun(e); + }} + })} + }) + +``` + +## Final Product + +Once you've followed this guide, you should have your own working spear in-game. + +![](/assets/images/items/spears/spear_first_person.png) + +![](/assets/images/items/spears/spear_third_person.png) + +Example Pack Download: + +💾 Example Pack diff --git a/docs/wiki/items/throwable.md b/docs/wiki/items/throwable.md new file mode 100644 index 00000000..1eb66f43 --- /dev/null +++ b/docs/wiki/items/throwable.md @@ -0,0 +1,382 @@ +--- +title: Throwable Items +category: Tutorials +tags: + - intermediate +mentions: + - Fabrimat + - MedicalJewel105 + - Luthorius + - IlkinQafarov + - seeit360 + - TheItsNameless + - SmokeyStack + - ThomasOrs +--- + +::: tip +This tutorial assumes you have a basic understanding of Molang, animation controllers and entity definitions. +::: + +Items like the Splash Potion or the Trident are special items that can be thrown. Currently, there are two ways to accomplish something similar in your add-on, one that can be done in the stable release and one that needs the `Holiday Creator Features` experimental toggle to be enabled. + +## Stable method + +This method lets you detect the usage of an item through the `minecraft:food` component from an animation controller, and modifying the `player.json` you can then spawn an entity when that happens. + +### The Item + +First, you'll want to make the actual item: + +BP/items/throwable_item.item.json + +```json +{ + "format_version": "1.16.0", + "minecraft:item": { + "description": { + "identifier": "wiki:throwable_item" + }, + "components": { + "minecraft:max_stack_size": 16, + "minecraft:use_duration": 12000, + "minecraft:food": { + "can_always_eat": true + } + } + } +} +``` + +We can notice several things here: + +- `format_version` must be `1.16.0` +- `minecraft:use_duration` should be a high number, in order to stop the eating sound to play and to prevent the player from eating the item +- `minecraft:food` is used to allow player to actually "use" the item, so we can detect it + +Because the format version is `1.16.0`, your item needs an RP definition too: + +RP/items/throwable_item.item.json + +```json +{ + "format_version": "1.16.0", + "minecraft:item": { + "description": { + "identifier": "wiki:throwable_item", + "category": "Equipment" + }, + "components": { + "minecraft:icon": "throwable_item" + } + } +} +``` + +### The Entity + +The entity will be the actual thrown item, and it will behave like a projectile. +Make sure to add snowball runtime identifier to make your projectile to actually be shoot, not spawned. You can also experiment with other projectile runtime id's. + +BP/entities/throwable_item_entity.se.json + +```json +{ + "format_version": "1.16.0", + "minecraft:entity": { + "description": { + "identifier": "wiki:throwable_item_entity", + "is_spawnable": false, + "is_summonable": true, + "is_experimental": false, + "runtime_identifier": "minecraft:snowball" + }, + "components": { + "minecraft:collision_box": { + "width": 0.25, + "height": 0.25 + }, + "minecraft:projectile": { + "on_hit": { + "grant_xp": { + "minXP": 3, + "maxXP": 5 + }, + "impact_damage": { + "damage": 16 + }, + "remove_on_hit": {} + }, + "power": 0.7, + "gravity": 0.03, + "angle_offset": -20.0, + "hit_sound": "glass" + }, + "minecraft:physics": {}, + "minecraft:pushable": { + "is_pushable": true, + "is_pushable_by_piston": true + }, + "minecraft:conditional_bandwidth_optimization": { + "default_values": { + "max_optimized_distance": 80.0, + "max_dropped_ticks": 10, + "use_motion_prediction_hints": true + } + } + } + } +} +``` + +This entity is based on the Vanilla splash potion. + +You can then customize its behavior by editing the `minecraft:projectile` component, in this case the thrown item will grant some exp and will damage any entity it will hit. + +### The Animation Controller + +The animation controller is responsible for detecting the usage of the item and for telling the player entity to spawn a throwable entity. + +BP/animation_controllers/throwables.ac.json + +```json +{ + "format_version": "1.10.0", + "animation_controllers": { + "controller.animation.player.throwables": { // The ID we will reference in the player's entity description + "states": { + "default": { + "transitions": [ + { + // Current "q.is_item_name_any" takes 3 arguments, first is slot name, second is slot id, third is the item we want to check for + "throw_item": "q.is_item_name_any('slot.weapon.mainhand', 0, 'wiki:throwable_item') && q.is_using_item" + // "q.is_using_item" returns 'true' or 'false', in our case if player uses item it is going to return 'true' + } + ], + "on_entry": [ + // Resets the player entity in order to be able to throw another item + "@s wiki:reset_player" + ] + }, + "throw_item": { + "transitions": [ + { + "default": "1.0" + } + ], + "on_entry": [ + // Call the event in the player entity responsible of throwing the item + "@s wiki:throw_item", + // Remove the item from player's inventory + "/clear @s wiki:throwable_item -1 1" + ] + } + } + } + } +} +``` + +#### player.json + +:::tip +Always make sure that your `player.json` file is updated to the latest version available, depending on the game version you are working on. +You can do that [here](https://bedrock.dev/packs). +::: + +:::warning +Do not edit/remove existing parts of the `player.json` file unless you know what you are doing, as it could (and probably will) break the game. +::: + +Now, you have to register the animation controller to the `player.json` file: + +BP/entities/player.json + +```json +{ + "format_version": "1.18.20", + "minecraft:entity": { + "description": { + "identifier": "minecraft:player", + "is_spawnable": false, + "is_summonable": false, + "is_experimental": false, + "scripts": { + "animate": [ + "throwables_controller" // This should exactly match the same as the one below + ] + }, + "animations": { + "throwables_controller": "controller.animation.player.throwables" // ID as referenced in animation controller file + } + }, + "components": { + "minecraft:breathable": { // keeps breath timer bubbles from appearing + "total_supply": 15, + "suffocate_time": -1, + "inhale_time": 3.75, + "generates_bubbles": false + } + }, + ... + } +``` + +Then, you need to add all the events and component groups to the `player.json` file: + +BP/entities/player.json#minecraft:entity + +```json +"component_groups": { + "wiki:throw_entity": { // Contains a component that will spawn the entity + "minecraft:spawn_entity": { + "entities": { + "min_wait_time": 0, + "max_wait_time": 0, + "single_use": true, + "spawn_entity": "wiki:throwable_item_entity", + "num_to_spawn": 1 + } + } + } +}, +"events": { + "wiki:reset_player": { + "remove": { + "component_groups": [ + "wiki:throw_entity" + ] + } + }, + "wiki:throw_item": { + "add": { + "component_groups": [ + "wiki:throw_entity" + ] + } + } +} +``` + +## Experimental method + +This method requires the `Holiday Creator Features` experimental toggle to be enabled. + +### The Item + +BP/items/throwable_item.item.json + +```json +{ + "format_version": "1.16.100", + "minecraft:item": { + "description": { + "identifier": "wiki:throwable_item" + }, + "components": { + "minecraft:max_stack_size": 16, + "minecraft:on_use": { + "on_use": { + "event": "throw" + } + }, + "minecraft:icon": { + "texture": "apple" + } + }, + "events": { + "throw": { + "shoot": { + "projectile": "wiki:throwable_item_entity", + "launch_power": 2, + "angle_offset": 1 + }, + "swing": {}, + "decrement_stack": {}, + "run_command": { + "command": [ + "playsound fire.ignite", + "playsound mob.witch.throw" + ] + } + } + } + } +} +``` + +We can notice several things here: + +- `format_version` must be `1.16.100` +- `minecraft:on_use` will call an event every time the item is used (right-clicked) + +In the event: + +- `shoot` will shoot our entity +- `swing` will run the swing animation on the player +- `decrement_stack` will remove one item from the player's inventory +- `run_command` will execute commands when the item is shot, like playing sounds + + +### The Entity + +The entity file is the same as the Stable version. + + + +BP/entities/throwable_item_entity.se.json + +```json +{ + "format_version": "1.16.0", + "minecraft:entity": { + "description": { + "identifier": "wiki:throwable_item_entity", + "is_spawnable": false, + "is_summonable": true, + "is_experimental": false, + "runtime_identifier": "minecraft:snowball" + }, + "components": { + "minecraft:collision_box": { + "width": 0.25, + "height": 0.25 + }, + "minecraft:projectile": { + "on_hit": { + "grant_xp": { + "minXP": 3, + "maxXP": 5 + }, + "impact_damage": { + "damage": 16 + }, + "remove_on_hit": {} + }, + "power": 0.7, + "gravity": 0.03, + "angle_offset": -20.0, + "hit_sound": "glass" + }, + "minecraft:physics": {}, + "minecraft:pushable": { + "is_pushable": true, + "is_pushable_by_piston": true + }, + "minecraft:conditional_bandwidth_optimization": { + "default_values": { + "max_optimized_distance": 80.0, + "max_dropped_ticks": 10, + "use_motion_prediction_hints": true + } + } + } + } +} +``` + + + +## Conclusion + +Once you have your throwable item you can start trying several things, like playing with its power, effects, animations or combining it with an [AOE Cloud](/entities/introduction-to-aec). The only limit is your imagination. diff --git a/docs/wiki/items/tool-durability.md b/docs/wiki/items/tool-durability.md new file mode 100644 index 00000000..fc03ddc2 --- /dev/null +++ b/docs/wiki/items/tool-durability.md @@ -0,0 +1,267 @@ +--- +title: Tool Durability +category: Tutorials +tags: + - experimental + - intermediate + - scripting +mentions: + - MedicalJewel105 + - TheDoctor15 + - napstaa967 +--- + +## Introduction + +1.16.100+ items have different durability mechanic than 1.10 and 1.16 items. +Now you need to define when will the item get durability damage and also an event that does it. +What will be discussed on this page: +- Durability component +- Event that updates durability +- Damaging entities +- Block breaking +- `repair_amount` value +- `on_tool_used` event + +### Components + +BP/items/my_item.json#components + +```json +"minecraft:durability": { + "max_durability": 200 +} +``` + +`minecraft:durability` will give your item a set max durability + +## Event + +### Item event + +BP/items/my_item.json#events + +```json +"durability_update": { + "damage": { + "type": "none", + "amount": 1, + "target": "self" + } +} +``` + +When this event is called the item (`self` target) will receive durability damage. +Looks simple, doesn't it? + +### Script event + +For the script methods, we'll be using a function to damage our item + +This function supports unbreaking on items + +BP/scripts/main.js + +```js +function damage_item(item) { + // Get durability + const durabilityComponent = item.getComponent("durability") + var unbreaking = 0 + // Get unbreaking level + if (item.hasComponent("enchantments")) { + unbreaking = item.getComponent("enchantments").enchantments.getEnchantment("unbreaking") + if (!unbreaking) { + unbreaking = 0 + } else { + unbreaking = unbreaking.level + } + } + // Apply damage + if (durabilityComponent.damage == durabilityComponent.maxDurability) { + + return + } + durabilityComponent.damage += Number(Math.round(Math.random() * 100) <= durabilityComponent.getDamageChance(unbreaking)) + return item +} +``` + +## Damaging entities + +### Using scripts + +:::warning Experimental Script + +This script uses `@minecraft/server 1.9.0-beta`, which will change in the next minecraft update. +::: + +For format versions 1.20.40 and onward, `on_hurt_entity` no longer works. + +This provides a way to damage weapons using scripts + +BP/scripts/main.js + +```js +// Add your item IDs into this array +const my_items = ["wiki:silver_dagger"] + +world.afterEvents.entityHurt.subscribe(event => { + // If there's no source entity, skip + if (!event.damageSource.damagingEntity) return + + // Get equipped weapon + const equipment = event.damageSource.damagingEntity.getComponent("minecraft:equippable") + if (!equipment) return + const weapon = equipment.getEquipment(EquipmentSlot.Mainhand) + + // If there's no weapon, skip + if (!weapon) return + + // If the item is not in our item IDs, skip + if (!my_items.includes(weapon.typeId)) return + let newItem = damage_item(weapon) + equipment.setEquipment(EquipmentSlot.Mainhand, newItem) + if (!newItem) { + if (event.damageSource.damagingEntity instanceof Player) { + event.damageSource.damagingEntity.playSound("random.break") + } + } +}) +``` + +### on_hurt_entity + +:::warning + +`on_hurt_entity` was removed in format version 1.20.40 +::: + +`on_hurt_entity` can be defined in "minecraft:weapon" component. It tells the game what event should happen when player hurts entity using this item. + +BP/items/my_item.json#components + +```json +"minecraft:weapon": { + "on_hurt_entity": { + "event": "durability_update" + } +} +``` + +## Block breaking + +### Using scripts + +:::warning Experimental Script + +This script uses `@minecraft/server 1.9.0-beta`, which will change in the next minecraft update. +::: + +For format versions 1.20.20 and onward, `on_dig` no longer works. + +This provides a way to damage digger items by using scripts + +BP/scripts/main.js + +```js +// Add your item IDs into this array +const my_items = ["wiki:obsidian_pickaxe"] + +world.afterEvents.playerBreakBlock.subscribe(event => { + // If there's no item, skip + if (!event.itemStackAfterBreak) return + // If the item is not in our item IDs, skip + if (!my_items.includes(event.itemStackAfterBreak.typeId)) return + + // If player is in creative, skip + if (world.getPlayers({ + gameMode: GameMode.creative + }).includes(event.player)) return + const newItem = damage_item(event.itemStackAfterBreak) + event.player.getComponent("minecraft:equippable").setEquipment(EquipmentSlot.Mainhand, newItem) + if (!newItem) { + event.player.playSound("random.break") + } +}) +``` + +### on_dig + +:::warning + +`on_dig` was removed in format version 1.20.20 +::: + +`on_dig` can be defined in "minecraft:digger" component. It tells the game what event should happen when player dug a block using this item. + +BP/items/my_item.json#components + +```json +"minecraft:digger": { + "use_efficiency": true, + "destroy_speeds": [ + { + "block": { + "tags": "q.any_tag('wood')" + }, + "speed": 8, + "on_dig": { + // Defines event that should happen when block with tag wood was dug. + "event": "durability_update" + } + } + ], + "on_dig": { + // Defines event that should happen when any block was destroyed. + "event": "durability_update" + } +} +``` + +## repair_amount + +`repair_amount` can be defined in "minecraft:repairable" component. It tells the game how much of the item's durability should be back when it was repaired. + +BP/items/my_item.json#components + +```json +"minecraft:repairable": { + "repair_items": [ + { + "repair_amount": "context.other->q.remaining_durability + 0.05 * context.other->q.max_durability", + "items": [ + "bs:silver", + "bs:silver_axe" + ] + } + ] +} +``` + +Formula explanation: + +`"context.other->q.remaining_durability + 0.05 * context.other->q.max_durability"` + +The _final_ durability will be durability of the first axe + durability of the second axe + 5% of 2nd axe MAX durability. + +## on_tool_used + +(This might not work now) +`on_tool_used` is special event that can be called using tags. +Tags work kinda like runtime identifiers for entities. +Known tags: + +| Tag | Effects | How can be called | +| -------------------- | -------------- | -------------------------------------------------- | +| minecraft:is_axe | Strips logs | By interacting with blocks that axe interacts with | +| minecraft:is_hoe | Makes farmland | By interacting with blocks that hoe interacts with | +| minecraft:is_pickaxe | Unknown | Unknown | +| minecraft:is_sword | Unknown | Unknown | + +You can apply these tags this way: + +BP/items/my_item.json#components + +```json +"tag:minecraft:is_axe": {} +``` diff --git a/docs/wiki/items/troubleshooting-items.md b/docs/wiki/items/troubleshooting-items.md new file mode 100644 index 00000000..1d665d7a --- /dev/null +++ b/docs/wiki/items/troubleshooting-items.md @@ -0,0 +1,243 @@ +--- +title: Troubleshooting Items +category: General +nav_order: 4 +tags: + - help +mentions: + - SmokeyStack + - yanasakana + - SirLich + - MedicalJewel105 + - TheDoctor15 + - ThomasOrs +--- + +:::tip +This page contains troubleshooting information about _items_. You should read our [global troubleshooting](/guide/troubleshooting) document before continuing here. +::: + +## Start Here + +I followed a tutorial or tried to make my own item and something is wrong! Calm down. This page will help debug common issues. Follow the buttons and prompts to learn about possible issues with your item, and tips for fixing. + +Continue + +--- + +## 1.10 vs 1.16 Items? + +Before starting, you need to determine whether you creating an experimental item, or a stable item. + +:::tip +Versions `1.16.0` and prior are currently **stable** (Includes versions `1.16`, `1.14`, `1.13`, `1.12`, `1.10`). These **do not** require `Holiday Creator Features` to be enabled. + +🔗 Tutorial on [stable items](/guide/custom-item). +🔗 Documentation for [stable items](https://bedrock.dev/docs/1.16.0.0/1.16.20.54/Item) + +::: + +:::tip +Versions `1.16.100` and onward are **experimental**. These items **will not work unless** `Holiday Creator Features` **is enabled in the world**. + +🔗 Our tutorial on [experimental items](/items/item-components). +🔗 Documentation for [experimental items](https://bedrock.dev/docs/stable/Item) +::: + +### Continue + +1.10 format (stable) 1.16.100 format (experimental) + +--- + +## Stable Items + +This section contains troubleshooting information for stable items. Remember, you are using the `1.10` format, so you need both an RP file and a BP file for your item! If you only have a BP file, you have become confused between format versions. Please start again [here](#_1-10-vs-1-16-items). + +Find the issue you have, then read the prompts. + +- [I cannot /give myself my custom item!](#i-cannot-give-myself-my-custom-item) +- [My textures are missing!](#my-textures-are-missing) + +### I cannot /give myself my custom item! + +An issue here will be caused by the item file in the BP. + +- Confirm that your pack is actually applied to your world +- Confirm that your item is in the folder `BP/items/` +- Confirm that your item is valid, according to [jsonlint](https://jsonlint.com/). +- Confirm that your identifier is all lowercase, and looks similar to this: `wiki:my_item` + +### My textures are missing! + +Navigate to your `item_texture.json` file. Ensure that it is properly named, and in the correct folder. Some examples of wrong names: + +- ⚠️ `texture/item_texture.json` +- ⚠️ `textures/Item_texture.json` +- ⚠️ `textures/item_textures.json` + +Here is an example file to compare against: + +RP/textures/item_texture.json + +```json +{ + "resource_pack_name": "wiki", + "texture_name": "atlas.items", + "texture_data": { + "gem": { + "textures": "textures/items/gem" + } + } +} +``` + +Next, navigate to your items RP file. Ensure that it is in the correct folder. Example of incorrect path: + +- ⚠️ `item/gem.json` + +An example file, to compare against: + +RP/items/gem.json + +```json +{ + "format_version": "1.10", + "minecraft:item": { + "description": { + "identifier": "wiki:gem", + "category": "Nature" + }, + "components": { + "minecraft:icon": "gem", //make sure this string matches the string you put in item_texture.json! + "minecraft:render_offsets": "tools" + } + } +} +``` + +If you followed this properly, your item should now have a texture. + +--- + +## Experimental Items + +This section contains troubleshooting information for experimental items. Remember, you are using the `1.16` format, so there shouldn't be an RP file for your item! If you have both an RP file and a BP file, you have become confused between format versions. Please start again [here](#_1-10-vs-1-16-items). + +Find the issue you have, then read the prompts. + +- [Start Here](#start-here) +- [1.10 vs 1.16 Items?](#110-vs-116-items) + - [Continue](#continue) +- [Stable Items](#stable-items) + - [I cannot /give myself my custom item!](#i-cannot-give-myself-my-custom-item) + - [My textures are missing!](#my-textures-are-missing) +- [Experimental Items](#experimental-items) + - [I cannot /give myself my custom item!](#i-cannot-give-myself-my-custom-item-1) + - [My Textures Are Missing!](#my-textures-are-missing-1) + - [My item is Huge](#my-item-is-huge) +- [What now?](#what-now) + +### I cannot /give myself my custom item! + +- Confirm that your pack is actually applied to your world +- Confirm that your item is in the folder `BP/items/` +- Confirm that your item is valid, according to [jsonlint](https://jsonlint.com/). +- Confirm that your identifier is all lowercase, and looks similar to this: `wiki:my_item` + +### My Textures Are Missing! + +Navigate to your `item_texture.json` file. Ensure that it is properly named, and in the correct folder. Some examples of wrong names: + +- ⚠️ `texture/item_texture.json` +- ⚠️ `textures/Item_texture.json` +- ⚠️ `textures/item_textures.json` + +Here is an example file to compare against: + +RP/textures/item_texture.json + +```json +{ + "resource_pack_name": "wiki", + "texture_name": "atlas.items", + "texture_data": { + "gem": { + "textures": "textures/items/gem" + } + } +} +``` + +Next, navigate to your items BP file. Place the `minecraft:icon` component in your item file under the components section. Ensure that it is properly named. + +BP/items/your_item.json + +```json +{ + "format_version": "1.16.100", + "minecraft:item": { + "description": { + "identifier": "namespace:your_item", + "category" : "items" // This line is required + }, + "components": { + "minecraft:icon": { + "texture": "your_item_name" // Make sure this string matches the string you put in item_texture.json + } + }, + "events": {...} + } +} +``` + +If you followed this properly, your item should now have a texture. + +### My item is Huge + +To turn it to back into a normal size item (`16x16`), use render offsets and the following formula: `base value/(res/16)` + +The base values, `[0.075, 0.125, 0.075]`, seems to be the about the same scale value as normal items. + +BP/items/your_item.json#components + +```json +"minecraft:render_offsets":{ + "main_hand":{ + "first_person":{ + "scale":[ + 0, + 0, + 0 + ] + }, + "third_person":{ + "scale":[ + 0, + 0, + 0 + ] + } + }, + "off_hand":{ + "first_person":{ + "scale":[ + 0, + 0, + 0 + ] + }, + "third_person":{ + "scale":[ + 0, + 0, + 0 + ] + } + } +} +``` + +## What now? + +You've reached the end of the guide. If you still have any problems, feel free to [join the discord server](/discord) and ask your question there. diff --git a/docs/wiki/items/vanilla-usage-items.md b/docs/wiki/items/vanilla-usage-items.md new file mode 100644 index 00000000..45006062 --- /dev/null +++ b/docs/wiki/items/vanilla-usage-items.md @@ -0,0 +1,536 @@ +--- +title: Vanilla Usage Components +category: Documentation +mentions: + - MedicalJewel105 +--- + +This page was created with [Wiki Content Generator](https://github.com/Bedrock-OSS/bedrock-wiki-content-generator). If there are issues, contact us on [Bedrock OSS](https://discord.gg/XjV87YN) Discord server. +Note that not more than 8 examples are shown for each component to keep this page fast to load. Namespace `minecraft` was also removed. +If you want to see full page, you can do it [here](/items/vui-full). *Last updated for 1.20.10* + +## block + + + +camera + + + +```json +"minecraft:block": "minecraft:camera" +``` + + + +## camera + + + +camera + + + +```json +"minecraft:camera": { + "black_bars_duration": 0.2, + "black_bars_screen_ratio": 0.08, + "shutter_duration": 0.2, + "picture_duration": 1.0, + "slide_away_duration": 0.2 +} +``` + + + +## foil + + + +appleEnchanted + + + +```json +"minecraft:foil": true +``` + +golden_apple + + + +```json +"minecraft:foil": false +``` + + + +## food + + + +apple + + + +```json +"minecraft:food": { + "nutrition": 4, + "saturation_modifier": "low" +} +``` + +appleEnchanted + + + +```json +"minecraft:food": { + "nutrition": 4, + "saturation_modifier": "supernatural", + "can_always_eat": true, + "effects": [ + { + "name": "regeneration", + "chance": 1.0, + "duration": 30, + "amplifier": 4 + }, + { + "name": "absorption", + "chance": 1.0, + "duration": 120, + "amplifier": 3 + }, + { + "name": "resistance", + "chance": 1.0, + "duration": 300, + "amplifier": 0 + }, + { + "name": "fire_resistance", + "chance": 1.0, + "duration": 300, + "amplifier": 0 + } + ] +} +``` + +baked_potato + + + +```json +"minecraft:food": { + "nutrition": 5, + "saturation_modifier": "normal" +} +``` + +beef + + + +```json +"minecraft:food": { + "nutrition": 3, + "saturation_modifier": "low" +} +``` + +beetroot + + + +```json +"minecraft:food": { + "nutrition": 1, + "saturation_modifier": "normal" +} +``` + +beetroot_soup + + + +```json +"minecraft:food": { + "nutrition": 6, + "saturation_modifier": "normal", + "using_converts_to": "bowl" +} +``` + +bread + + + +```json +"minecraft:food": { + "nutrition": 5, + "saturation_modifier": "normal" +} +``` + +carrot + + + +```json +"minecraft:food": { + "nutrition": 3, + "saturation_modifier": "normal" +} +``` + + + +## hand_equipped + + + +appleEnchanted + + + +```json +"minecraft:hand_equipped": false +``` + + + +## max_damage + + + +clownfish + + + +```json +"minecraft:max_damage": 0 +``` + +cooked_fish + + + +```json +"minecraft:max_damage": 0 +``` + +cooked_salmon + + + +```json +"minecraft:max_damage": 0 +``` + +fish + + + +```json +"minecraft:max_damage": 0 +``` + +pufferfish + + + +```json +"minecraft:max_damage": 0 +``` + +salmon + + + +```json +"minecraft:max_damage": 0 +``` + + + +## max_stack_size + + + +beetroot_soup + + + +```json +"minecraft:max_stack_size": 1 +``` + +honey_bottle + + + +```json +"minecraft:max_stack_size": 16 +``` + +mushroom_stew + + + +```json +"minecraft:max_stack_size": 1 +``` + +rabbit_stew + + + +```json +"minecraft:max_stack_size": 1 +``` + +suspicious_stew + + + +```json +"minecraft:max_stack_size": 1 +``` + + + +## seed + + + +beetroot_seeds + + + +```json +"minecraft:seed": { + "crop_result": "beetroot" +} +``` + +carrot + + + +```json +"minecraft:seed": { + "crop_result": "carrots" +} +``` + +glow_berries + + + +```json +"minecraft:seed": { + "crop_result": "cave_vines", + "plant_at": [ + "cave_vines", + "cave_vines_head_with_berries" + ], + "plant_at_any_solid_surface": true, + "plant_at_face": "DOWN" +} +``` + +melon_seeds + + + +```json +"minecraft:seed": { + "crop_result": "melon_stem" +} +``` + +nether_wart + + + +```json +"minecraft:seed": { + "plant_at": "soul_sand", + "crop_result": "nether_wart" +} +``` + +pitcher_pod + + + +```json +"minecraft:seed": { + "crop_result": "pitcher_crop" +} +``` + +potato + + + +```json +"minecraft:seed": { + "crop_result": "potatoes" +} +``` + +pumpkin_seeds + + + +```json +"minecraft:seed": { + "crop_result": "pumpkin_stem" +} +``` + + + +## stacked_by_data + + + +appleEnchanted + + + +```json +"minecraft:stacked_by_data": true +``` + +clownfish + + + +```json +"minecraft:stacked_by_data": true +``` + +cooked_fish + + + +```json +"minecraft:stacked_by_data": true +``` + +cooked_salmon + + + +```json +"minecraft:stacked_by_data": true +``` + +fish + + + +```json +"minecraft:stacked_by_data": true +``` + +golden_apple + + + +```json +"minecraft:stacked_by_data": true +``` + +pufferfish + + + +```json +"minecraft:stacked_by_data": true +``` + +salmon + + + +```json +"minecraft:stacked_by_data": true +``` + + + +## use_duration + + + +apple + + + +```json +"minecraft:use_duration": 32 +``` + +appleEnchanted + + + +```json +"minecraft:use_duration": 32 +``` + +baked_potato + + + +```json +"minecraft:use_duration": 32 +``` + +beef + + + +```json +"minecraft:use_duration": 32 +``` + +beetroot + + + +```json +"minecraft:use_duration": 32 +``` + +beetroot_soup + + + +```json +"minecraft:use_duration": 32 +``` + +bread + + + +```json +"minecraft:use_duration": 32 +``` + +camera + + + +```json +"minecraft:use_duration": 100000 +``` + + + diff --git a/docs/wiki/items/vui-full.md b/docs/wiki/items/vui-full.md new file mode 100644 index 00000000..d3e33add --- /dev/null +++ b/docs/wiki/items/vui-full.md @@ -0,0 +1,1005 @@ +--- +title: Vanilla Usage Components - Full +category: Documentation +mentions: + - MedicalJewel105 +hidden: true +--- + +This page was created with [Wiki Content Generator](https://github.com/Bedrock-OSS/bedrock-wiki-content-generator). If there are issues, contact us on [Bedrock OSS](https://discord.gg/XjV87YN) Discord server. +Includes all examples. Namespace `minecraft` and some formatting have been removed to make the page load quickly. *Last updated for 1.20.10* + +## block + +camera + +```json +"minecraft:block": "minecraft:camera" +``` + +## camera + +camera + +```json +"minecraft:camera": { + "black_bars_duration": 0.2, + "black_bars_screen_ratio": 0.08, + "shutter_duration": 0.2, + "picture_duration": 1.0, + "slide_away_duration": 0.2 +} +``` + +## foil + +appleEnchanted + +```json +"minecraft:foil": true +``` + +golden_apple + +```json +"minecraft:foil": false +``` + +## food + +apple + +```json +"minecraft:food": { + "nutrition": 4, + "saturation_modifier": "low" +} +``` + +appleEnchanted + +```json +"minecraft:food": { + "nutrition": 4, + "saturation_modifier": "supernatural", + "can_always_eat": true, + "effects": [ + { + "name": "regeneration", + "chance": 1.0, + "duration": 30, + "amplifier": 4 + }, + { + "name": "absorption", + "chance": 1.0, + "duration": 120, + "amplifier": 3 + }, + { + "name": "resistance", + "chance": 1.0, + "duration": 300, + "amplifier": 0 + }, + { + "name": "fire_resistance", + "chance": 1.0, + "duration": 300, + "amplifier": 0 + } + ] +} +``` + +baked_potato + +```json +"minecraft:food": { + "nutrition": 5, + "saturation_modifier": "normal" +} +``` + +beef + +```json +"minecraft:food": { + "nutrition": 3, + "saturation_modifier": "low" +} +``` + +beetroot + +```json +"minecraft:food": { + "nutrition": 1, + "saturation_modifier": "normal" +} +``` + +beetroot_soup + +```json +"minecraft:food": { + "nutrition": 6, + "saturation_modifier": "normal", + "using_converts_to": "bowl" +} +``` + +bread + +```json +"minecraft:food": { + "nutrition": 5, + "saturation_modifier": "normal" +} +``` + +carrot + +```json +"minecraft:food": { + "nutrition": 3, + "saturation_modifier": "normal" +} +``` + +chicken + +```json +"minecraft:food": { + "nutrition": 2, + "saturation_modifier": "low", + "effects": [ + { + "name": "hunger", + "chance": 0.3, + "duration": 30, + "amplifier": 0 + } + ] +} +``` + +chorus_fruit + +```json +"minecraft:food": { + "nutrition": 4, + "saturation_modifier": "low", + "on_use_action": "chorus_teleport", + "on_use_range": [ + 8, + 8, + 8 + ], + "cooldown_type": "chorusfruit", + "cooldown_time": 20, + "can_always_eat": true +} +``` + +clownfish + +```json +"minecraft:food": { + "nutrition": 1, + "saturation_modifier": "poor" +} +``` + +cooked_beef + +```json +"minecraft:food": { + "nutrition": 8, + "saturation_modifier": "good" +} +``` + +cooked_chicken + +```json +"minecraft:food": { + "nutrition": 6, + "saturation_modifier": "normal" +} +``` + +cooked_fish + +```json +"minecraft:food": { + "nutrition": 5, + "saturation_modifier": "normal" +} +``` + +cooked_porkchop + +```json +"minecraft:food": { + "nutrition": 8, + "saturation_modifier": "good" +} +``` + +cooked_rabbit + +```json +"minecraft:food": { + "nutrition": 5, + "saturation_modifier": "normal" +} +``` + +cooked_salmon + +```json +"minecraft:food": { + "nutrition": 6, + "saturation_modifier": "good" +} +``` + +cookie + +```json +"minecraft:food": { + "nutrition": 2, + "saturation_modifier": "poor" +} +``` + +dried_kelp + +```json +"minecraft:food": { + "nutrition": 1, + "saturation_modifier": "poor" +} +``` + +fish + +```json +"minecraft:food": { + "nutrition": 2, + "saturation_modifier": "poor" +} +``` + +glow_berries + +```json +"minecraft:food": { + "nutrition": 2, + "saturation_modifier": "low", + "is_meat": false +} +``` + +golden_apple + +```json +"minecraft:food": { + "nutrition": 4, + "saturation_modifier": "supernatural", + "can_always_eat": true, + "effects": [ + { + "name": "regeneration", + "chance": 1.0, + "duration": 5, + "amplifier": 1 + }, + { + "name": "absorption", + "chance": 1.0, + "duration": 120, + "amplifier": 0 + } + ] +} +``` + +golden_carrot + +```json +"minecraft:food": { + "nutrition": 6, + "saturation_modifier": "supernatural" +} +``` + +honey_bottle + +```json +"minecraft:food": { + "nutrition": 6, + "saturation_modifier": "poor", + "can_always_eat": true, + "using_converts_to": "glass_bottle", + "remove_effects": [ + "poison" + ] +} +``` + +melon + +```json +"minecraft:food": { + "nutrition": 2, + "saturation_modifier": "low" +} +``` + +mushroom_stew + +```json +"minecraft:food": { + "nutrition": 6, + "saturation_modifier": "normal", + "using_converts_to": "bowl" +} +``` + +muttonCooked + +```json +"minecraft:food": { + "nutrition": 6, + "saturation_modifier": "good" +} +``` + +muttonRaw + +```json +"minecraft:food": { + "nutrition": 2, + "saturation_modifier": "low" +} +``` + +poisonous_potato + +```json +"minecraft:food": { + "nutrition": 2, + "saturation_modifier": "low", + "effects": [ + { + "name": "poison", + "chance": 0.6, + "duration": 5, + "amplifier": 0 + } + ] +} +``` + +porkchop + +```json +"minecraft:food": { + "nutrition": 3, + "saturation_modifier": "low" +} +``` + +potato + +```json +"minecraft:food": { + "nutrition": 1, + "saturation_modifier": "low" +} +``` + +pufferfish + +```json +"minecraft:food": { + "nutrition": 1, + "saturation_modifier": "poor", + "effects": [ + { + "name": "poison", + "duration": 60, + "amplifier": 1 + }, + { + "name": "nausea", + "duration": 15, + "amplifier": 1 + }, + { + "name": "hunger", + "duration": 15, + "amplifier": 2 + } + ] +} +``` + +pumpkin_pie + +```json +"minecraft:food": { + "nutrition": 8, + "saturation_modifier": "low" +} +``` + +rabbit + +```json +"minecraft:food": { + "nutrition": 3, + "saturation_modifier": "low" +} +``` + +rabbit_stew + +```json +"minecraft:food": { + "nutrition": 10, + "saturation_modifier": "normal", + "using_converts_to": "bowl" +} +``` + +rotten_flesh + +```json +"minecraft:food": { + "nutrition": 4, + "saturation_modifier": "poor", + "effects": [ + { + "name": "hunger", + "chance": 0.8, + "duration": 30, + "amplifier": 0 + } + ] +} +``` + +salmon + +```json +"minecraft:food": { + "nutrition": 2, + "saturation_modifier": "poor" +} +``` + +spider_eye + +```json +"minecraft:food": { + "nutrition": 2, + "saturation_modifier": "good", + "effects": [ + { + "name": "poison", + "chance": 1.0, + "duration": 5, + "amplifier": 0 + } + ] +} +``` + +suspicious_stew + +```json +"minecraft:food": { + "nutrition": 6, + "saturation_modifier": "normal", + "using_converts_to": "bowl", + "on_use_action": "suspicious_stew_effect" +} +``` + +sweet_berries + +```json +"minecraft:food": { + "nutrition": 2, + "saturation_modifier": "low", + "is_meat": false +} +``` + +## hand_equipped + +appleEnchanted + +```json +"minecraft:hand_equipped": false +``` + +## max_damage + +clownfish + +```json +"minecraft:max_damage": 0 +``` + +cooked_fish + +```json +"minecraft:max_damage": 0 +``` + +cooked_salmon + +```json +"minecraft:max_damage": 0 +``` + +fish + +```json +"minecraft:max_damage": 0 +``` + +pufferfish + +```json +"minecraft:max_damage": 0 +``` + +salmon + +```json +"minecraft:max_damage": 0 +``` + +## max_stack_size + +beetroot_soup + +```json +"minecraft:max_stack_size": 1 +``` + +honey_bottle + +```json +"minecraft:max_stack_size": 16 +``` + +mushroom_stew + +```json +"minecraft:max_stack_size": 1 +``` + +rabbit_stew + +```json +"minecraft:max_stack_size": 1 +``` + +suspicious_stew + +```json +"minecraft:max_stack_size": 1 +``` + +## seed + +beetroot_seeds + +```json +"minecraft:seed": { + "crop_result": "beetroot" +} +``` + +carrot + +```json +"minecraft:seed": { + "crop_result": "carrots" +} +``` + +glow_berries + +```json +"minecraft:seed": { + "crop_result": "cave_vines", + "plant_at": [ + "cave_vines", + "cave_vines_head_with_berries" + ], + "plant_at_any_solid_surface": true, + "plant_at_face": "DOWN" +} +``` + +melon_seeds + +```json +"minecraft:seed": { + "crop_result": "melon_stem" +} +``` + +nether_wart + +```json +"minecraft:seed": { + "plant_at": "soul_sand", + "crop_result": "nether_wart" +} +``` + +pitcher_pod + +```json +"minecraft:seed": { + "crop_result": "pitcher_crop" +} +``` + +potato + +```json +"minecraft:seed": { + "crop_result": "potatoes" +} +``` + +pumpkin_seeds + +```json +"minecraft:seed": { + "crop_result": "pumpkin_stem" +} +``` + +sweet_berries + +```json +"minecraft:seed": { + "crop_result": "sweet_berry_bush", + "plant_at": [ + "farmland", + "grass", + "dirt", + "podzol", + "moss_block", + "mycelium", + "mud", + "muddy_mangrove_roots", + "dirt_with_roots" + ] +} +``` + +torchflower_seeds + +```json +"minecraft:seed": { + "crop_result": "torchflower_crop" +} +``` + +wheat_seeds + +```json +"minecraft:seed": { + "crop_result": "wheat" +} +``` + +## stacked_by_data + +appleEnchanted + +```json +"minecraft:stacked_by_data": true +``` + +clownfish + +```json +"minecraft:stacked_by_data": true +``` + +cooked_fish + +```json +"minecraft:stacked_by_data": true +``` + +cooked_salmon + +```json +"minecraft:stacked_by_data": true +``` + +fish + +```json +"minecraft:stacked_by_data": true +``` + +golden_apple + +```json +"minecraft:stacked_by_data": true +``` + +pufferfish + +```json +"minecraft:stacked_by_data": true +``` + +salmon + +```json +"minecraft:stacked_by_data": true +``` + +## use_duration + +apple + +```json +"minecraft:use_duration": 32 +``` + +appleEnchanted + +```json +"minecraft:use_duration": 32 +``` + +baked_potato + +```json +"minecraft:use_duration": 32 +``` + +beef + +```json +"minecraft:use_duration": 32 +``` + +beetroot + +```json +"minecraft:use_duration": 32 +``` + +beetroot_soup + +```json +"minecraft:use_duration": 32 +``` + +bread + +```json +"minecraft:use_duration": 32 +``` + +camera + +```json +"minecraft:use_duration": 100000 +``` + +carrot + +```json +"minecraft:use_duration": 32 +``` + +chicken + +```json +"minecraft:use_duration": 32 +``` + +chorus_fruit + +```json +"minecraft:use_duration": 32 +``` + +clownfish + +```json +"minecraft:use_duration": 32 +``` + +cooked_beef + +```json +"minecraft:use_duration": 32 +``` + +cooked_chicken + +```json +"minecraft:use_duration": 32 +``` + +cooked_fish + +```json +"minecraft:use_duration": 32 +``` + +cooked_porkchop + +```json +"minecraft:use_duration": 32 +``` + +cooked_rabbit + +```json +"minecraft:use_duration": 32 +``` + +cooked_salmon + +```json +"minecraft:use_duration": 32 +``` + +cookie + +```json +"minecraft:use_duration": 32 +``` + +dried_kelp + +```json +"minecraft:use_duration": 16 +``` + +fish + +```json +"minecraft:use_duration": 32 +``` + +glow_berries + +```json +"minecraft:use_duration": 32 +``` + +golden_apple + +```json +"minecraft:use_duration": 32 +``` + +golden_carrot + +```json +"minecraft:use_duration": 32 +``` + +honey_bottle + +```json +"minecraft:use_duration": 40 +``` + +melon + +```json +"minecraft:use_duration": 32 +``` + +mushroom_stew + +```json +"minecraft:use_duration": 32 +``` + +muttonCooked + +```json +"minecraft:use_duration": 32 +``` + +muttonRaw + +```json +"minecraft:use_duration": 32 +``` + +poisonous_potato + +```json +"minecraft:use_duration": 32 +``` + +porkchop + +```json +"minecraft:use_duration": 32 +``` + +potato + +```json +"minecraft:use_duration": 32 +``` + +pufferfish + +```json +"minecraft:use_duration": 32 +``` + +pumpkin_pie + +```json +"minecraft:use_duration": 32 +``` + +rabbit + +```json +"minecraft:use_duration": 32 +``` + +rabbit_stew + +```json +"minecraft:use_duration": 32 +``` + +rotten_flesh + +```json +"minecraft:use_duration": 32 +``` + +salmon + +```json +"minecraft:use_duration": 32 +``` + +spider_eye + +```json +"minecraft:use_duration": 32 +``` + +suspicious_stew + +```json +"minecraft:use_duration": 32 +``` + +sweet_berries + +```json +"minecraft:use_duration": 32 +``` + diff --git a/docs/wiki/loot/index.md b/docs/wiki/loot/index.md new file mode 100644 index 00000000..c56fd342 --- /dev/null +++ b/docs/wiki/loot/index.md @@ -0,0 +1,10 @@ +--- +title: Loot, Recipes, and Trading +categories: +- title: General + color: blue +- title: Documentation + color: red +- title: Tutorials + color: green +--- \ No newline at end of file diff --git a/docs/wiki/loot/item-functions.md b/docs/wiki/loot/item-functions.md new file mode 100644 index 00000000..3f83989a --- /dev/null +++ b/docs/wiki/loot/item-functions.md @@ -0,0 +1,746 @@ +--- +title: Item Functions +category: Documentation +nav_order: 4 +tags: + - Stable + - Last updated for Version 1.18.10 +mentions: + - Ciosciaa + - MedicalJewel105 + - ThomasOrs +toc_max_level: 1 +--- + +Item functions modify the nature of an item in [loot tables](/loot/loot-tables) and [trade tables](/loot/trade-tables). + +TODO +can enchantments be prefixed with minecraft:/whatever? + +Functions +Note that every single thing tested here was in trade tables only +Usable in loot tables and trade tables only +Are objects with `function` and other props… +None accept Molang +No Java additional functions or properties were successful +All may be prefixed with any sequence of text followed by a colon, like `minecraft:exploration_map` or `d1245436576u:fio2ejfoijfiowejf::::::exploration_map` + +## General +A handful of functions are available for basic item properties. These functions are usable on any item. + +| Function | Container Loot | Block Drops | Fishing | Entity Drops | Entity Equipment | Trade Tables | +| -------------------- | -------------- | ----------- | ------- | ------------ | ---------------- | ------------ | +| `set_count` | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| `set_name` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `set_lore` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `set_data` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `random_block_state` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `random_aux_value` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `set_damage` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | + +### Count + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ❌ | + +::: tip NOTE +Trade tables use the [`"quantity"` property](/loot/trade-tables#quantity) to set their count. +::: + +The `set_count` function sets the count for that item entry. + +Count Function + +```json +{ + "function": "set_count", + + "count": { + "min": 2, + "max": 4 + } +} +``` + +The `"count"` property determines how many of that item should be yielded; it can either be provided as an integer or a [range object](#). Provided counts values may be larger than the stack size for that item. When this happens, the item will leak into other slots if in a container or separate into multiple different item stacks if dropped into the world. The count property actually defaults to `0`, so it should always be included. + +### Name + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +The name of an item can be set using the `set_name` function. Names are visible in the user interface when hovering over an item. Names can be changed by players using anvils. + +Name Function + +```json +{ + "function": "set_name", + + "name": "Cursed Bow" +} +``` + +The name to give the item is given with the string `"name"` property. By default, name text appears italicized. However, item names support format codes, and `§r` can be inserted at the start of the text to reset it to non-italics. Raw text is unsupported in item names. `\n` can be used for newlines. + +### Lore + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +The `set_lore` function sets the lore for an item. + +Lore Function + +```json +{ + "function": "set_lore", + + "lore": [ + "", + "" + ] +} +``` + +The `"lore"` property configures the lore. It can be represented as either a string or an array of strings. All lore strings support format codes but do not support localization. In the array form, each string represents a new line of lore. Each such string's formatting context is independent, meaning formatting will reset with each string. By default, purple and italicized text is used for lore; this can be reset by prepending the reset format code (`§r`) to each string as necessary. `\n` can be used within any lore string to form a newline while preserving the current formatting context. + +### Data + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`set_data` establishes the data for the given item, similar to the argument in the `/give` command. If used on a block, it will set the block's data value. If used on an item, it will set it's aux value. Unlike the command, however, `set_data` cannot set the durability of an item. For that, use [`durability`](#durability). + +Data Function + +```json +{ + "function": "set_data", + + "data": 2 +} +``` + +The `"data"` property sets the item's data. If not provided, it will default to `0`. `"data"` can either be provided as an integer or a range object. + +As an integer: +```json +"data": 1 +``` + +As a range object: +```json +"data": { + "min": 0, + "max": 5 +} +``` + +The object form will randomly select a data value inclusively between the provided minimum and maximum each instance this function's item entry is selected. + +### Block State + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`random_block_state` sets an individual block state for a block. + +Block State Function + +```json +{ + "function": "random_block_state", + + "block_state": "wiki:color", + "values": 3 +} +``` + +Sets a block state for a block +block_state +Required string name of block state +values +Can be number or min/max object +Defaults to 0… kinda required otherwise pointless? IDK… + +### Aux Value + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`random_aux_value` + +Aux Value Function + +```json +{ + "function": "random_aux_value", + + "values": { + "min": 2, + "max": 4 + } +} +``` + +Sets aux value of an item +values +Can be integer or min/max object +Min/max object chosen uniformly randomly +Only used for aux value; won't, for example, set damage of a tool but will set color of wool +Overrides any provided aux value as identifier `:suffix`, like `minecraft:wool:10` +Works on block data, too + +### Durability + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +Item durability can be set using the `set_damage` function. + +Durability Function + +```json +{ + "function": "set_damage", + + "damage": { + "min": 0.5, + "max": 1 + } +} +``` + +The `"damage"` property sets the item's durability. It can be represented either as a number or a [range object](#). Values are intended to range from `0` to `1`, where `0` is the minimum possible durability for an item and `1` is undamaged. + +## Item-Specific Data +Some functions are only usable by a certain set of items. See each function for which items are relevant. + +| Function | Container Loot | Block Drops | Fishing | Entity Drops | Entity Equipment | Trade Tables | +| -------------------- | -------------- | ----------- | ------- | ------------ | ---------------- | ------------ | +| `furnace_smelt` | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | +| `set_book_contents` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `exploration_map` | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ | +| `set_banner_details` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `random_dye` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `set_actor_id` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `fill_container` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | + +### Heat Item + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ❌ | +| Block drops | ❌ | +| Fishing | ❌ | +| Entity drops | ✅ | +| Entity equipment | ❌ | +| Trade table | ❌ | + +`furnace_smelt` + +Heat Item Function + +```json +{ + "function": "furnace_smelt" +} +``` + +auto-implies that the entity must’ve been on fire when they died +Vanilla files use a function condition for this, but even removing that condition still implies that the entity must’ve died on fire for the furnace_smelt function to trigger + +### Book Contents + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`set_book_contents` + +Book Contents Function + +```json +{ + "function": "set_book_contents", + + "title": "", + "author": "", + + "pages": [ + "", + "" + ] +} +``` + +Sets data for a book +Can only be used on `writable_book` or `written_book` +author +String name of the author +title +String name of the book +pages +Array of strings — each string is the contents of that page +Supports up to 50 strings and 798 characters per string +12,800‌ character limit across all pages +Use `\n` in the string (not `\\n`) to add newlines +Can’t use tabs +Can use color codes; Each different page string resets the color codes each time + +### Exploration Map + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`exploration_map` + +Exploration Map Function + +```json +{ + "function": "exploration_map", + + "destination": "village" +} +``` + +trade table info: +destination +Currently only `monument` `mansion`. +Nothing else, not even buried treasure (this one looks like it’ll work — names the map right instead of Unknown Map like the others, but it doesn’t point anywhere). :( + +Loot table info: +Destination +Works for any /locate location (see old recipe notes for caveats there; this is for container loot tables) +Only works if in the appropriate dimension +If a mansion or monument, gets named, colored, and icon’d correctly, corresponding to the right marker decoration +If invalid or no destination is given, shows no marker but still has the river and ocean lines on the map +Works in containers and both entity equipment and drops +Keep in mind how only 2 locations worked from traders + +### Banner Type + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`set_banner_details` + +Banner Type Function + +```json +{ + "function": "set_banner_details" +} +``` + +Sets type of a `banner` (only usable on this) +type +Can only be 0 or 1 +0 is just a white banner +1 is illager banner + +### Random Dyeing + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`random_dye` + +Random Dyeing Function + +```json +{ + "function": "random_dye" +} +``` + +Randomly dyes leather armor or horse armor +Doesn’t work on wool or whatever + +### Spawn Eggs + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`set_actor_id` + +Spawn Eggs Function + +```json +{ + "function": "set_actor_id" +} +``` + +Usable with spawn eggs +id +Should be the identifier for the mob +in trade tables, defaults to trader's entity type + +### Container Contents + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`fill_container` + +Container Contents Function + +```json +{ + "function": "fill_container" +} +``` + +Sets the contents of a container block +loot_table +Path to loot table file from behavior pack root + +loot_table needed or will just be the normal item +Cannot point to that current loot table +Works in containers and both entity stuff and blocks + +## Enchanting +| Function | Container Loot | Block Drops | Fishing | Entity Drops | Entity Equipment | Trade Tables | +| -------------------------- | -------------- | ----------- | ------- | ------------ | ---------------- | ------------ | +| `enchant_book_for_trading` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `enchant_with_levels` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `enchant_randomly` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `enchant_random_gear` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| `specific_enchants` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | + +### Enchant for Trading + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`enchant_book_for_trading` + +Enchant for Trading Function + +```json +{ + "function": "enchant_book_for_trading" +} +``` + +documented in trade tables + +### Level-Based Enchantments + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`enchant_with_levels` enchants items using enchantment table logic, optionally allowing for treasure enchantments. + +Level-Based Enchantments Function + +```json +{ + "function": "enchant_with_levels", + + "levels": { + "min": 15, + "max": 21 + }, + "treasure": true +} +``` + +Enchants books as though off an enchantment table with the given levels +Unlike enchanting table, doesn’t cap at 30, otherwise seems symmetrical +level 99999 gives ludicrously powerful books… with pretty much every possible enchantment on them +treasure + Enables treasure enchantments as possibilities for that item + boolean, defaults to false + If false, curses can't appear as possibilities; if true, they can +levels + Can be number or min/max object + Defaults to 0 + Can be negative, but will just be remapped as though 0. + +### Random Enchantments + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`enchant_randomly` + +Random Enchantments Function + +```json +{ + "function": "enchant_randomly" +} +``` + +Randomly picks a count of enchantments and their strengths for the given item +treasure +Enables treasure enchantments as possibilities for that item +boolean, defaults to false + +### Enchant Gear + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`enchant_random_gear` + +Enchant Gear Function + +```json +{ + "function": "enchant_random_gear" +} +``` + +Randomly picks a count of enchantments and their strengths for the given item +Pretty much like enchant_randomly, but seemingly no treasure enchantments +Not working on shears, but does even work on carrot-on-a-stick +chance +Number from 0 to 1 +Chance that the item is enchanted at all +Defaults to 0 +Going over 1 doesn't make it "more" enchanted + +### Specific Enchantments + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ✅ | +| Block drops | ✅ | +| Fishing | ✅ | +| Entity drops | ✅ | +| Entity equipment | ✅ | +| Trade table | ✅ | + +`specific_enchants` + +Specific Enchantments Function + +```json +{ + "function": "specific_enchants" +} +``` + +Applies a specific set of enchantments +enchants +Can be string array or object +For array, any mix of strings or objects (see below) +For string, an enchantment id +For object: +id +The identifier for the enchantment +See below for names +level +Optional, defaults to 1 +Can be an exact number or a 2-valued array, representing min and max, inclusive + +## External Factors +| Function | Container Loot | Block Drops | Fishing | Entity Drops | Entity Equipment | Trade Tables | +| --------------------------- | -------------- | ----------- | ------- | ------------ | ---------------- | ------------ | +| `looting_enchant` | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | +| `explosion_decay` | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | +| `set_data_from_color_index` | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | +| `trader_material_type` | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | + +### Held Tool Looting Enchantment + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ❌ | +| Block drops | ❌ | +| Fishing | ❌ | +| Entity drops | ✅ | +| Entity equipment | ❌ | +| Trade table | ❌ | + +`looting_enchant` + +Held Tool Looting Function + +```json +{ + "function": "looting_enchant", + + "count": { + "min": 0, + "max": 1 + } +} +``` + +Count can be an integer or min/max + +### Explosion Decay + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ❌ | +| Block drops | ✅ | +| Fishing | ❌ | +| Entity drops | ❌ | +| Entity equipment | ❌ | +| Trade table | ❌ | + +`explosion_decay` + +Explosion Decay Function + +```json +{ + "function": "explosion_decay" +} +``` + +By default, always survives. If in an explosion, has a chance of not dropping based on explosion power at that block’s location + +### Entity Color + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ❌ | +| Block drops | ❌ | +| Fishing | ❌ | +| Entity drops | ❌ | +| Entity equipment | ❌ | +| Trade table | ✅ | + +`set_data_from_color_index` + +Entity Color Function + +```json +{ + "function": "set_data_from_color_index" +} +``` + +Sets the data value of the block to the value of the `minecraft:color` component on the entity + +### Trader Material Type + +| Usage | Usable | +| ---------------- | ------ | +| Container loot | ❌ | +| Block drops | ❌ | +| Fishing | ❌ | +| Entity drops | ❌ | +| Entity equipment | ❌ | +| Trade table | ✅ | + +`trader_material_type` + +Trader Material Type Function + +```json +{ + "function": "trader_material_type" +} +``` + +Only in trades? Maybe it can work somewhere in loot diff --git a/docs/wiki/loot/loot-tables.md b/docs/wiki/loot/loot-tables.md new file mode 100644 index 00000000..384326dc --- /dev/null +++ b/docs/wiki/loot/loot-tables.md @@ -0,0 +1,292 @@ +--- +title: Loot Tables +category: Documentation +nav_order: 1 +tags: + - Stable + - Last updated for Version 1.18.10 +mentions: + - Ciosciaa + - Etanarvazac + - SmokeyStack +--- + +::: warning +This document is a work in progress. +::: + +Loot tables are used to select a set of items from a declared collection. Loot tables can be used from: + +- The `/loot` command +- Container contents +- Block drops +- Fishing +- Mob drops +- Equipment on spawned mobs +- Other various mob actions + +A different collection of items may be chosen each instance the same loot table would be used, based on [external conditions](#), and [innate randomness](#). Such variation is crucial for playability and adventuring, especially in more RPG-driven systems. + +## Integration +Loot tables are not registered add-on entries and are instead referenced by path from the above sources. Loot tables may be placed anywhere within a behavior pack, but it's recommended to place them under the top-level `loot_tables` directory, following vanilla convention. + + + +## Structure +Loot tables are represented as JSON objects with a single required `"pools"` array property. + +# + +```json +{ + "pools": [ + … + ] +} +``` + +The loot returned from a loot table invocation will be the *collective sum* of the yields of all pools provided here. + +### Pools +Pools act as isolated constructs for selecting items; the results of pools cannot be influenced by other pools. + +# + +```json +{ + "rolls": 1, + + "entries": [ + { + "type": "item", + "name": "wiki:silver" + } + ] +} +``` + +Two types of pools are available: general-purpose [weighted random pools](#weighted-random-pools) and [tiered pools](#tiered-pools), the latter of which is traditionally used for selecting mob equipment. + +#### Weighted Random Pools +A traditional weighted random pool selects items based on relative weight, choosing a number of yields based on a configured roll count. + +artifacts.json/pools/0 + +```json +{ + "rolls": { + "min": 2, + "max": 4 + }, + + "entries": [ + { + "type": "item", + "name": "minecraft:golden_apple", + "weight": 20 + }, + { + "type": "item", + "name": "minecraft:appleEnchanted", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:name_tag", + "weight": 30 + } + ] +} +``` + +##### Rolls + + +###### Bonus Rolls +The roll count for a weighted random pool may be altered based on the player's luck using the optional `"bonus_rolls"` property. + +```json + +``` + +##### Entry Weighting +The weight is the chance of this entry being chosen. The higher the weight in comparison to other entries in this "entries" array, the higher the chance of the entry being chosen. + +```json +"weight": 3 +``` + + + +###### Quality +The weight of an entry can be changed based on the player's luck using the quality property. + +```json +"quality": 2 +``` + +Currently, luck is only expressed when fishing with a fishing rod enchanted with Luck of the Sea. + +#### Tiered Pools +Tiered pools are used to select exactly one entry from a collection. + +```json +{ + "tiers": { + "initial_range": 2, + + "bonus_rolls": 3, + "bonus_chance": 0.095 + }, + + "entries": [ + { + "type": "loot_table", + "name": "loot_tables/entities/armor_set_leather.json" + }, + { + "type": "loot_table", + "name": "loot_tables/entities/armor_set_gold.json" + }, + { + "type": "loot_table", + "name": "loot_tables/entities/armor_set_chain.json" + }, + { + "type": "loot_table", + "name": "loot_tables/entities/armor_set_iron.json" + }, + { + "type": "loot_table", + "name": "loot_tables/entities/armor_set_diamond.json" + } + ] +} +``` + +A pool becomes tiered with the inclusion of the `"tiers"` object property: + +```json +"tiers": { + "initial_range": 2, + + "bonus_rolls": 3, + "bonus_chance": 0.095 +} +``` + +Entries in a tiered pool are *ordered*. The selected entry for a tiered pool is based on its index. To determine this index, a starting index is randomly rolled and then a batch of success rolls attempt to increment this starting index. + +The starting index is decided by rolling a random integer between 1 and the integer property `"initial_range"`. If no initial range is provided, it defaults to `1`, forcing a starting index of 1. + +Next, attempts are made to advanced the index using additional rolls. The count of these roll attempts is given as an integer to `"bonus_rolls"`. The chance that any such roll succeeds is given via `"bonus_chance"`. Chances for `"bonus_chance"` are out of 1, meaning `0.5` would be a 50% chance for any bonus roll to succeed. Each successful roll increases the index by 1. Both of these properties default to `0`, meaning both must be provided to use this additional rolls mechanic. + +The final determined index is used to select the corresponding entry as that pool's yield. Indices in tiered pools are one-indexed, meaning the first entry has an index of 1, the second has an index of 2, and so forth. If the determined index is larger than the entry count for that pool, no yield will be provided. + +::: warning +All [conditions](#) on entries in a tiered pool are ignored. Conditions on the pool itself are still allowed. +::: + +### Entries +Entries are the selectable units of a pool. Three different types of entries are available. + +```json + +``` + +#### Item Entries +Item entries are the fundamental entry type for selecting loot. Item entries refer to + +```json + +``` + +#### Loot Table Entries +Loot hierarchies can be formed using loot table entries. + +```json + +``` + +#### Empty Entries +When selected, empty entries won't yield any loot for that roll. + +```json +"type": "empty", +"weight": 4 +``` + +Empty entries can generally be mimicked using [a roll count](#) whose range includes 0, [random chance conditions](#), or [count functions](#) that could randomly select 0. Their primary advantage is readability when using [weighted random pools](#): denoting by weight when a roll won't yield an entry may be easier to understand. + +### Functions +Functions are what makes loot tables so powerful. They can do a wide range of tasks for each entry in your loot table. For example, they can change the amount of an item is dropped, what enchantments are present (even on items that normally cannot be enchanted), the item name, it's lore, and it can even write books! View [item functions](/loot/item-functions) for a full list of functions and how they're used. + +artifacts.json/pools/entries + +```json +{ + "type": "item", + "name": "minecraft:dirt", + "weight": 10, + "functions": [ + { + "function": "set_count", + "count": { + "min": 16, + "max": 64 + } + }, + { + "function": "set_name", + "name": "Pile of dirt" + } + ] +} +``` + +### Conditions +Conditions check to see if a certain criteria is met. Examples: "Was Zombie killed by Player", "Did the sword have the Looting enchantment on it? If so, what level?" + +artifacts.json/pools/entries + +```json +{ + "conditions": [ + { + "condition": "killed_by_player" + }, + { + "condition": "random_chance_with_looting", + "chance": 0.025, + "looting_multiplier": 0.01 + } + ], + "rolls": 1, + "entries": [ + { + "type": "item", + "name": "minecraft:iron_ingot", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:carrot", + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:potato", + "weight": 1 + } + ] +} +``` + +## Overrides + diff --git a/docs/wiki/loot/randomized-structure-loot.md b/docs/wiki/loot/randomized-structure-loot.md new file mode 100644 index 00000000..5140a315 --- /dev/null +++ b/docs/wiki/loot/randomized-structure-loot.md @@ -0,0 +1,125 @@ +--- +title: Randomized Structure Loot +category: Tutorials +mentions: + - MedicalJewel105 + - SirLich + - SmokeyStack + - Ciosciaa + - rebrainertv +tags: + - easy +--- + +Adding loot tables to containers in structure is easy, you need to have a PC and your choice of either [NBT Studio](https://github.com/tryashtar/nbt-studio/releases/download/v1.14.1/NbtStudio.exe) (executable) or [Loot Tabler](https://mcbe-essentials.github.io/structure-editor/loot-tabler) (browser application). + +## Setup +### Creating the Loot Table + +To start, create the directory `BP/loot_tables/chests` and create your loot table file here. + +You can learn how to make loot tables in [Beginners Guide](/guide/loot-table) + +BP/loot_tables/chests/my_structure_loot.json + +```json +{ + "pools": [ + { + "rolls": { + "min": 8, + "max": 10 + }, + "entries": [ + { + "type": "item", + "name": "minecraft:glass_bottle", + "functions": [ + { + "function": "set_count", + "count": { + "min": 4, + "max": 6 + } + } + ], + "weight": 1 + }, + { + "type": "item", + "name": "minecraft:potion", + "functions": [ + { + "function": "set_count", + "count": { + "min": 4, + "max": 6 + } + } + ], + "weight": 1 + } + ] + } + ] +} +``` + +### Exporting Structure + +Once you have created your loot table, export your structure into `BP/structures`. Then follow the steps for either NBT Studio or Loot Tabler + +![](/assets/images/tutorials/randomised-structure-loot/export_structure.png) + +## NBT Studio (Executable) +### Software Preparation + +Download and launch [NBT Studio](https://github.com/tryashtar/nbt-studio/releases/download/v1.14.1/NbtStudio.exe) + +### Adding the Loot Table + +Launch NBT Studio and open file `(Ctrl + O)` + +![](/assets/images/tutorials/randomised-structure-loot/open_file.png) + +Find your container (Ctrl + F) + +![](/assets/images/tutorials/randomised-structure-loot/find_container.png) + +Navigate to your container, `block_position_data` > `block_entity_data`. Add a string tag + +![](/assets/images/tutorials/randomised-structure-loot/add_string_tag1.png) + +Add `LootTable` and the file path to your loot table + +![](/assets/images/tutorials/randomised-structure-loot/add_string_tag2.png) + +Save changes (Ctrl + S) + +## Loot Tabler (Browser Application) + +:::tip +To export a structure on mobile devices, [Download this pack.](https://mcpedl.com/export-structure-button-android-addon/) +::: + +### Adding the Loot Table + +Open the website and click "Upload". Choose your structure file. + +![](/assets/images/tutorials/randomised-structure-loot/LootTable-step1.png) + +Find your container in the containers list, making use of the information displayed under "Container Options" + +![](/assets/images/tutorials/randomised-structure-loot/LootTable-step2.png) + +Under "Loot Table", enter the path to your loot table. Set "Loot Table Seed" to blank or `0` if you want the loot to generate randomly. If you want the loot table to generate consistently, enter a specific value. + +![](/assets/images/tutorials/randomised-structure-loot/LootTable-step3.png) + +Download your structure file and place it in `BP/structures`. + +## Testing + +Load your structure and open the container + +![](/assets/images/tutorials/randomised-structure-loot/test.png) diff --git a/docs/wiki/loot/recipes.md b/docs/wiki/loot/recipes.md new file mode 100644 index 00000000..03307aca --- /dev/null +++ b/docs/wiki/loot/recipes.md @@ -0,0 +1,778 @@ +--- +title: Recipes +category: Documentation +nav_order: 3 +tags: + - Stable + - Last updated for Version 1.20.30 +mentions: + - Ciosciaa + - SirLich + - MedicalJewel105 + - TheHyperWhale + - Luthorius + - QuazChick +--- + +Recipes are the means of handling several item transactions, namely those occurring in crafting tables, furnaces, campfires, and brewing stands. + +![](/assets/images/loot/recipes/recipe.png) + +::: tip +Anvil interactions are handled within an [item definition](/items/item-components), not via recipe files. Loom transactions are currently unavailable. +::: + +No experimental toggles are required to use recipes or any of their features. + +### Registration + +All recipes are stored in the `recipes` folder in the behavior pack root. The files can be named and organized under any folder hierarchy as desired. + +This arbitrary structure is used for the paths in this document: + + + +As an example, a "cold steel sword" might be crafted using the following [shaped recipe](#shaped-recipes): + +BP/recipes/crafting/weapons/cold_steel_sword.json +```json +{ + "format_version": "1.17.41", + "minecraft:recipe_shaped": { + "description": { + "identifier": "wiki:cold_steel_sword" + }, + "tags": ["crafting_table", "altar"], + "pattern": [ + "X", + "X", + "I" + ], + "key": { + "X": "wiki:cold_steel", + "I": "minecraft:stick" + }, + "unlock": [ + { + "item": "wiki:cold_steel" + }, + { + "item": "minecraft:wool", + "data": 3 + }, + { + "context": "PlayerInWater" + } + ], + "result": "wiki:cold_steel_sword" + } +} +``` + +## Shared Properties and Structures + +### Format Version + +The [format version](/guide/format-version) is intended to version the schema used for the body of a recipe. It is provided with the top-level `"format_version"` property. + +#/ +```json +"format_version": "1.17.41" +``` + +In practice, the format version can be set to any value or even omitted. + +::: warning +It's strongly recommended to include a format version anyway, choosing a value that represents an actual Minecraft version to help future-proof the code. Consider using the current release version or last major release version. +::: + +### Description + +The `"description"` object, required within any recipe type, holds the identifier of a recipe. + +#/minecraft:recipe_shaped/ +```json +"description": { + "identifier": "wiki:cold_steel_sword" +} +``` + +Its only child is the required `"identifier"` property, which is designed to uniquely identify a recipe across all packs applied to a world. There are no namespacing requirements for recipe identifiers except that no two full recipe identifiers in a single pack may match. + +::: warning +It's strongly recommended to use a namespace. Namespaces are a standard in other add-on domains and assist in logically scoping the recipe to a pack, lessening possibilities of collisions for players wanting to use multiple behavior packs in their world. +::: + +### Tags + +Recipes are linked to crafting interfaces using the required `"tags"` array property, which must be placed within any recipe type. These tags will make the recipe be shared across different blocks that uses the `minecraft:crafting_table` component. When the recipe does not inlcude the `crafting_table` tag, or any vanilla tag, but a tag from your custom block, the recipe will only be shared to that custom block and not the crafting table/stonecutter/etc. At least one tag must be provided. + +#/minecraft:recipe_shaped/ +```json +"tags": ["crafting_table", "altar"] +``` + +Vanilla interfaces are exposed to tags for each set of recipe types. + +Crafting: + +- `crafting_table` +- `stonecutter` +- `smithing_table` + +::: +warning Note that if you want to make a smithing recipe, you will need to use `:netherite_ingot` for the second slot, though using a different identifier will not work. **This no longer works after 1.18.30**. +::: + +Cooking and Smelting: + +- `furnace` +- `blast_furnace` +- `smoker` +- `campfire` +- `soul_campfire` + +Brewing: + +- `brewing_stand` + +Education: + +- `material_reducer` + +::: tip +Additionally, [custom crafting tables](/blocks/block-components#crafting-table) can declare a custom tag for crafting recipes to use. Custom cooking and smelting blocks and custom brewing stands are not currently available. +::: + +::: tip +To effectively disable a recipe (useful for [overriding](#overrides) a prior recipe), set the tag array to `[""]`. +::: + +### Recipe Unlocking +Minecraft 1.20.30 added recipe unlocking to the game. In order to have your recipes use this function, you `manifest.json` must have a `min_engine_version` of 1.20.11 (1.20.30 is recommender). You also need to add the `unlock` array with its objects to your recipe. +```json + "unlock": [ + { + "item": "wiki:cold_steel" //item to unlock recipe + }, + { + "item": "minecraft:wool", //item to unlock recipe + "data": 3 + }, + { + "context": "PlayerInWater" //event to unlock recipe + } + ] +``` +Each object in this array contains `"item"` and this tells the recipe what item the player needs in their inventory in order for this recipe to be unlocked. It also accepts data values. `"context"` is used to determine what event unlocks this recipe. `"PlayerInWater"` will unlock this recipe when the player enters water. This is also the only known context for recipes. + +### Item Descriptors + +Working with recipes entails referencing items across a number of properties. Items may be provided in one of two formats: a string reference or an item object. Both formats have means of handling data values, but only the item object may be used to specify a count for that item (usable in recipe outputs). For recipe inputs, if no data value is provided, items with any data value under that identifier will be usable for that input. The data value for an output defaults to `0` if one is not explicitly provided. Selecting recipe inputs by item tags is not supported. + +#### String Reference + +Generally, a string reference is just the namespace and identifier combination for that item: + +#/minecraft:recipe_shapeless/ingredients/0 +```json +"minecraft:planks" +``` + +String references additionally support specification of a data value as a suffix: + +#/minecraft:recipe_shapeless/ingredients/0 +```json +"minecraft:planks:2" +``` + +#### Item Object + +The item object is a more explicit construct for referencing items. + +#/minecraft:recipe_shapeless/ingredients/0 +```json +{ + "item": "minecraft:planks", + "data": 2, + "count": 3 +} +``` + +The required `"item"` property functions the same as the string reference format. Although an explicit data field is available, the data suffix string format is still supported in the `"item"` property. However, unlike the suffix form, `"data"` can accept Molang. The Molang here is evaluated once on world load, not per-crafting attempt. Variables cannot be used to pass data between properties in a recipe. Furthermore, the nature of input items cannot be queried. Currently, the only known usable query in the `"data"` property is `q.get_actor_info_id`, used to look up the ID of an entity's spawn egg by its identifier: + +#/minecraft:recipe_shapeless/result +```json +{ + "item": "minecraft:spawn_egg", + "data": "q.get_actor_info_id('minecraft:chicken')" +} +``` + +The optional integer `"count"` property may be used to stack items. It defaults to `1`. Currently, setting the count only functions in [crafting](#crafting) and [furnace](#heating) recipe outputs and [shapeless recipe ingredients](#ingredients). A provided count is ignored in other locations. + +::: tip NOTE +If a count greater than `1` is provided for an item that does not stack, an error will be thrown. There is no way to force single-return recipe outputs, like those in shapeless recipes or brewing mixes, to return multiple items in one transaction. +::: + +::: warning +Despite having similarities to trade [table item descriptors](/loot/trade-tables#items), recipe item descriptors cannot use functions. +::: + +#### Identifier Additions + +Additional identifiers not typically usable are available to recipes to describe basic potions. + +#/minecraft:recipe_brewing_mix/input +```json +"minecraft:potion_type:strength" +``` + +These identifiers are not usable in the object notation, only the string notation. Variants are unavailable for splash and lingering potions. All such identifiers follow the format: minecraft:potion_type:potion_effect, where potion_effect can be one of the following: + +- `water` +- `awkward` +- `mundane` +- `thick` +- `healing` +- `regeneration` +- `swiftness` +- `strength` +- `harming` +- `poison` +- `slowness` +- `weakness` +- `water_breathing` +- `fire_resistance` +- `nightvision` +- `invisibility` +- `leaping` +- `slow_falling` +- `turtle_master` +- `wither` + +Where supported, `long_` and `strong_` prefixes may be used to designate modified potions, such as `minecraft:potion_type:strong_poison`. + +## Crafting + +Crafting operations instantly transform inputs to outputs using crafting grids. Two crafting recipe types are available: [shapeless recipes](#shapeless-recipes), whose inputs may be arranged in any way, and [shaped recipes](#shaped-recipes), used to define strict arrangements of inputs. +Crafting recipes support both crafting tables and stonecutters: + +#/minecraft:recipe_shapeless/ +```json +"tags": ["crafting_table", "stonecutter"] +``` + +`"crafting_table"` applies to both vanilla crafting tables and the player 2 × 2 crafting grid in their inventory. There is currently no way to opt into one but not the other. Crafting recipes additionally support custom tags, linking recipes to a [crafting grid provided by a custom block](/blocks/block-components#crafting-table). + +### Shapeless Recipes + +Shapeless recipes simply bind a collection of inputs to a single output on a crafting grid. + +![](/assets/images/loot/recipes/shapeless_recipe.png) + +BP/recipes/decorations/knobs/brass.json +```json +{ + "format_version": "1.17.41", + "minecraft:recipe_shapeless": { + "description": { + "identifier": "wiki:brass_door_knob" + }, + "group": "handles", + "tags": ["construction_bench"], + "ingredients": [ + "wiki:brass", + { + "item": "wiki:screw", + "data": 2 + } + ], + "unlock": [ + { + "item": "wiki:cold_steel" + }, + { + "item": "minecraft:wool", + "data": 3 + }, + { + "context": "PlayerInWater" + } + ], + "result": { + "item": "wiki:door_knob", + "data": 3 + } + } +} +``` + +#### Ingredients + +The required `"ingredients"` array property lists the items required as inputs for the crafting recipe. + +#/minecraft:recipe_shapeless/ +```json +"ingredients": [ + "wiki:brass", + { + "item": "wiki:screw", + "data": 2 + } +] +``` + +Each entry is an [item descriptor](#item-descriptors). If an ingredient provides a count, that count must be expressed across multiple crafting grid slots. Using stacked items in a single grid slot to yield a product is unsupported. If the items required for crafting are available but the count of ingredients is greater than the crafting interface being used supports, the recipe will automatically be made unavailable in the recipe book. + +#### Shapeless Results + +Shapeless recipe outputs are expressed using the required `"result"` property and may be expressed as either an [item descriptor](#item-descriptors) or an array of a single item descriptor. + +#/minecraft:recipe_shapeless/ +```json +"result": { + "item": "wiki:door_knob", + "data": 3 +} +``` + +### Shaped Recipes + +Shaped recipes enforce that the ingredients used during crafting conform to a strict shape. + +![](/assets/images/loot/recipes/shaped_recipe.png) + +BP/recipes/covered_arch.json +```json +{ + "format_version": "1.17.41", + "minecraft:recipe_shaped": { + "description": { + "identifier": "wiki:covered_arch" + }, + "tags": ["crafting_table"], + "pattern": [ + "SSS", + "I I", + "I I" + ], + "key": { + "S": "wiki:cloth", + "I": "wiki:support" + }, + "unlock": [ + { + "item": "wiki:cold_steel" + }, + { + "item": "minecraft:wool", + "data": 3 + }, + { + "context": "PlayerInWater" + } + ], + "result": [ + { + "item": "wiki:covered_arch", + + "count": 3 + }, + "wiki:crafting_scrap" + ] + } +} +``` + +#### Patterns + +The required `"pattern"` array property establishes the shape used for the recipe. + +#/minecraft:recipe_shaped/ +```json +"pattern": [ + "SSS", + "I I", + "I I" +] +``` + +Each entry in the array is a string representing a row in the crafting grid. Each character in each string represents a slot within that row. Spaces by default represent slots that should be empty. + +Characters act as a shorthand to visually describe an item. Each distinct character is matched with a [key](#keys) that dictates what item should be present in that slot. + +::: tip +If the pattern is only comprised of spaces, empty crafting interfaces able to fit that pattern's size will constantly match the recipe. A player may retrieve an infinite amount of the crafting output, including immediately filling their inventory to the limit upon shift-retrieving the result. +::: + +##### Row Normalization + +The pattern grid must be at most 3 × 3 but may be smaller. If string lengths are mismatched, Minecraft will automatically extend shorter strings, implying spaces in filled slots. The following two are equivalent: + +#/minecraft:recipe_shaped/ +```json +"pattern": [ + "MA", + "IFI", + "M" +] +``` + +#/minecraft:recipe_shaped/ +```json +"pattern": [ + "MA ", + "IFI", + "M " +] +``` + +::: tip NOTE +Currently, no crafting grids, including those configurable from custom blocks, may be larger than 3 × 3. If the expressed pattern is unusable within the current crafting interface, the recipe will automatically be unavailable in the recipe book. +::: + +##### Grid Freedom + +Spaces are not automatically implied to fill in any remaining slots in the 3 × 3 space. If a provided pattern is smaller than the crafting grid being used, the pattern can be used anywhere so long as the structure and contents are maintained. As an example, consider the following pattern on a crafting table: + +#/minecraft:recipe_shaped/ +```json +"pattern": [ + "O" + "OO" +] +``` + +The "L" shape isn't restricted to the upper-left corner of the crafting grid. Using a 3 × 3 grid as an example, the pattern would be usable with any of these configurations: + + +*Underscores represent empty slots.* +```txt +O__ +OO_ +___ +``` +```txt +_O_ +_OO +___ +``` +```txt +___ +O__ +OO_ +``` +```txt +___ +_O_ +_OO +``` + + +To restrict placements to a particular location, use explicit spaces, which enforce empty slots in certain locations. The following is only usable in the upper-left corner of a grid: + +#/minecraft:recipe_shaped/ +```json +"pattern": [ + "O " + "OO " + " " +] +``` + +##### Symmetry + +All shaped recipes are innately horizontally symmetric: + +#/minecraft:recipe_shaped/ +```json +"pattern": [ + "Z " + " Z " + " Z" +] +``` + +The preceding recipe may also be used by a player as though it were set to: + +#/minecraft:recipe_shaped/ +```json +"pattern": [ + " Z" + " Z " + "Z " +] +``` + +#### Keys + +Keys provide meaning to characters in a [pattern](#patterns), done via the required `"key"` object property, which maps key names to [item descriptors](#item-descriptors). + +#/minecraft:recipe_shaped/ +```json +"key": { + "S": "wiki:cloth", + "I": "wiki:support" +} +``` + +Every key present in the pattern should be accounted for here. Keys names are case-sensitive. If an item supports multiple data values and no data value is provided, any item of that identifier will be usable for that key. Any `"count"` property present in an item descriptor is ignored and regarded as `1`; stacked items in a crafting grid slot are only consumable one at a time. + +::: tip NOTE +Any unicode character from `U+0020` to `U+07FF` may be used as a key name. If a key name has more than one character, only the first character is considered. Since spaces are by default used to signify empty slots on a grid and there's no way to re-designate a key for a blank slot, it's not recommended to use them as a key. +::: + +::: warning +If a character in the pattern is not present in the key map, it will be treated as though it were a space, a designated empty tile. +::: + +### Recipe Unlocking +Minecraft 1.20.30 added recipe unlocking to the game. In order to have your recipes use this function, you `manifest.json` must have a `min_engine_version` of 1.20.11 (1.20.30 is recommender). You also need to add the `unlock` array with its objects to your recipe. +```json + "unlock": [ + { + "item": "wiki:cold_steel" //item to unlock recipe + }, + { + "item": "minecraft:wool", //item to unlock recipe + "data": 3 + }, + { + "context": "PlayerInWater" //event to unlock recipe + } + ] +``` +Each object in this array contains `"item"` and this tells the recipe what item the player needs in their inventory in order for this recipe to be unlocked. `"context"` is used to determine what event unlocks this recipe. `"PlayerInWater"` will unlock this recipe when the player enters water. This is also the only known context for recipes. + +#### Shaped Results + +Shaped crafting recipe outputs behave very similarly to their [shapeless counterparts](#shapeless-results). Unlike array results for shapeless recipes, however, shaped recipe result arrays may contain more than one [item descriptor](#item-descriptors). + +#/minecraft:recipe_shaped/ +```json +"result": [ + { + "item": "wiki:covered_arch", + "count": 3 + }, + "wiki:crafting_scrap" +] +``` +The first entry in the array will be used as the visible output of the crafting block. All other values are automatically placed in the player's inventory upon removing the visible result from the output slot. There does not seem to be a limit on the number of items that may be returned from a crafting action. + +::: tip NOTE +Any items not able to fit in the player's inventory are instead placed in the input slots of the crafting table left-to-right and then top-to-bottom. Anything not able to fit there is then thrown from the player as though they had used the "Drop Item" action. +::: + +### Recipe Book + +The recipe book automatically indexes and displays available recipes to the player, intelligently accounting for [ingredient counts](#ingredients) in shapeless recipes or [pattern constraints](#patterns) in shaped recipes. When multiple recipes point to the same output, the recipe book uses its own unique prioritization system. + +When both recipes being compared are shapeless recipes, the following rules determine prioritization in order: + +- Lower ingredient count of the _first_ listed ingredient +- More negative [priority](#priority) +- Lower-valued identifier string + +For shaped recipes, recipes with "lesser" identifiers, when compared as strings, are always prioritized. + +When comparing a shaped recipe to a shapeless recipe, the rules for comparing shapeless recipes are used; however, the interpreted count of ingredients for the shaped recipe is different from its actual ingredient count. Exactly how the ingredient count for a shaped recipe is determined is unknown. + +### Grouping + +This section is included informatively. Groups are present in crafting recipes in vanilla definitions, given with the optional `"group"` string property. + +#/minecraft:recipe_shaped/ +```json +"group": "slingshots" +``` + +It is currently unknown what, if anything, this property achieves. Presumably, it would be used with the [recipe book](#recipe-book). Neither using new custom groups nor reusing groups from vanilla definitions appear to achieve anything. + +### Priority + +Crafting recipes support an additional property for handling input collisions, `"priority"`, which primarily acts as a [tiebreaker](#prioritization) when multiple recipes could possibly apply to the given situation. Priorities are provided directly within the crafting recipe type object. + +#/minecraft:recipe_shaped/ +```json +"priority": 2 +``` + +Crafting recipes with lower priority values take precedence. So, if all else is equal, a recipe with a priority of `0` would be used over a recipe with priority `1`. Priorities may be negative if necessary. If `"priority"` is not provided, a priority of `0` is implied. + +## Heating + +Furnace recipes are used to transform an item using a heat source over a period of time. A slight misnomer, furnace recipes are used with any interface that involves a heat source, including campfires. + +![](/assets/images/loot/recipes/furnace_recipe.png) + +BP/recipes/magic/magic_ash.json +```json +{ + "format_version": "1.17.41", + "minecraft:recipe_furnace": { + "description": { + "identifier": "wiki:magic_ash" + }, + "tags": ["soul_campfire"], + "input": "wiki:bone_fragments", + "output": { + "item": "wiki:magic_ash", + "count": 4 + } + } +} +``` + +All vanilla heating blocks are supported via tags. + +#/minecraft:recipe_furnace/ +```json +"tags": ["furnace", "blast_furnace", "smoker", "campfire", "soul_campfire"] +``` + +### Heating Transactions + +Furnace recipes bind exactly one input [item descriptor](#item-descriptors) to exactly one output item descriptor. + +#/minecraft:recipe_furnace/ +```json +"input": "wiki:bone_fragments" +"output": { + "item": "wiki:magic_ash", + "count": 4 +} +``` + +Any count given in the input is ignored. XP returns and fuel sources for a cooking and smelting recipe cannot be altered. The time required to heat an item is set by the used block and is unchangeable. + +## Brewing + +Brewing recipes are used to transform an item using another item as a catalyst. Two brewing recipe types are available: [brewing mixes](#brewing-mixes), which do not transition data from input to output, and [brewing containers](#brewing-containers), which do. + +Only one interface supports brewing recipes: + +#/minecraft:recipe_brewing_container/ +```json +"tags": ["brewing_stand"] +``` + +### Brewing Transactions + +Brewing transactions are similar to [heating transactions](#heating-transactions), requiring an input and output, each pointing to a single [item descriptor](#item-descriptors). Brewing recipes, however, also require the `"reagent"` property as a catalyst, which also can only point to a single item descriptor. + +#/minecraft:recipe_brewing_mix/ +```json +"input": "wiki:flask", +"reagent": "wiki:jade", +"output": "wiki:insanity_resistance" +``` + +Provided count values are ignored in these brewing properties. Items are meant to transform one at a time in a brew. + +::: warning +If the input item for a brewing recipe has the ability to stack, the _entire_ stack will be consumed in the transformation. There are currently no workarounds to avoid this. +::: + +After the brewing time has passed, the catalyst is consumed, and output items directly replace input items. + +::: warning +Currently, the stackability of the produced output is bugged, regardless of whether a data value was specified. In particular, the output is incompatible and will not stack with items of the same identifier and data value. +::: + +### Brewing Mixes + +Brewing mixes are simple brewing recipes theoretically designed to isolate the data value of the input from the data value of the output. + +![](/assets/images/loot/recipes/brewing_mix_recipe.png) + +BP/recipes/brewing/negative/paralysis.json +```json +{ + "format_version": "1.17.41", + "minecraft:recipe_brewing_mix": { + "description": { + "identifier": "wiki:paralysis_brew" + }, + "tags": ["brewing_stand"], + "input": "wiki:amberglass_flask", + "reagent": "wiki:viporfly_poison", + "output": "wiki:paralysis_brew" + } +} +``` + +::: warning +Unfortunately, assigned data values are broken for brewing mix recipes. + +In general, a brewing recipe will never work if a data value is supplied to the input. The only exceptions are if the input is one of the following: + +- `minecraft:potion` +- `minecraft:splash_potion` +- `minecraft:lingering_potion` +- [Potion identifier additions](#identifier-additions) + +If a data value is specified for a reagent using the `"data"` property format, a brew occurs when any item with the given identifier is placed as a reagent for that recipe, regardless of data value. However, the brew only succeeds if the correct data value is matched. If it’s not, the brew will appear to succeed, but the input will not be transformed into the output; despite the brew failing, the reagent and a percentage of the blaze powder fuel are consumed anyway. +::: + +### Brewing Containers + +Brewing containers are designed to pass the data value of an input to the transformed output. + +![](/assets/images/loot/recipes/brewing_container_recipe.png) + +BP/recipes/illumination_potion.json +```json +{ + "format_version": "1.17.41", + "minecraft:recipe_brewing_container": { + "description": { + "identifier": "wiki:illumination_potion" + }, + "tags": ["brewing_stand"], + "input": "minecraft:potion", + "reagent": "wiki:radiant_berries", + "output": "wiki:illumination_potion" + } +} +``` + +Brewing containers are stricter than [brewing mixes](#brewing-mixes) about their inputs. Only the following item types are allowed in a brewing container recipe: + +- `minecraft:potion` +- `minecraft:splash_potion` +- `minecraft:lingering_potion` +- [Potion identifier additions](#identifier-additions) + +Because the data value is carried downstream from input to output in a brewing container recipe, assigned data values in `"input"` and `"output"` are ignored. + +## Overrides + +As with all domains in add-ons, the pack order in the behavior pack list affects how Minecraft chooses files to use during gameplay. Higher-listed behavior pack entries take priority over lower-listed ones, including the base vanilla pack. + +To override a recipe in a lower-listed pack, the recipe type and identifiers must both match. The override file can be named and located in any way — only the contents matter. Partial overrides are not accepted in recipes; the entire recipe must be redefined. + +::: warning +Overrides only work if the recipe type is an _exact_ match. In most cases, a mismatch results in a new recipe created alongside the existing one. + +If attempting to construct an override that converts between the two crafting recipe types, an error will be thrown. To circumvent this, first copy the vanilla definition into the pack. Next, set the `"tags"` for that file to `[""]`; this effectively disables the recipe. Finally, set up a new file as the other crafting recipe type, choosing a different identifier to avoid the error. +::: + +## Prioritization + +After considering [overrides](#overrides), if multiple recipes would apply based on the inputs, the outputs are selected using the following tiebreakers, considered in order: + +- Recipes declared in higher-ordered packs in the world behavior packs list +- If for crafting recipes, _lower_-valued [priority properties](#priority) +- If for crafting recipes, [shaped recipes](#shaped-recipes) over [shapeless ones](#shapeless-recipes) +- "Lesser" identifiers, as interpreted by string comparison diff --git a/docs/wiki/loot/trade-tables.md b/docs/wiki/loot/trade-tables.md new file mode 100644 index 00000000..cfc19b44 --- /dev/null +++ b/docs/wiki/loot/trade-tables.md @@ -0,0 +1,703 @@ +--- +title: Trade Tables +category: Documentation +nav_order: 2 +tags: + - Stable + - Last updated for Version 1.18.10 +mentions: + - Ciosciaa + - SirLich + - TheItsNameless +--- + +Trade tables represent the fundamental data behind trading item transactions for an entity. Trade tables are not standalone; they must be referenced from an [entity component](https://bedrock.dev/docs/stable/Entities#minecraft%3Aeconomy_trade_table). Using the randomizing properties available to trade tables, trade offers, item counts, and cost calculations may vary across entity instances, even if all would point to the same trade table. + +![](/assets/images/loot/trade_tables/trading.png) + +Trade tables are not identified or versioned. Like loot tables, trade tables do not support Molang and instead rely on JSON constructs, like range objects and [functions](#functions). Despite being different, trade tables still support comments. + +## Integration + +Trade tables don't represent a primary add-on system, like blocks or biomes. They aren't registered by being placed in a specific folder; instead, they're referenced (from entities). Trade tables may be placed anywhere within a behavior pack. + +::: tip +It's recommended to follow vanilla convention and place all trade tables within the top-level `trading` directory in a behavior pack. From there, any hierarchy can be employed. +::: + + + +The following example is referenced and analyzed throughout the document: + + + +BP/trading/minister.json +```json +{ + "tiers": [ + { + "groups": [ + { + "num_to_select": 1, + + "trades": [ + { + "wants": [ + { + "item": "wiki:blessing_glyph", + "quantity": { + "min": 2, + "max": 4 + }, + + "price_multiplier": 0.5 + }, + { + "item": "minecraft:book" + } + ], + "gives": [ + { + "item": "minecraft:enchanted_book", + "functions": [ + { + "function": "enchant_book_for_trading", + + "base_cost": 4, + "base_random_cost": 12, + "per_level_cost": 4, + "per_level_random_cost": 8 + } + ] + } + ], + "max_uses": 7, + + "trader_exp": 3 + }, + { + "wants": [ + { + "item": "wiki:crystalline_spiritite", + "quantity": 32, + + "price_multiplier": 0.125 + } + ], + "gives": [ + { + "item": "wiki:exalted_blade", + "functions": [ + { + "function": "enchant_with_levels", + + "treasure": true, + "levels": { + "min": 15, + "max": 25 + } + } + ] + } + ], + "max_uses": 2, + + "reward_exp": false, + "trader_exp": 8 + } + ] + } + ] + }, + { + "total_exp_required": 28, + + "trades": [ + { + "wants": [ + { + "choice": [ + { + "item": "wiki:sacred_stones", + "quantity": { + "min": 4, + "max": 6 + }, + + "price_multiplier": 0.5 + }, + { + "item": "wiki:blessed_beads", + "quantity": { + "min": 16, + "max": 24 + }, + + "price_multiplier": 0.5 + } + ] + } + ], + "gives": [ + { + "item": "wiki:aeleon_jewels", + "quantity": { + "min": 4, + "max": 6 + } + } + ], + "max_uses": 2 + } + ] + } + ] +} +``` + + +## Structure + +Trade tables are represented as un-versioned, un-namespaced objects. + +# + +```json +{ + "tiers": [ + { + "groups": […] + }, + { + "total_exp_required": 28, + + "trades": […] + } + ] +} +``` + +Trade tables use [tiers](#tiers) to structure trade organization. Tiers are defined with the required top-level `"tiers"` array property. Tiers appear in order in the trading interface. + +### Tiers + +Tiers act as an unlockable set of trades and represent the highest level of grouping in a trade table. + +#/tiers/0 + +```json +{ + "groups": […] +} +``` + +#/tiers/1 + +```json +{ + "total_exp_required": 28, + + "trades": […] +} +``` + +Each tier must either represent a set of [trades](#trades) (as `"trades"`) or [trade groups](#groups) (as `"groups"`); one of these properties is required. If trades are specified, all such trades will appear for that tier. If instead groups are given, trades from all listed groups will be used for that tier; how each group selects its trades depends on its configuration. + +::: tip NOTE +If both `"trades"` and `"groups"` are given in a tier, the trades declaration is ignored in favor of groups. +::: + +Within a tier, trades appear in order in the trading interface. If trades are grouped, those groups will appear in their defined order as well, organized by group and then by trade. Trades in one group are not visually differentiable from trades in other groups; only tiers are visually separated and identifiable. + +#### Experience Requirement + +Tiers are unlocked when the _trader_ meets experience thresholds. Each trader has its own internal lifetime experience that accumulates when trading with players. The amount of experience obtained per trade depends on that trade's [experience reward](#trader-experience). The optional `"total_exp_required"` property specifies how much experience the trader needs in order for that tier to unlock. + +#/tiers/1/ + +```json +"total_exp_required": 28 +``` + +By default, the amount of experience needed is set to the index of the trade tier. Therefore, the second tier would require the trader to have 1 XP; the third tier would require 2 XP; and so forth. The first tier is always unlocked automatically, [regardless of its set experience threshold](#initial-tier-experience). + +#### Tier Unlocking + +Tiers are unlocked in order. When a new tier is unlocked, the subsequent tier is additionally checked to see if its threshold is met by the current XP. If it is, it unlocks and checks its subsequent tier, and so forth. Tier unlocking is checked when the rewarded trader experience would suffice for multiple tiers or if a [provided initial experience](#initial-tier-experience) would unlock subsequent tiers when correctly updated by the game. + +::: tip NOTE +Since tiers are checked one-at-a-time, if tier unlocking would stop due to the XP requirements of a tier not being met, no subsequent tiers will be checked, even if those later tiers' XP requirements have been met. +::: + +##### Initial Tier Experience + +Special handling occurs for a non-zero experience threshold in the first tier. If negative, _all_ tiers will be unlocked. If greater than 0, the initial experience of the trader is set to the provided value. + +::: warning +When the initial tier's experience threshold is non-zero, a manual update is required for a trader's trades to reflect the actual nature of their trade table. In these cases, performing a trade or closing and re-opening the trading interface will update the interface correctly. Initially, only the first tier will be available even if other tiers should be unlocked. +::: + +##### Tier Freezing + +Excluding the [initial tier](#initial-tier-experience), it's possible to freeze trades at a tier: + +Example Tier Freeze + +```json +"total_exp_required": -1 +``` + +When its prior tier is unlocked, a tier with a negative XP requirement will immediately unlock, [as expected](#tier-unlocking). However, it will be impossible for the player to progress to any subsequent tiers. + +### Trade Groups + +Trade groups are a way to randomly select which trades an individual trader should use for a tier. + +#/tiers/0/groups/0 + +```json +{ + "num_to_select": 1, + + "trades": […] +} +``` + +The trades from which to select are given with the required `"trades"` array; each entry is a [trade](#trades). A select number of these trades, indicated by the optional `"num_to_select"` property, will be picked for that tier for each trader. If `"num_to_select"` is `0`, all trades will be selected; this is the default. + +::: tip NOTE +Trade groups cannot be nested for advanced chance selection. +::: + +::: tip +Currently, no random selection count is possible. Nor is weighting by trade, but trades can be duplicated within the array to effectively increase their likelihood of being selected. +::: + +### Trades + +Trades represent a transaction between a trader and the player. + +#/tiers/0/trades/1 + +```json +{ + "wants": […], + "gives": […], + "max_uses": 2, + + "reward_exp": false, + "trader_exp": 8 +} +``` + +Once a trade is picked for a trade slot, it will not fundamentally change. Only the [quantity](#quantity) can be modified in certain situations. + +::: tip +Individual trade definitions can affect more than just trades themselves. Notably, an entity can [hold a particular item](https://bedrock.dev/docs/stable/Entities#minecraft%3Abehavior.trade_interest) in response to the player holding an item. +::: + +#### Wanted and Given Items + +The fundamental transactional units are declared using `"wants"` and `"gives"`; players trade with `"wants"` to receive `"gives"`. Both properties must be arrays and are required. + +#/tiers/0/trades/1/ + +```json +"wants": […], +"gives": […] +``` + +A trade can have between 1 and 2 wanted entries and must have exactly 1 given entry. Each entry of either array may be either an [item](#items) or a [choice](#choices). + +The trading interface will adapt depending on the number of items wanted. In some circumstances, some trading modifiers, such as [quantity-modifying enchantment functions](#quantity-modifying-enchantment-functions), only affect the first wanted item. + +::: tip NOTE +If an object is provided as an entry that contains both item and choice properties, only the choice part is considered; the item parts will be ignored. +::: + +#### Trade Limit + +A trader can typically only perform an individual trade a set number of times before having to resupply. The numeric `"max_uses"` property configures this number. + +#/tiers/0/trades/1/ + +```json +"max_uses": 2 +``` + +Trade limits are specific to each trade. Diminishing supply in one trade won't affect another trade, even if both trades have the same wanted and given items. By default, a trader will be able to carry out an individual trade 7 times before needing to resupply. + +::: tip NOTE +The act of resupplying is handled by an entity component (`"minecraft:trade_resupply": {}`). +::: + +If a value of `0` is given, that trade will be shown in the trading interface but will be impossible to use. If a negative value is given, that trade will never need resupplying; it will be infinitely usable. + +#### Player Experience + +Experience orbs intended for the _player_ can be disabled for a trade using the optional Boolean `"reward_exp"` property. + +#/tiers/0/trades/1/ + +```json +"reward_exp": false +``` + +By default, `"reward_exp"` is true, and the player will be rewarded with some experience for trading. The amount of experience received is not modifiable within a trade table. + +#### Trader Experience + +Traders may receive experience when the player finalizes a trade. This property is the key to establishing a trade progression system with a trader using [tiers](#tiers). + +#/tiers/0/trades/1/ + +```json +"trader_exp": 8 +``` + +The amount of experience to reward the _trader_ is given the the optional numeric property `"trader_exp"`. By default, the trader will receive 1 XP. + +::: tip +For non-linearly spaced tiers, it's typical for the trader experience to increase in higher tiers. This way, lower-tier trades will have less leveling impact than higher-tier trades. +::: + +### Choices + +Choices are simple objects for randomly selecting an item to use for a trade. One item is selected with uniform randomness for that trade for each instance of a trader. + +#/tiers/1/trades/0/wants/0 + +```json +{ + "choice": [ + { + "item": "wiki:sacred_stones", + … + }, + { + "item": "wiki:blessed_beads", + … + } + ] +} +``` + +Choices only contain the required `"choice"` array property. Each entry in the array is an [item](#items). At least one item must be provided. + +::: tip NOTE +Choices cannot be nested. +::: + +::: tip +There are currently no means of specifying a weight for a given item, but an item may be duplicated within the array to effectively increase its likelihood for being selected. +::: + +### Items + +Items are the subjects of a trade. Their definitions are shared between wanted and given items, but there are some various implications depending on location used. + +#/tiers/1/trades/0/wants/0/choice/0 + +```json +{ + "item": "wiki:sacred_stones", + "quantity": { + "min": 4, + "max": 6 + }, + + "price_multiplier": 0.5 +} +``` + +#/tiers/0/groups/0/trades/1/gives/0 + +```json +{ + "item": "wiki:exalted_blade", + "functions": [ + { + "function": "enchant_with_levels", + + "treasure": true, + "levels": { + "min": 15, + "max": 25 + } + } + ] +} +``` + +#### Item Reference + +Items are referenced within trades using the required `"item"` string property. + +#/tiers/1/trades/0/wants/0/choice/0/ + +```json +"item": "wiki:exalted_blade" +``` + +The item reference must point to the identifier of an item. A data value can be provided in-place to the reference as a suffix: + +Example Data Assignment + +```json +"item": "minecraft:log:2" +``` + +::: tip +Data values can also be set (and much more conveniently randomized) using the `set_data` function. +::: + +If no data value is specified for a _wanted_ item, any item with that identifier may be traded. If no data value is specified for a _given_ item, a data value of `0` is implied. + +#### Quantity + +The optional `"quantity"` property specifies the count of items wanted or given in a trade. + +#/tiers/1/trades/0/wants/0/choice/0/ + +```json +"quantity": { + "min": 4, + "max": 6 +} +``` + +Quantity can be expressed as either an integer literal or a range object, such as seen above. If expressed as a range, a random value is selected uniformly inclusively within the specified limits. If no quantity is provided, the item count will default to 1. + +::: tip NOTE +Quantity is always bounded by the stack size and can only affect a single slot in a trade. It's impossible to, for example, enforce a requirement of 100 planks from a single slot (although this can be done using 2 `"wants"`) or giving 2 un-stackable swords to the player in a single trade. +::: + +#### Price Multiplier + +The price multiplier dictates how an item's [base quantity](#quantity) is altered due to certain events. + +#/tiers/1/trades/0/wants/0/choice/0/ + +```json +"price_multiplier": 0.5 +``` + +`"price_multiplier"` is optional and defaults to `0`. Two systems exist that use the price multiplier: a modern and a legacy system. In the modern system, the given price multiplier can only affect the _first wanted item_ in a trade. In the legacy system, any _wanted items_ can be affected. + +##### Fluctuation Factors + +Trade prices fluctuate as a result of serval factors: + +- An increased demand, occurring when trading for the same item across multiple [resupplies](#trade-limit) +- Being recently cured, such as villagers being cured from being zombie villagers +- Being _near_ a trader who was recently cured +- Trading with a player who is affected with "Hero of the Village" + +The price multiplier affects all these situations with the exception of a player having "Hero of the Village" when using the new pricing formula, which uses fixed values. + +##### Cost Calculations + +The price multiplier directly and solely affects cost increases in response to an increased demand for a trade. By default, demand is 0 and cannot decrease past that value. Demand for a trade stacks, increasing when resupplying after that trade [has been exhausted](#trade-limit) and decreasing if no trades occurred between resupplies. + +Cost increase due solely to demand is linear, where each increase in demand adds a proportion of the base cost, given by the price multiplier. Assuming the following variables… + +| Variable | Meaning | +| -------- | ------------------------------------------------------------------------------------ | +| _c_ | Total cost | +| _p_ | Base cost, including [quantity overrides](#quantity-modifying-enchantment-functions) | +| _m_ | Price multiplier | +| _d_ | Current demand | + +
+…The following formula can be used to calculate the total cost when no other factors are present: + +_c_ = _p_ × (1 + _m_ \* _d_) + +::: tip NOTE +Other situations additionally use entity properties for cost calculations and are not provided here. +::: + +If the price multiplier is `0`, the quantity will remain constant in most situations (except the "Hero of the Village" modifier using the new pricing formula). + +::: tip NOTE +A negative price multiplier is possible but can't affect increasing costs due to [demand](#trade-limit); the multiplier will effectively be capped to `0`. However, negative values do affect prices in response to the trader recently being cured, the trader being nearby another trader who was recently cured, or trading with a player affected with "Hero of the Village" _using the legacy pricing formulas_. +::: + +#### Functions + +Functions are used to modify the nature of the item. The optional `"functions"` array contains a collection of functions to be applied to the item. + +#/tiers/0/groups/0/trades/1/gives/0/ + +```json +"functions": [ + { + "function": "enchant_with_levels", + + "treasure": true, + "levels": { + "min": 15, + "max": 25 + } + } +] +``` + +The functions used by trade tables are shared with loot tables. When used ([where usable](#unusable-wanted-item-functions)) in a wanted item declaration, they act to restrict the nature of the wanted item. Such function restrictions can only affect the first wanted item. + +##### Generally Unusable Functions + +In general, functions behave well for trading; however, the following do not work anywhere in trade tables: + +- `set_count` +- `furnace_smelt` +- `looting_enchant` +- `trader_material_type` + +::: tip NOTE +`set_count`'s functionality is replaced by the [quantity property](#quantity). + +`trader_material_type`, seen only in a single vanilla trade table, would theoretically set the data value of the item based on the mark variant of the entity, but this doesn't seem to be usable in any custom way. +::: + +##### Unusable Wanted Item Functions + +In general, using functions to specify item attributes for a wanted item will require the offered item to conform to those attributes. However, the following functions do not enforce a strict match and are therefore useless on wanted items: + +- `set_name` +- `set_lore` +- `set_damage` +- `set_book_contents` +- `random_dye` +- `fill_container` + +##### Quantity-Modifying Enchantment Functions + +2 functions actually set the quantity for the first _wanted item_ if being used as _given items_, potentially overriding any provided [quantity](#quantity) for that first wanted item: + +- `enchant_with_levels` +- `enchant_book_for_trading` + +::: tip NOTE +Despite overriding the quantity, all [modified trade prices](#fluctuation-factors) adapt correctly. These functions cannot affect the quantity of a second wanted item, even when using the legacy cost formulas. If these functions are used on a _wanted item_, the quantity is not overridden. +::: + +###### Enchant with Levels Function + +`enchant_with_levels` randomly enchants an item as through enchanted from an enchantment table. + +#/tiers/0/groups/0/trades/1/gives/0/functions/0 + +```json +{ + "function": "enchant_with_levels", + + "treasure": true, + "levels": { + "min": 5, + "max": 25 + } +} +``` + +The cost for the first wanted item is determined by adding this function's chosen level value (capped to `0` if it would be negative) to the original [quantity](#quantity). The level value is computed from the optional `"levels"` property. If a numeric literal is used, that value is the chosen level value. If a range object is used, as above, a random number is rolled inclusively between the provided minimum and maximum. That random number then acts as the chosen level value. In the above example, the first wanted item's cost would be increased by 5 to 25. + +###### Enchant Book for Trading Function + +`enchant_book_for_trading` is intended solely for trading. Its properties combine to determine the first wanted item's cost. + +#/tiers/0/groups/0/trades/0/gives/0/functions/0 + +```json +{ + "function": "enchant_book_for_trading", + + "base_cost": 4, + "base_random_cost": 12, + "per_level_cost": 4, + "per_level_random_cost": 8 +} +``` + +This function was only designed to be used on books, rolling for a single enchantment across all possible non-curse enchantments, including treasure enchantments. The function doesn't adapt to the current item. If used on a book, an enchantment will always successfully be applied; if used on something else enchantable, it's possible the item won't be successfully enchanted. + +::: tip NOTE +Presumably, when failing, the function rolls for an enchantment not applicable to the item and then fails to apply this irrelevant enchantment, resulting in an unenchanted item. The successfulness of enchanting a non-book is therefore proportional to the number of enchantments applicable to that item. +::: + +The total cost is set from a base cost, which is independent of the rolled enchantment, and a per-level cost, which is dependent on the random roll. All cost configuration properties are optional. + +The base cost is computed by summing a starting value and a random roll. The starting value is given with `"base_cost"`, which defaults to `2`. The random roll is provided via `"base_random_cost"`, which defaults to `4`. A number will be uniformly randomly selected inclusively between 0 and the `"base_random_cost"` when a trade is generated for a trader. + +For each level on the chosen enchantment, the same process occurs as in the base cost calculations: a fixed value is added to a uniformly randomly selected value. In this case, the base per-level cost is given with `"per_level_cost"`, which defaults to `3`, and the random per-level cost is given with `"per_level_random_cost"`, which defaults to `10`. The random per-level roll may be different for each level. + +Once the base cost and costs for each level are calculated, they are summed together to form the total cost. Finally, if the chosen enchantment is a treasure enchantment, the cost is then doubled. As usual, this cost cannot be less than 1 or greater than the stack size of that item. This formula holds true regardless of the pricing system being used by the trader. + +::: warning +If either random cost property is negative, there seems to be a 50-50 chance that the cost will be either the given [quantity](#quantity) or the maximum stack size for that first wanted item. +::: + +::: tip +If the total combined cost would be negative (assuming no negative random cost properties were used), the provided [quantity](#quantity) of the affected wanted item is used instead. The simplest means of guaranteeing this would be: + +Example Quantity-Based Enchanted Book Cost + +```json +{ + "function": "enchant_book_for_trading", + + "base_cost": -1, + "base_random_cost": 0, + "per_level_cost": 0, + "per_level_random_cost": 0 +} +``` + +::: + +##### Spawn Egg Trader Binding + +The `"set_actor_id"` function is used to set the data value of a spawn egg based on a provided entity identifier, given with `"id"`. + +Example Spawn Egg Trader Binding + +```json +{ + "function": "set_actor_id" +} +``` + +In trade tables, if no ID is provided, the trader's entity type will be assigned to the egg. + +## Overrides + +Because trade tables do not use in-data identifiers, they are overridden simply by replacing a prior trade table with a new one. You can learn more about [asset overrides here](/concepts/overwriting-assets) + +Below are the currently used vanilla trade tables for each trader: +|Trader|Path| +|-|-| +|Stone Mason|`BP/trading/economy_trades/stone_mason_trades.json`| +|Farmer|`BP/trading/economy_trades/farmer_trades.json`| +|Fisherman|`BP/trading/economy_trades/fisherman_trades.json`| +|Butcher|`BP/trading/economy_trades/butcher_trades.json`| +|Shepherd|`BP/trading/economy_trades/shepherd_trades.json`| +|Leather Worker|`BP/trading/economy_trades/leather_worker_trades.json`| +|Librarian|`BP/trading/economy_trades/librarian_trades.json`| +|Cartographer|`BP/trading/economy_trades/cartographer_trades.json`| +|Cleric|`BP/trading/economy_trades/cleric_trades.json`| +|Tool Smith|`BP/trading/economy_trades/tool_smith_trades.json`| +|Weapon Smith|`BP/trading/economy_trades/weapon_smith_trades.json`| +|Fletcher|`BP/trading/economy_trades/fletcher_trades.json`| +|Armorer|`BP/trading/economy_trades/armorer_trades.json`| +|Wandering Trader|`BP/trading/economy_trades/wandering_trader_trades.json`| + +::: tip NOTE +Additional trade tables exist directly within the `trading` folder, but these are deprecated. Only the tables in the `economy_trades` sub-folder are currently used. +::: + +Alternatively, a trader entity definition can be updated to point to a new trade table location. diff --git a/docs/wiki/loot/trading-behavior.md b/docs/wiki/loot/trading-behavior.md new file mode 100644 index 00000000..e2b83983 --- /dev/null +++ b/docs/wiki/loot/trading-behavior.md @@ -0,0 +1,32 @@ +--- +title: Trading Behavior +category: General +nav_order: 2 +mentions: + - Ciosciaa + - MedicalJewel105 +--- + +Making an entity a trader is accomplished via `minecraft:trade_table` or `minecraft:economy_trade_table` components. Both of them will open a trading UI from the given path, but the economy trades component has some more options referring to some Village and Pillage trading mechanics. Other AI goals you'll need are `minecraft:behavior.trade_with_player`, optionally `minecraft.behavior:trade_interest` (allows the mob to hold/offer an item) and, potentially, `"minecraft:trade_resupply": {}`. + +For a simple trading UI, `trade_table` + `trade_with_player` components should do the trick. + +1. Add `"minecraft:behavior.trade_with_player": {}` to your entity's components. +2. Copy the following code into a component group of your entity. I'll call mine `"wiki:trader"`; + +BP/entities/trader.json + +```json +"minecraft:trade_table": { + "display_name": "Trading Entity", // Text to be displayed. + "table": "trading/trading_entity_trades.json", // Path to the trade table file + "new_screen": true //If set to false, the UI will display as the pre-Village&Pillage one. +} +``` + +3. Now make sure the component group is added to the entity via an event. It's a good idea to add it in `minecraft:entity_spawned` event, since it triggers on spawn. +If you don't feel confident with events and component groups, make sure you're familiar with entity definition rules/concepts. See the [Intro to Entities](/entities/entity-intro-bp). + +:::warning +If you add the component in components, it will cause all kinds of problems, including blank trading UIs for all entities in the world. Because of an issue with the trading AI goals, they must be added in component groups. +::: diff --git a/docs/wiki/meta/addon-performance.md b/docs/wiki/meta/addon-performance.md new file mode 100644 index 00000000..29d54cb4 --- /dev/null +++ b/docs/wiki/meta/addon-performance.md @@ -0,0 +1,218 @@ +--- +title: Addon Performance +mentions: + - SirLich + - Joelant05 + - MedicalJewel105 + - TheItsNameless + - SmokeyStack +--- + +::: warning +This page was compiled primarily using community feedback from multiple sources. As a result, some information may be generalized, subjective, or conflicting. Always use your own best judgment when optimizing your addons. This page is not a substitute for testing your addon on a wide range of devices. +::: + +Performance in addons is crucial, as the most technically fantastic addon is mainly useless if the majority of the player base cannot experience it. When developing addons, it should always be considered that many Bedrock players will be experiencing your addon on a significantly lower power device than you are developing on. This is especially true for mobile users. Therefore, addons should be developed with performance in mind and tested for performance on lower-end devices when possible. + +This guide is a non-exhaustive list of specific performance considerations separated by the various subsystems of Bedrock Edition. No single point should be taken as a hard and fast rule. Instead, these performance considerations should help you to recognize potential areas for improvement. + +## Biomes and Features + +### Biomes + +- The biome system is generally efficient +- Large values for heightmaps are usually handled gracefully +- The component `climate` creates large particle storms + +### Features + +- Biomes generally cause less lag than feature generation. +- Hundreds of iterations per chunk of a multi-block feature have been achieved at a low-performance cost. +- Thousands of iterations per chunk of multi-block features negatively impact gameplay. +- Hundreds of thousands of iterations per chunk of a single-block feature have been achieved at a low-performance cost. +- Thousands of instances of features *per chunk* comes at little cost. +- Tens of thousands of feature instances *per chunk* yields a noticeable impact on chunk loading. +- Hundreds of thousands of instances of features *per chunk* slows chunk loading to an unbearable crawl. + +## Blocks + +### Materials + +- The minimum needed material type with regards to rendering should always be utilized +> `alpha_blend` performance is worse than `alpha_test`, which is worse than `opaque` + +### Quantity and Type + +- Flowing liquids should be avoided and minimized + +### Updates + +- Block updates should be minimized + +## Commands + +### Quantity and Type + +- Minimize the number of commands run per tick +> `/effect` and `/gamemode` run every tick are avoidable and have a significant performance impact +- Large clones, fills and structure loads during runtime should be avoided +> Breaking these more extensive operations into multiple commands distributed over multiple ticks will avoid lag spikes, consider using structure loading animations + +### Selectors + +- Care should be taken to ensure a function is not executed on too many entities, and therefore too many times +- Executing a scoreboard command outweighs the cost of running an entity selector multiple times +- Using c=1 to ensure the selector stops when it finds one entity may improve performance +- When executing multiple commands with the same selector, use a function instead to avoid repeatedly resolving the same selector + +### Tags vs. Scoreboards + +- Scoreboards perform better at a large scale than tags + +## Entities + +- Entities generally have one of the most significant performance impacts by subsystem and thus should be minimized where possible + +### Components + +- Pathfinding on flying mobs has a significant performance cost +- Flying mobs in general encounter performance problems +> Faking flying mobs via animation should be considered if possible + +### Dummy Entities + +- Dummy entities generally have equal performance impact to proper entities, except when excluding heavy components like pathfinding + +### Geometry + +#### Bones + +- No performance impact has been observed regarding bone count + +#### Elements + +- Element count is not generally an issue, except in extreme cases when thousands of elements are reached + +### Materials + +- The minimum material required to achieve the desired effect should always be used +- When in doubt, refer to the material definition files to get an idea of the costs of various materials, taking the material inheritance system into account + +### Quantity + +- Loaded entities at any given time should be minimized +> Below 30 is optimal + +## Lighting + +### Map Considerations + +- Hollow areas will cause lag due to lighting calculations even if you don't see them +> Avoid this by filling in unused enclosed areas +- Keeping the map set to day or night will avoid lighting recalculation + +### Sources + +- Bedrock lighting is calculated dynamically, meaning different light sources have different performance costs +> Light blocks are the most performant because they lack particles, rendering, and particular state logic + +> Torches are a minor performance issue because they emit particles, render, and have particular state logic dependent on what block they connect to + +> Custom light blocks with minimal components are a reasonable compromise between performance and aesthetics + +#### Comparison Table + +| Light Source | Score | Redstone Updates | Animted Texture | Light Updates | Tick Updates | Particles | Renders | +| ---------------: | :---: | :--------------: | :-------------: | :-----------: | :----------: | :-------: | :-----: | +| Light Blocks | 1 | False | False | True | False | False | False | +| Lanterns | 4 | False | True | True | True | False | True | +| Custom Blocks | 2 | False | False | True | False | False | True | +| Mushrooms | 3 | False | False | True | True | False | True | +| Redstone Lamps | 3 | True | False | True | False | False | True | +| Glowstone | 3 | True | False | True | True | False | True | +| Sea Lanterns | 4 | False | True | True | True | False | True | +| Torches | 4 | False | False | True | True | True | True | +| Redstone Torches | 5 | True | False | True | True | True | True | + +## Molang + +### Recursion + +- Minimize use of recursion when possible +- Intense nested loop structures will cause performance issues +- Use break to escape loops when possible + +### Structs + +- Avoid making structs too deep, as there is a performance cost with each layer + +### Variables + +- Use temp variables when possible to minimize variables loaded in memory +- Consider how often variables are calculated based on script type + +## Textures + +### texture_list.json + +- Tons of textures badly affect game performance. Create a [`texture_list.json`](/concepts/textures-list) file. + +### Quantity + +- No more than 3000 textures should be used +> This is due to limits imposed by Render Dragon + +> Render Dragon has a 4096 texture quantity limit, and there are 800 vanilla textures as of 1.16 + +### Resolution + +- The maximum texture resolution is 16384x16384 +- The recommended maximum texture resolution is 4096x4096 to maintain compatibility with low-end devices +- Keep in mind that textures are atlased, and larger textures can mess with atlas generation on lower-end devices +- Only make textures as significant as needed to convey the detail needed at the needed distance + +## Trades + +Villager trades cause performance issues and even crashes on all devices at 60 trades or greater. Avoid tons of trades for one entity. +Your best bet to resolve this issue is to split your trades in half and move them to another villager or custom entity/npc, 30 trades is a good safe number from testing. +*probably JSON UI issues* + +## Sounds + +### Count + +- Total registered sounds are reported to have an impact on performance + +### Compression + +- Sound compression is exceptionally beneficial to pack size +- This is especially noticeable on older and low power devices, such as the Switch +- The FMod simple API utilized by Bedrock decompresses all sounds into WAV before loading into RAM, meaning no CPU performance improvement in this respect +> If audio is streamed, this does not occur + +### Streaming + +- As general guidance, sounds over 500kb in size or 1 minute in length should be streamed + +## Redstone + +### Chunk Boundaries + +- Crossing chunk boundaries with Redstone should be avoided + +### Command Blocks + +- When creating large command blockchains, stack vertically and in a single chunk +- Minimize command block use in favor of functions and behaviors where possible + +## Ticking Areas + +- Total chunks are of more significant concern than ticking areas +- Dynamic areas should be avoided unless necessary +- Best practice is to minimizing the ticking area to one chunk if possible +> All always-on Redstone should fit in this ticking chunk +- Unload ticking areas when they are no longer needed, testing via /testforblock + +## Files + +- Tons of files can badly affect game performance. Create a [`contents.json`](/concepts/contents) file. diff --git a/docs/wiki/meta/index.md b/docs/wiki/meta/index.md new file mode 100644 index 00000000..f2207e98 --- /dev/null +++ b/docs/wiki/meta/index.md @@ -0,0 +1,3 @@ +--- +title: Meta +--- diff --git a/docs/wiki/meta/jq.md b/docs/wiki/meta/jq.md new file mode 100644 index 00000000..a62e74b0 --- /dev/null +++ b/docs/wiki/meta/jq.md @@ -0,0 +1,154 @@ +--- +title: Creating addons with JQ +hidden: true +mentions: + - SirLich + - Joelant05 + - MedicalJewel105 +--- + +## Introduction + +> "jq is like sed for JSON data - you can use it to slice and filter and map and transform structured data with the same ease that sed, awk, grep and friends let you play with text." + +_— https://stedolan.github.io/jq/_ + +jq is a JSON editing program written in C. It can be thought of similarly to Perl. Because it was explicitly written to parse JSON, however, it has many valuable features that are not present in other text processors. jq defines its programs as filters, as they take an input, your JSON data, and produce an output, your modified JSON data. Though seemingly simple, jq contains many advanced features that can be extremely useful when procedurally generating addon files. + +I'll be explaining jq from the perspective that jq is a command-line interface. However, wrappers have been designed for jq in essentially every programming language, so you can easily incorporate jq filters into the programing language of your choice, including Go, JavaScript, Java, Ruby, Python, and R. Given that, I will primarily focus on filter design from the perspective of Minecraft addons, and I'll leave the implementation to your specific use case. I'll be including embeds from [jqterm.com](https://jqterm.com/?query=.), which uses a JavaScript implementation of jq to display filters in a web browser. + +## Getting jq + +The official source to download the jq binaries is https://stedolan.github.io/jq/download/. The executables downloaded here should be essentially portable and just "run". + +You may also use your system package manager, though if you take this approach, ensure that the version installed is the latest, jq-1.6. + +A community-maintained list of the wrappers available for jq in various languages is available [here](https://github.com/fiatjaf/awesome-jq). + +## Defining Syntax + +### The Dot + +The simplest possible filter in jq is the dot (`.`), which will take the input JSON and return it unchanged. jq uses the standardized path notation for JSON files. Consider the following structure of a resource pack manifest: + + + +### Paths + +Here, we see that our `.` filter returns what we expected: the entire JSON file. Now, let's say we wanted to return some specific part of the JSON file, the header UUID, for example. We would then construct a filter that contains the full path to that value. In this case, that would be `.header.uuid`. Let's see that in action: + + + +### Array Access + +We can access arrays in jq similarly to how we would in other languages. Let's say we wanted to return the last number in our minimum engine version array. We would construct the following filter: `.header.min_engine_version[-1]`. Note that, of course, we could also specify the positive position 2 if we always wanted to return to the second position. Simply using empty brackets, `.[]`, will return all array elements in a line separated list. Feel free to play around with this and learn the basics: + + + +### Editing Values + +Now let's get into the real meat of jq and start manipulating our JSON data. The way we do this is with the plain assignment operator (`=`). There are a few variants of this operator, referred to as update-assignment operators, such as `|=` and `+=`, which you can read more about in jq's official [manual](https://stedolan.github.io/jq/manual/#Assignment), and experiment within the example below: + + + +### The Pipe + +Similar to UNIX command-line interfaces, jq makes use of the pipe, `|`. When you use the pipe character, you are essentially telling jq to take the result of your filter on the left of the pipe and run it through the filter to the pipe's right. Let's go back to our array access example, except this time. We will output the entire array apply some filter to the output array. We'll use jq's built-in map function to demonstrate this, which is a handy function as it can be used to apply a specified filter to every value in an input array. We'll add 1 to each value in the minimum engine version array: + + + +### Logical Operations + +#### If, Then, Else + +Logical statements in jq are essentially written in a human-readable format. They take the form `if A then B else C end`. 'A' in this case could test for a specific value or test if some key exists. More conditions can be added with elif in the form `if A then B elif C then D else E end`. For comparisons, the operators are essentially the same as Molang, utilizing `==`, `!=`, `>`, `>=`, `<`, and `<=`. In the example below, we'll conditionally change the description of the pack based on the format version. If the format version is greater than 1, we'll set the description to "Big Format". Otherwise, we'll leave the description alone: + + + +#### And, Or, Not + +The operations `and` and `or` are also written in plain English. If we wanted to test for condition 'A' and condition 'B', we'd write `if (A and B) then C else D`. + +The operation `not` behaves like a single argument function, which we'll discuss in further depth below. When we pipe some boolean into `not`, it will return the opposite value. We'll demonstrate this by setting our header description to "Little Version" only if both our header version and module version are not greater than 1: + + + +### Variables + +Variables can be defined anywhere in filter. When a variable is defined, it is valid for use anywhere downstream in the pipe from where it was initially defined. They are defined in the form: `.input as $var | $var`, which would effectively return `.input`. Any valid JSON type can also serve as an input, such as objects, arrays, strings, and numbers. Take the simple example: + + + +## Builtin Functions + +### Syntax + +jq comes with a variety of built-in functions. We've already encountered the function `map` while explaining the pipe. One thing of note regarding jq functions is that their syntax differs depending on the number of arguments they take. Multi-argument functions will take their values enclosed in parentheses and separated by semicolons. In contrast, for single-argument functions, the input is piped in. Take the example below, in which we use the multi-argument function pow to raise the format version to the third power, while we also use the single argument function sqrt to find the square root of the format version. In this example, you'll also note that we introduce the concept of building an entirely new JSON structure within our jq filter. This is extremely useful in situations where we'd like to reshape some input files somehow. It's always important to keep in mind that any valid JSON is valid anywhere in a jq filter: + + + +### Math + +jq incorporates C-style math functions and generally carries over all built-in C math functions from your system. Refer to the [manual](https://stedolan.github.io/jq/manual/#Math) for a complete list of these. + +### Map and Map Values + +We've already seen a bit of what `map` can do, as seen in the pipe section. I'll explain a bit about its cousin, `map_values`. While `map` can apply some filter to all values in an array, `map_values` apply some filter to all keys in an input list of objects. In the example below, I'll introduce `map_values` and a couple of extra functions. Our goal will be to substitute the string "Example" with "Production" by iterating through all the values with the typed string under the header. We must separate the string values from the array values, as we cannot perform the function we will use to make this substitution, `gsub`, on arrays. The function `gsub` is a multi-argument function that will take the substring we would like to change, followed by the result we'd like to change that substring to. We'll also be utilizing the `select` function to separate our strings from our arrays. We'll incorporate a variable so we have easy access to all the information contained in the header. We'll use the function `type`, which lets us check the JSON data type of input. + + + +### To and From Entries + +The function `to_entries` is a useful single argument jq builtin that is helpful when we'd like to rearrange keys and values. Let's say we wanted to invert all the key/value pairs in the header. Using `to_entries`, we'll construct an array of all key-value pairs in the header, reformatted as objects, and assigned "key" or "value" to reference them later. To understand how this function works, it's important to see what this intermediate looks like. Note that this can also be reversed by appending `from_entries`: + + + +Now, we'll use `map` to iterate through each array entry, and finally, we'll introduce a new function, add. This single-argument function will take the array of objects output by `map` and essentially move them up one level to again exist as key-value pairs under the header. We'll also need to convert all our values to strings so they can serve as keys. We'll use the single-argument function `tostring`. Note that `tonumber` is the inverse of this: + + + +### Walk + +The function `walk` is compelling, as it will recursively apply to everything in the input at all levels. Take the example of deleting all objects with the value null. We'll also be introducing the function `with_entries`, which is just a shorthand for `to_entries | map(some filter) | from_entries`. We'll start our filter with `walk`, indicating we want to go through everything. We'll then use an if statement to ensure we are only editing objects. Else we'll leave the input unchanged. For all objects, we'll use `with_entries` to convert those to mapped keys and values and run a `select` function on those to ensure we only carry on values that are not equal to null: + + + +### Further Reading + +Jq has far too many functions to list off here. I've tried to explain those that I find most useful in my jq projects. For further reading, refer to the [jq manual](https://stedolan.github.io/jq/manual/). + +## Defining Custom Functions + +In jq, one can easily define custom functions with the syntax `def function_name($input1; $input2): some function;`. The variables can then be used all throughout the function. A function can also have no input. Take the boiler plate examples below: + + + +## Command Line Use + +When invoked from the command line, jq takes the form `jq '[filter]' input.json`. This will only display the output in the terminal. For bash-based systems, simply use the arrow operator, `jq '[filter]' input.json > output.json` to write an output file. If you wish to overwrite the input file on the fly, this method will not work. You will need to generate a temp file or use a utility like Sponge from [moreutils](https://rentes.github.io/unix/utilities/2015/07/27/moreutils-package/). Then, you may simply `jq '[filter]' input.json | sponge input.json`. For large filters, it's generally easier to employ a shell or bash script. You may use the -n flag to construct a JSON file from scratch rather than specify an input. Finally, you may pass terminal variables to be used in your jq filters as follows: + +``` +jq -n --arg jqvar1 $var1 --arg jqvar2 $var2 ' +{ +"var1": $jqvar1, +"var2": $jqvar2 +}' +``` + +## Bringing It All Together + +Many of the previous examples are abstract and contrived, designed to allow you to become familiar with the basics of jq. Now, I'd like to go over an example of a practical use case of jq. I'll be explaining the jq filter I wrote for converting a Java model to a Bedrock model for use as an attachable while remapping all its UV values. + +First, we'll define a simple variable to change the name of our model geometry easily. Next, we'll define a function to deal with our elements, `element_array`. We'll first get some information from the array of textures from our Java model to know how many textures we have, what order they're in, and therefore how to shift our UV values. Now that we've defined all our variables from our texture array, which we'll use later in UV calculations, we'll start to map our elements array. + +Iterating through each element in our array of elements, we'll calculate our origin and size. We can use simple math from jq to do this. To go from Java to Bedrock, we'll need to change 2 absolute corner positions to one origin value and one size value. We'll also shift our X and Z coordinates by 8 to account for the different centering of coordinate systems between Bedrock and Java. + +Now, we'll deal with rotation. The way Java defines its rotations uses a string followed by a value, but we'd like to construct an array based on that. We can do so with a reasonably simple if, then, else statement. Since rotation is optional, we'll just set that to null for now if we don't have a rotation. We can delete that later. Next, we'll set the element pivot, shifting by 8 on the X and Z due to the coordinate difference and setting to null if we lack a pivot. + +We will then calculate our UV values. I wish to shift all our UV's as if we are generating a single square texture atlas from our input textures. We'll define a nested function, `uv_calc`, here. We'll then use some modular division via the `fmod` function to figure out the offsets. Finally, we'll change Java's four coordinate style UV system to Bedrock's, which uses a point value and a size value, with simple arithmetic. We'll then run the function for each of the six faces of our element, and finally, use `walk` to remove any objects with the value null. + +To make our geometry compatible with custom blocks, we'll define the function `pivot_groups`, which we'll ultimately use to iterate over our element array, find all unique rotation pivot combinations, and create a bone for all elements that share a rotation-pivot variety. + +Lastly, we'll put down the structure of our actual geometry file. We'll concatenate in our model name, use our `element_array` function to bring in all our cubes with no rotation, and add in our special pivot groups. We'll use the map to give each group a unique name, iterating up one value each time. + +This filter is a little heavy, so I've linked it on a separate page rather than embedding it [here](https://jqterm.com/85a349e33fd8709ceb0c64be6b63c497?query=%22test%22%20as%20%24model_name%20%7C%0A%0Adef%20element_array%3A%0A%20%20%20%20%28.textures%20%7C%20to_entries%20%7C%20sort_by%28.key%29%20%7C%20map%28%7B%28.key%29%3A%20.value%7D%29%20%7C%20add%20%7C%20keys_unsorted%29%20as%20%24texture_array%0A%20%20%20%20%7C%20%28%24texture_array%20%7C%20length%29%20as%20%24frames%0A%20%20%20%20%7C%20%28%28%24frames%20%7C%20sqrt%29%20%7C%20ceil%29%20as%20%24sides%0A%20%20%20%20%7C%20%28.texture_size%5B1%5D%20%2F%2F%2016%29%20as%20%24t1%0A%20%20%20%20%7C%20.elements%20%7C%20map%28%7B%0A%20%20%20%20%20%20%22origin%22%3A%20%5B%28-.to%5B0%5D%20%2B%208%29%2C%20%28.from%5B1%5D%29%2C%20%28.from%5B2%5D%20-%208%29%5D%2C%0A%20%20%20%20%20%20%22size%22%3A%20%5B.to%5B0%5D%20-%20.from%5B0%5D%2C%20.to%5B1%5D%20-%20.from%5B1%5D%2C%20.to%5B2%5D%20-%20.from%5B2%5D%5D%2C%0A%20%20%20%20%20%20%22rotation%22%3A%20%0A%20%20%20%20%20%20%28if%20%28.rotation.axis%29%20%3D%3D%20%22x%22%20then%20%5B%28.rotation.angle%20%7C%20tonumber%20*%20-1%29%2C%200%2C%200%5D%20%0A%20%20%20%20%20%20%20%20elif%20%28.rotation.axis%29%20%3D%3D%20%22y%22%20then%20%5B0%2C%20%28.rotation.angle%20%7C%20tonumber%20*%20-1%29%2C%200%5D%20%0A%20%20%20%20%20%20%20%20elif%20%28.rotation.axis%29%20%3D%3D%20%22z%22%20then%20%5B0%2C%200%2C%20%28.rotation.angle%20%7C%20tonumber%29%5D%20%0A%20%20%20%20%20%20%20%20else%20null%20end%29%2C%0A%20%20%20%20%20%20%22pivot%22%3A%20%28if%20.rotation.origin%20then%20%5B%28-%20.rotation.origin%5B0%5D%20%2B%208%29%2C%20.rotation.origin%5B1%5D%2C%20%28.rotation.origin%5B2%5D%20-%208%29%5D%20else%20null%20end%29%2C%0A%20%20%20%20%20%20%22uv%22%3A%20%28%0A%20%20%20%20%20%20%20%20def%20uv_calc%28%24input%29%3A%0A%20%20%20%20%20%20%20%20%20%20%28if%20%28.faces%20%7C%20.%5B%24input%5D%29%20then%0A%20%20%20%20%20%20%20%20%20%20%28.faces%20%7C%20.%5B%24input%5D.texture%5B1%3A%5D%20as%20%24input_n%20%7C%20%24texture_array%20%7C%20%28index%28%24input_n%29%20%2F%2F%20index%28%22particle%22%29%29%29%20as%20%24pos_n%0A%20%20%20%20%20%20%20%20%20%20%7C%20%28%28.faces%20%7C%20.%5B%24input%5D.uv%5B0%5D%20%2F%20%24sides%29%20%2B%20%28%28fmod%28%24pos_n%3B%20%24sides%29%29%20*%20%2816%20%2F%20%24sides%29%29%29%20as%20%24fn0%0A%20%20%20%20%20%20%20%20%20%20%7C%20%28%28.faces%20%7C%20.%5B%24input%5D.uv%5B1%5D%20%2F%20%24sides%29%20%2B%20%28%28%28%24pos_n%20%2F%20%24sides%29%20%7C%20floor%29%20*%20%2816%20%2F%20%24sides%29%29%29%20as%20%24fn1%0A%20%20%20%20%20%20%20%20%20%20%7C%20%28%28.faces%20%7C%20.%5B%24input%5D.uv%5B2%5D%20%2F%20%24sides%29%20%2B%20%28%28fmod%28%24pos_n%3B%20%24sides%29%29%20*%20%2816%20%2F%20%24sides%29%29%29%20as%20%24fn2%0A%20%20%20%20%20%20%20%20%20%20%7C%20%28%28.faces%20%7C%20.%5B%24input%5D.uv%5B3%5D%20%2F%20%24sides%29%20%2B%20%28%28%28%24pos_n%20%2F%20%24sides%29%20%7C%20floor%29%20*%20%2816%20%2F%20%24sides%29%29%29%20as%20%24fn3%20%7C%0A%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22uv%22%3A%20%5B%28%24fn0%29%2C%20%28%24fn1%29%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22uv_size%22%3A%20%5B%28%24fn2%20-%20%24fn0%29%2C%20%28%24fn3%20-%20%24fn1%29%5D%0A%20%20%20%20%20%20%20%20%20%20%7D%20else%20null%20end%29%3B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22north%22%3A%20uv_calc%28%22north%22%29%2C%0A%20%20%20%20%20%20%20%20%22south%22%3A%20uv_calc%28%22south%22%29%2C%0A%20%20%20%20%20%20%20%20%22east%22%3A%20uv_calc%28%22east%22%29%2C%0A%20%20%20%20%20%20%20%20%22west%22%3A%20uv_calc%28%22west%22%29%2C%0A%20%20%20%20%20%20%20%20%22up%22%3A%20uv_calc%28%22up%22%29%2C%0A%20%20%20%20%20%20%20%20%22down%22%3A%20uv_calc%28%22down%22%29%0A%20%20%20%20%20%20%20%20%7D%29%0A%20%20%20%20%7D%29%20%7C%20walk%28%20if%20type%20%3D%3D%20%22object%22%20then%20with_entries%28select%28.value%20!%3D%20null%29%29%20else%20.%20end%29%3B%0A%0Adef%20pivot_groups%3A%0A%20%20%20%20%28element_array%29%20as%20%24element_array%20%7C%0A%20%20%20%20%5B%5B.elements%5B%5D.rotation%5D%20%7C%20unique%20%7C%20.%5B%5D%20%7C%20select%20%28.!%3Dnull%29%5D%0A%20%20%20%20%7C%20map%28%28%0A%20%20%20%20%5B%28-%20.origin%5B0%5D%20%2B%208%29%2C%20.origin%5B1%5D%2C%20%28.origin%5B2%5D%20-%208%29%5D%20as%20%24i_piv%20%7C%0A%20%20%20%20%28if%20%28.axis%29%20%3D%3D%20%22x%22%20then%20%5B%28.angle%20%7C%20tonumber%20*%20-1%29%2C%200%2C%200%5D%20%0A%20%20%20%20%20%20elif%20%28.axis%29%20%3D%3D%20%22y%22%20then%20%5B0%2C%20%28.angle%20%7C%20tonumber%20*%20-1%29%2C%200%5D%20%0A%20%20%20%20%20%20else%20%5B0%2C%200%2C%20%28.angle%20%7C%20tonumber%29%5D%20end%29%20as%20%24i_rot%20%7C%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%22parent%22%3A%20%22geysercmd_z%22%2C%0A%20%20%20%20%20%20%22pivot%22%3A%20%28%24i_piv%29%2C%0A%20%20%20%20%20%20%22rotation%22%3A%20%28%24i_rot%29%2C%0A%20%20%20%20%20%20%22mirror%22%3A%20true%2C%0A%20%20%20%20%20%20%22cubes%22%3A%20%5B%28%24element_array%20%7C%20.%5B%5D%20%7C%20select%28.rotation%20%3D%3D%20%24i_rot%20and%20.pivot%20%3D%3D%20%24i_piv%29%29%5D%0A%20%20%20%20%7D%29%29%3B%0A%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%22format_version%22%3A%20%221.16.0%22%2C%0A%20%20%20%20%20%20%22minecraft%3Ageometry%22%3A%20%5B%7B%0A%20%20%20%20%20%20%20%20%22description%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%22identifier%22%3A%20%28%22geometry.geysercmd.%22%20%2B%20%28%24model_name%29%29%2C%0A%20%20%20%20%20%20%20%20%20%20%22texture_width%22%3A%2016%2C%0A%20%20%20%20%20%20%20%20%20%20%22texture_height%22%3A%2016%2C%0A%20%20%20%20%20%20%20%20%20%20%22visible_bounds_width%22%3A%204%2C%0A%20%20%20%20%20%20%20%20%20%20%22visible_bounds_height%22%3A%204.5%2C%0A%20%20%20%20%20%20%20%20%20%20%22visible_bounds_offset%22%3A%20%5B0%2C%200.75%2C%200%5D%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%22bones%22%3A%20%28%5B%7B%0A%20%20%20%20%20%20%20%20%20%20%22name%22%3A%20%22geysercmd%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22binding%22%3A%20%22c.item_slot%20%3D%3D%20%27head%27%20%3F%20%27head%27%20%3A%20q.item_slot_to_bone_name%28c.item_slot%29%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22pivot%22%3A%20%5B0%2C%208%2C%200%5D%0A%20%20%20%20%20%20%20%20%7D%2C%20%7B%0A%20%20%20%20%20%20%20%20%20%20%22name%22%3A%20%22geysercmd_x%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22parent%22%3A%20%22geysercmd%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22pivot%22%3A%20%5B0%2C%208%2C%200%5D%0A%20%20%20%20%20%20%20%20%7D%2C%20%7B%0A%20%20%20%20%20%20%20%20%20%20%22name%22%3A%20%22geysercmd_y%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22parent%22%3A%20%22geysercmd_x%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22pivot%22%3A%20%5B0%2C%208%2C%200%5D%0A%20%20%20%20%20%20%20%20%7D%2C%20%7B%0A%20%20%20%20%20%20%20%20%20%20%22name%22%3A%20%22geysercmd_z%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22parent%22%3A%20%22geysercmd_y%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22pivot%22%3A%20%5B0%2C%208%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%22cubes%22%3A%20%5B%28element_array%20%7C%20.%5B%5D%20%7C%20select%28.rotation%20%3D%3D%20null%29%29%5D%0A%20%20%20%20%20%20%20%20%7D%5D%20%2B%20%28pivot_groups%20%7C%20map%28del%28.cubes%5B%5D.rotation%29%29%20%7C%20to_entries%20%7C%20map%28%20%28.value.name%20%3D%20%22rot_%5C%281%2B.key%29%22%20%29%20%7C%20.value%29%29%29%0A%20%20%20%20%20%20%7D%5D%0A%20%20%20%20%7D). diff --git a/docs/wiki/meta/style-guide.md b/docs/wiki/meta/style-guide.md new file mode 100644 index 00000000..071b3452 --- /dev/null +++ b/docs/wiki/meta/style-guide.md @@ -0,0 +1,167 @@ +--- +title: Style Guide +mentions: + - SirLich + - solvedDev + - MedicalJewel105 + - ChibiMango +--- + +This document will present the officially supported Bedrock-Wiki style guide for addon-creation. This guide aims to promote best practices while creating addons and create a consistent format for everyone to follow. + +:::tip +The style guide is a living, breathing document, which will evolve as addon-creation evolves. Please get in touch if you think something needs to be updated or changed! +::: + +## Folder Structure + +- No spaces in your file paths. `use_underscores`. +- No `CAPITALS` in your identifiers, file names, or folder names. +- The total character length of any path must not exceed 80 characters (console limitation). +- Content folders should use consistent pluralization: Don't mix and match. + +## Identifiers + +Do not use identifiers that begin with a number, and especially don't use an identifier that is _only_ a number. This applies to entities, component_groups, events, and anything else that takes a `namespace:name` pair. + +## File and Folder names + +| Concept | Example Identifier | +| -------------------- | -------------------------- | +| Behavior Pack | dragons_BP | +| Resource Pack | dragons_RP | +| Geometry | dragon.geo.json | +| Animation | dragon.animation.json | +| Animation Controller | dragon.ac.json | +| RP Entity | dragon.ce.json | +| BP Entity | dragon.se.json | +| Item 1.16.100+ | dragon_tooth.item.json | +| BP Item | dragon_tooth.item.bp.json | +| RP Item | dragon_tooth.item.rp.json | +| Render Controller | dragon.rc.json | +| Loot Table | dragon.loot.json | +| Recipe | dragon_saddle.recipe.json | +| Spawn Rules | dragon.spawn.json | +| Trade Table | dragon.trade.json | +| Particles | dragon_magic.particle.json | +| Texture | dragon.png | +| Gametest | dragonTest.js | + +## Namespaces + +A suitable namespace should be unique to you or your team. Something like `mob` or `cars` or `content` or `custom` would be a **bad** namespace since another developer might come up with the same namespace as you. + +`minecraft` and `minecon` are reserved. Don't use these. + +For personal projects, use a convenient version of your player name, and for team projects, use a suitable version of your team name. + +When multiple developers work on a project together, the namespace should always be shared. If credit is required, use sub-indexing: `minetite.sirlich:dragon` + +Where to use name-spaces: + +- entities +- particles +- component-groups +- events + +When not to use namespaces: + +- do not include your namespace in any folder path or file-name + +## Sub-indexing + +Sub indexing is the use of `.` to separate chained concepts. Sub-indexing should go in descending order from big to small: + +✔️ `animation.controller.dragon.flying.taking_off` + +❌ `animation.controller.dragon_take_off_flying` + +When using sub-indexing, use `_` as space, not another `.`. + +✔️ `animation.controller.dragon.flying.taking_off` + +❌ `animation.controller.dragon.flying.taking.off` + +You can use sub-indexing in your entities: +`sirlich:dragon.drake` + +## Groups and Events should complement each other + +| Group | Event | +| ------------ | ---------------------- | +| sirlich:wild | ✔️ sirlich:become_wild | +| sirlich:wild | ❌ sirlich:wild | +| sirlich:tame | ✔️ sirlich:on_tame | +| sirlich:tame | ❌ sirlich:tame | + +## Short-Names should be Generic + +Short-names are file-specific identifiers, which are used to map between an identifier and a pretty name. They are handy because they allow us to re-use animation controllers and render controllers. For this reason, your short-names should be generic. + +✔️ `"sit": "animation.dragon.sit"` + +❌ `"dragon_sitting": "animation.dragon.sit"` + +When we make short-names of this form, we can use a generic "sit" animation controller for all of them since we can use the `sit` short-name to play the sit animation. + +## Functions should be nested + +You can put functions in folders to achieve this. + +✔️ `function teleport/zone/hell` + +❌ `function teleport_hellzone` + +## Group animations files when possible + +Example: + + + +```json +{ + "format_version": "1.8.0", + "animations": { + "animation.dragon.sit": {...}, + "animation.dragon.fly": {...}, + "animation.dragon.roar": {...}, + } +} +``` + +## Split textures by path, not name + +✔️ `textures/dragon/red` + +❌ `textures/dragon_red_skin` + +✔️ `textures/npc/dragon_hunter/archer` + +❌ `textures npc/dragon_hunter_archer` + +## .lang File Comments + +Comments intended for the localizer should always be in-line, in the following format: + +`the.key=The string<\t>## Comment, intended for the one localizing.` + +`<\t>` represents a tab-character. + +Own-line comments can be used for organizational purposes but should not store localization-critical information. + +## Acronyms when discussing + +| Acronym | Concept | +| ------- | ---------------------------------- | +| BP | Behavior Pack | +| RP | Resource pack | +| VRP | Vanilla Resource Pack | +| VBP | Vanilla Behavior Pack | +| AC | Animation Controller | +| RPAC | Resource Pack Animation Controller | +| BPAC | Behavior Pack Animation Controller | +| BB | Blockbench | +| BDS | Bedrock Dedicated Server | +| FPV | First Person View | +| RD | Render Dragon | +| VSCode | Visual Studio Code | diff --git a/docs/wiki/meta/useful-links.md b/docs/wiki/meta/useful-links.md new file mode 100644 index 00000000..107250b5 --- /dev/null +++ b/docs/wiki/meta/useful-links.md @@ -0,0 +1,157 @@ +--- +title: Useful Links +mentions: + - SirLich + - MedicalJewel105 + - MetalManiacMc + - rebrainertv + - jasonjgardner + - MADLAD3718 + - cda94581 + - Luthorius + - NhanAZ + - AndreasHGK + - mark-wiemer + - Noruaric + - JaylyDev + - zheaEvyline +--- + +There is loads of helpful information about Bedrock Development online, but sometimes it is hard to find! We will do our best to keep this list up to date as we continue to find useful content. + +Important links have a ⭐. + +## Discord Links + +- ⭐ [Bedrock Add-Ons](https://discord.gg/46JUdQb) +- ⭐ [Bedrock OSS](https://discord.gg/XjV87YN) +- ⭐ [Minecraft](https://discord.gg/minecraft) +- ⭐ [Blockbench](http://discord.gg/fZQbxbg) +- ⭐ [bridge.](https://discord.gg/NxKuWuA) +- ⭐ [Minecraft Commands](https://discord.gg/QAFXFtZ) +- [Snowstorm](https://discord.gg/W9d78Z8AvM) +- [Amulet & MCEdit](https://discord.gg/dSnwqQf) +- [Amethyst](https://discord.gg/Cxrj9UXnDB) +- [Artists Refuge](https://discord.gg/aVXbPCdRr3) +- [BDSX](https://discord.gg/8UhbaDwFMh) +- [Bedrock Commands](https://discord.gg/vV29d6rJcj) +- [Dragonfly Server Software](https://discord.gg/U4kFWHhTNR) +- [MCBE Realm Hub](https://discord.gg/pCkYPvSGC8) +- [MCBE Utilities](https://discord.gg/9S4aKh684W) +- [MCPECore](https://discord.com/invite/N3e6exUQGs) +- [Minecraft Education](https://discord.gg/7fSQBdx) +- [Minecraft RTX](http://discord.gg/vNWc3Hh) +- [Mojang Bug Tracker](https://discord.gg/rpCyfKV) + +## Software (installed) + +- ⭐ [Blockbench: A boxy 3D model editor](https://blockbench.net/) +- ⭐ [bridge. Addon Editor](https://bridge-core.github.io/) +- ⭐ [VSCode Editor](https://code.visualstudio.com/) +- ⭐ [Regolith](https://github.com/Bedrock-OSS/regolith) +- [CoreCoder [Code Editor]](https://hanprog.itch.io/core-coder) +- [Feature Rule Generator v2 (paid version)](https://machine-builder.itch.io/frg-v2) +- [Feature Rule Generator v2 (free version)](https://drive.google.com/file/d/1rwQTtzgpWiqCS9ecO_j-qcxjdQvWSXgi/view) +- [Add-on JSON Generator (paid)](https://kaifireborn.itch.io/add-on-json-generator) +- [NBT Editor](https://www.universalminecrafteditor.com/) +- [World Converter (paid)](https://www.universalminecraftconverter.com/download) +- [Chunker (World Converter)](https://chunker.app/) +- [NBT Studio](https://github.com/tryashtar/nbt-studio) +- [BedrockLauncher (Bedrock version switcher)](https://bedrocklauncher.github.io/) +- [ResourcePack Converter [App]](https://converter.bedrockhub.io) +- [BedrockConnect [App]](https://bedrockconnect.bedrockhub.io) + +## Bedrock Tools Websites + +- ⭐ [Snowstorm Particle Generator](https://jannisx11.github.io/snowstorm/) +- ⭐ [Loot Table Generator](https://bedrock-oss.github.io/bedrock-loot-gen/) +- [Apply Loot Tables to Structures](https://mcbe-essentials.github.io/structure-editor/loot-tabler) +- [Structure Editor](https://mcbe-essentials.github.io/structure-editor/) +- [Convert MCSTRUCTURE to MCFUNCTION](https://mcbe-essentials.github.io/structure-to-function/) +- [Crafting Recipe Generator](https://crafting.thedestruc7i0n.ca/) +- [Trade Table Generator](https://mcbe-essentials.github.io/trade-table-editor/) +- [World Packager](https://mcbe-essentials.github.io/world-packager/) +- [Manifest Generator](https://bedrock-manifest.web.app/) +- [Foxynotail Tools](https://www.foxynotail.com/tools/) +- [.lang File Generator](https://solveddev.github.io/AnyLanguage/) +- [behavior-builder (beta)](https://stirante.com/behavior/index) +- [controller-builder (beta)](https://stirante.com/controller/index) +- [MCPACK Generator](https://mcbe-essentials.github.io/instant-pack/) +- [Molang Grapher](https://jannisx11.github.io/molang-grapher/) +- [Molang Playground](https://bridge-core.github.io/molang-playground/) +- [Dialogue Generator](https://mcbe-essentials.github.io/dialogue-editor/) +- [Selector Generator](https://mcbe-essentials.github.io/selector-generator/) +- [Addon Obfuscator](https://tools.pixelpoly.co/obfuscator) + +## Documentation + +- ⭐ [bedrock.dev](https://bedrock.dev/) +- ⭐ [Minecraft Creator Portal](https://docs.microsoft.com/en-us/minecraft/creator/) +- ⭐ [Minecraft Community Wiki](https://minecraft.wiki) +- [Mcbehub](https://mcbehub.com/category/realmdocs) +- [Bedrock Texture Pack Template](https://github.com/Brennian/BedrockTexturesTemplate) +- [Documentation Graveyard (removed components)](https://gist.github.com/destruc7i0n/ea1a6a7f97f0986d9326c58246f96fa3) + +### Getting Started With Your First Add-On + +- [Getting Started with Add-On Development for Bedrock Edition](https://learn.microsoft.com/en-us/minecraft/creator/documents/gettingstarted): These guides show you exactly how to build your first resource pack and your first behavior pack from start to finish. +- [Molang: a Beginner's Guide](https://learn.microsoft.com/en-us/minecraft/creator/documents/molangbeginnersguide): Molang is a Minecraft programming language that can be useful for writing some advanced add-ons. +- [Introduction to the GameTest Framework](https://learn.microsoft.com/en-us/minecraft/creator/documents/gametestgettingstarted): This is the best way to test games, and it uses JavaScript, the most popular programming language in the world! +- [Build a gameplay experience with TypeScript](https://learn.microsoft.com/en-us/minecraft/creator/documents/scriptinggettingstarted): TypeScript is Microsoft's copy of JavaScript. Writing add-ons in TypeScript allows you to add any functionality you can imagine! +- [@minecraft/server Module](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/mojang-minecraft/mojang-minecraft): This module and the others near it are how we can access Minecraft values with our TypeScript code. It's technical, but a great resource. +- [List and summary of commands (Unofficial Minecraft wiki)](https://minecraft.wiki/w/Commands#List_and_summary_of_commands): Most add-ons will run some commands. This community-supported wiki is the best resource for learning each and every command. + +## Sample Behavior & Resource Packs + +These packs are maintained and published by Mojang. + +- ⭐ [Vanilla Resource Pack](https://aka.ms/resourcepacktemplate) +- ⭐ [Vanilla Behavior Pack](https://aka.ms/behaviorpacktemplate) +- [Vanilla Resource Pack (BETA)](https://aka.ms/MinecraftBetaResources) +- [Vanilla Behavior Pack (BETA)](https://aka.ms/MinecraftBetaBehaviors) +- [Pack Archive (old versions)](https://bedrock.dev/packs) + +These packs are published by the open-source community + +- [wiki-addon](https://github.com/Bedrock-OSS/wiki-addon) +- [Enchantment Details](https://github.com/supercam19/EnchantmentDetails) +- [BC developer-packs](https://github.com/BedrockCommands/developer-packs) + +## Scripting Resources + +- [GameTests API Wrapper](https://github.com/notbeer/Framework-Wrapper) +- [GameTests Plugin-API-Starter-Pack](https://github.com/MajestikButter/Plugin-API-Starter-Pack) +- [Useful for Block Tags](https://mcpedl.com/debug-stick/) + +## Raytracing Resources +- ⭐ [Ray Tracing and PBR Texturing guide](https://docs.microsoft.com/en-us/minecraft/creator/documents/rtxgettingstarted) +- ⭐ [Minecraft with Ray Tracing and Advanced Graphics FAQ](https://help.minecraft.net/hc/en-us/articles/4408865164173-Minecraft-with-Ray-Tracing-and-Advanced-Graphics-FAQ) +- [r/minecraftRTX Getting Started Guide](https://www.reddit.com/r/minecraftRTX/comments/iq3lkl/getting_startedhelpful_guidesresource_packs/) +- [RenderBender](https://github.com/SpeedyCodes/RenderBender) +- [RTX Presets](https://discord.com/channels/691547840463241267/919021996271108108) +- [`.texture_set.json` Adobe Substance 3D Painter plugin](https://github.com/jasonjgardner/painter-plugin-texture-set-json) + +## Addon Marketplaces & Links + +- ⭐ [Minecraft Marketplace](https://www.minecraft.net/en-us/catalog) +- ⭐ [MCPEDL](http://mcpedl.com/?cookie_check=1) +- ⭐ [Bucket of Crabs (Marketplace joblist)](https://www.bucketofcrabs.net/) +- [MCDLHub](https://mcdlhub.com/) +- [CubitosMC](https://www.cubitosmc.com/) +- [Modbay](https://modbay.org/) +- [Minecraft Marketplace Stats](https://mcmarketstats.miste.fr/globalStats/) +- [Minecraft Marketplace Partners](https://www.playthismap.com/partners) + +## Other useful Links + +- [UUID v4 Generator (online)](https://www.uuidgenerator.net/version4) +- [Minecraft Marketplace partner Twitter list](https://twitter.com/i/lists/1191945551853629442?s=09) +- [Minecraft.net Official Add-ons page](https://www.minecraft.net/en-us/addons) +- [Run Bedrock on Linux](https://github.com/Element-0/ElementZero) +- [Linux Packaging Scripts](https://github.com/ChristopherHX/linux-packaging-scripts) +- [Block Models](https://blockmodels.com/) +- [Bedrock Addons Reddit](https://www.reddit.com/r/BedrockAddons/) +- [Windows 10 Non-renderdragon install](https://support.playhive.com/windows-10-installing-non-renderdragon-clients/) +- [Bedrock Edition Realm Protocol](https://github.com/NobUwU/BeRP) +- [Java & Bedrock Client](https://github.com/kennyvv/Alex) +- [Skin Pack Generator](https://github.com/MedicalJewel105/bedrock-skin-pack-generator) diff --git a/docs/wiki/meta/using-schemas.md b/docs/wiki/meta/using-schemas.md new file mode 100644 index 00000000..ff8f4da4 --- /dev/null +++ b/docs/wiki/meta/using-schemas.md @@ -0,0 +1,63 @@ +--- +title: Using Schemas +mentions: + - SirLich + - MedicalJewel105 + - 7dev7urandom + - KalmeMarq +--- + +A JSON schema gives you two things: validation to be sure that your JSON has the correct structure and (depending on editor support) IntelliSense to help you write your JSON correctly, to begin with. Schemas are nice because they give you instant feedback when you screw something up, but they can't catch everything. + +JSON schemas are just JSON files themselves and don't do anything on their own. You can write your own or use somebody else's. There's a handful of schemas for Bedrock out there already. Since none of the schemas are "official" (that I know of), and since Bedrock is a moving target, there will probably be some inaccuracies in any schema that you find. So keep that in mind: sometimes the issue will be in your code, sometimes the schema may be wrong. If you find a wrong schema, consider improving it and giving the author a pull request to our collective benefit. + +To get the validation working, you'll need a validator. You have many options here, including editor-specific options. + +## Schemas + +Many schemas exist, with many minor differences. Try out different schemas and see which one works best for you: + +| Author | Supports | Note | +| ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | +| [Assassin](https://github.com/aexer0e/bedrock-schema) | Behavior pack entity file | The original Schema this article was written for | +| [Tschrock's](https://github.com/bedrock-studio/bedrock-json-schemas/) | Manifest, Actor Animation Controller, Actor Animations, Actor Resource Definition, Render Controller, Geometry | | +| [stirante](https://github.com/stirante/bedrock-shader-schema/) | Shaders | | +| [KalmeMarq](https://github.com/KalmeMarq/Bugrock-JSON-UI-Schemas/) | JSON UI files (including _ui_defs.json and _global_variables.json) | | + +## VSCode + +To use this schema inside your JSON file in VSCode, simply add this line to your root object: + +`"$schema": "https://aexer0e.github.io/bedrock-schema/"` + +It should look like something like this: + + + +```json +"format_version": "1.14.0", +"$schema": "https://aexer0e.github.io/bedrock-schema/" +``` + +### Adding Schema to Workspaces + +If you want to utilize this schema to work with all of your files inside your Workspace, you can add it to your VS Code Workspace's settings. + +To do this, make sure you're in your Workspace, then press `Ctrl+Shift+P` and type and select `>Preferences: Open Workspace Settings (JSON)`. After that, add this to the root object + + + +```json +"settings": { + "json.schemas": [ + { + "fileMatch": [ + "*.json" + ], + "url": "https://aexer0e.github.io/bedrock-schema/" + } + ] +} +``` + +To test if it works, create a `.json` file, open an object, and see if you get the auto-completion options. (You can also press `Ctrl+Space` to force it into showing the available options.) diff --git a/docs/wiki/meta/version-control.md b/docs/wiki/meta/version-control.md new file mode 100644 index 00000000..30c5a02e --- /dev/null +++ b/docs/wiki/meta/version-control.md @@ -0,0 +1,89 @@ +--- +title: Version Control +mentions: + - SirLich + - sermah +--- + +Version control is the concept of backing up your code iteratively, so you can roll back to specific versions as needed. Version control could be achieved at the most basic level by taking a `.zip` of your addon every day and uploading it to google drive. This isn't unreasonable, but it has three significant difficulties that proper VCS (version control systems) fix: + +- It isn't easy to compare versions +- It isn't easy to _actually_ roll-back to a previous version +- It doesn't do anything to help in team-collaboration + +This tutorial will teach the basics of a tool called `git`, and a free, online git storage service called `GitHub. Anyone may follow along, but you will receive the most benefit if you are working in a team environment or often lose your work because you forget to back up. + +This tutorial will not be focusing directly on teaching `git` or `GitHub`, as outside knowledge sources better do this. The focus will be on setting up these tools for Minecraft once the basics have been learned. + +## Git + +`git` is a tool installed locally on your machine and allows you to version your files. You can `commit` changes to your files with a small message (ex. "Fixed issue where dragons couldn't fly after being tamed"), view the full change-list, and quickly jump back to specific changes. + +Git is insanely powerful and the de-facto tool for all major programming projects. The most significant drawback for MC work is that it is _complicated_. Be patient while learning. + +For a complete walkthrough of `git`, you should follow the following [git tutorial.](https://www.atlassian.com/git/tutorials/what-is-git) + +## GitHub + +GitHub is a version of your git project (`repository`) that is hosted online. This allows multiple people to work on the same project at the same time and collaborate. This is very helpful for map-making. By hosting on Github, you can also (optionally) make your code public, making it easier than ever to share your addons with the world. + +For a complete walkthrough of using `Github`, you should follow this [github tutorial](https://guides.github.com/activities/hello-world/). + +## Vocabulary Quiz + +If you've gotten this far, hopefully, you have a GitHub account and are familiar with `git` in a small way. The following terms will be used in this tutorial. If you don't know them, please google :) + +- repository +- branch +- commit +- github +- git + +# Setting up Git + +This assumes you are adding an _existing_ project to git. The steps are similar if you are starting from scratch. + +## Structure + +The big issue with using `git` for addons is that `git` generally works by encapsulating a _single_ folder and managing it. Of course, in Bedrock Addons, assets are spread across two folders: The `BP`, and `RP`. To get around this issue, we will place our repository outside of the `com.mojang` folder entirely and then use window `junctions` to "copy" the folders in. + +There are many advantages of placing our project in a separate location: + +- We can include additional files as needed, such as config files, tools, notes, .bb files, etc +- We can combine the RP and the BP into one repository +- All of our projects can be easily viewed in a simple location, instead of nested deep within com.mojang + +## Creating a Git Repository + +Pick a convenient location for your projects. I placed mine at `C:/sirlich/projects`. Make a new folder with the name of your map. We will be using `wiki` as the name of our mock project. + +Right-click the folder, and click `"Open git Bash"`. If this option doesn't appear, you can open `git bash` from the start menu and navigate your project folder. If you don't have `git bash` installed, you should do so now. + +Type: `git init`. This will create a blank repository in your project. + +## Linking your existing RP and BP + +The next step is to make the repository aware of your RP and BP folders. We will be using window symlink "junctions". When we create a junction, we essentially create a wormhole in our file system that will make it appear like your files are in two places at once. Deleting/editing/adding files is perfectly copied over. + +Type: `mklink /J wiki_RP "C:/path/to/RP/in/com/mojang"` +Type: `mklink /J wiki_BP "C:/path/to/BP/in/com/mojang"` + +When you are finished, you should see `wiki_RP` and `wiki_BP` in your project folder, containing all your assets, existing files, etc. + +You can now push this repository to `github`, following the tutorial above. + +## Extra Files + +Because we created our repository based on symlinks, we can add anything we like into the project folder without worrying about breaking the com.mojang folder. I like to track `.bb` files, cover-art files (`.kra` etc.). + +You can also add notes, video files, or anything else you want to track. + +## Working with your VCS + +The main things to remember about working with VCS: + +- Always `pull` before starting work +- Commit and `push` often +- Always `push` before stopping work +- If you screw up your files super bad, you can always reset to the last working version. If you commit/push often, hopefully, this wasn't too long ago. +- Always, and I mean `always` make good commit messages. It's vital when you have to roll back. diff --git a/docs/wiki/nbt/experimental-education-edition.md b/docs/wiki/nbt/experimental-education-edition.md new file mode 100644 index 00000000..3046d0c5 --- /dev/null +++ b/docs/wiki/nbt/experimental-education-edition.md @@ -0,0 +1,52 @@ +--- +title: Experiments in Education Edition +category: Tutorials +mentions: + - Fabrimat + - TheItsNameless +tags: + - easy + - Last updated for Version 1.18.32 (MEE) +--- + +[structure]: /assets/images/nbt/structure.png +[int]: /assets/images/nbt/int.png +[list]: /assets/images/nbt/list.png +[compound]: /assets/images/nbt/compound.png +[string]: /assets/images/nbt/string.png +[byte]: /assets/images/nbt/byte.png + +Education Edition is a variant of Bedrock Edition with some different features and limitations. +For security reasons it doesn't allow you to enable Experimental Features from the game. + +## Editing NBT + +::: warning +Always make a backup of your data before editing NBT files! + +Experimental features may not be compatible with every device and can cause your world to behave in unexpected way. +::: + +1. Extract the level.dat from your .mcworld, .mctemplate or com.mojang world folder. +2. Open the file with NBT editor (NBT Studio for example). +3. Select on the first node which is ![][structure] level.dat +4. Create a new compound tag called ![][compound] experiments +5. Select the new node and create a new ![][byte] byte with the name of the feature you need with a value of 1, which on 1.18.32 are: + - data_driven_biomes + - data_driven_items + - experimental_molang_features + - gametest + - spectator_mode + - upcoming_creator_features + - vanilla_experiments + - wild_update + +![](/assets/images/nbt/experiments-education-edition/byte-add.png) + +![](/assets/images/nbt/experiments-education-edition/experiments-file.png) + +Finally, save the file and put it back in the world package or directory. + +## Tips +Education Edition is usually one or two versions behind the classic Bedrock Edition, so you'll always know in advance which experimental features will be added to the stable gameplay and which will be modified or removed. +Try to add only features that will persist over time if you want to use that world in your classroom. diff --git a/docs/wiki/nbt/index.md b/docs/wiki/nbt/index.md new file mode 100644 index 00000000..6bba6e27 --- /dev/null +++ b/docs/wiki/nbt/index.md @@ -0,0 +1,10 @@ +--- +title: NBT +categories: + - title: General + color: blue + - title: Tutorials + color: green + - title: NBT in Depth + color: red +--- \ No newline at end of file diff --git a/docs/wiki/nbt/mcstructure.md b/docs/wiki/nbt/mcstructure.md new file mode 100644 index 00000000..02b7c835 --- /dev/null +++ b/docs/wiki/nbt/mcstructure.md @@ -0,0 +1,127 @@ +--- +title: .mcstructure +category: General +mentions: + - SirLich + - MedicalJewel105 + - Misledwater79 + - SmokeyStack +--- + +[int]: /assets/images/nbt/int.png +[list]: /assets/images/nbt/list.png +[compound]: /assets/images/nbt/compound.png +[string]: /assets/images/nbt/string.png + +### Saving and Loading + +The **Export** button creates `.mcstructure` files in a structure block. The files must be placed in a behavior pack to load them in-game with a load structure block. The path determines the structure identifier, which is typed into the structure block to load the structure. + +**Examples:** +`BP/structures/house.mcstructure` → `mystructure:house` +`BP/structures/dungeon/entrance.mcstructure` → `dungeon:entrance` +`BP/structures/stuff/towers/diamond.mcstructure` → `stuff:towers/diamond` + +The first subfolder defines the namespace, and subsequent folders define the path, ending with the structure file's name. + +Note that any files directly in the `structures` folder are given the `mystructure` namespace. If a structure exists in the `structures` folder and shares a name with a structure in an explicit `mystructure` folder, the game produces the following content log warning: + +``` +[structure][warning]-There was a conflict loading a structure in the default namespace. A structure with the name was found both in the root directory and the mystructure directory. +``` + +In this case, the file in the `mystructure` folder is the one that "wins," resulting in the file directly in the `structures` folder being ignored. + +### File Format + +`mcstructure` files are uncompressed [NBT files](https://wiki.vg/NBT#Specification). Like all Bedrock Edition NBT files, they are stored in little-endian format. The tag structure is as follows: + +> ![Integer][int] `format_version`: Currently always set to `1`. +> +> ![List][list] `size`: List of three integers describing the size of the structure's bounds. +> +> > ![Integer][int] Size of the structure in the X direction. +> > +> > ![Integer][int] Size of the structure in the Y direction. +> > +> > ![Integer][int] Size of the structure in the Z direction. +> +> ![Compound][compound] `structure`: Actual data compound. +> +> > ![List][list] `block_indices`: List containing two sublists, one for each layer. These contain the blocks in the structure. Each block is stored as an integer index into the palette (see below). Proceeds in ZYX order from the lowest corner to the highest one. For example, if the structure size is `[2,3,4]`, then the 24 (product of the dimensions) values in each layer list represent the blocks located at `[(0,0,0), (0,0,1), (0,0,2), (0,0,3), (0,1,0), (0,1,1), (0,1,2), (0,1,3), (0,2,0), (0,2,1), (0,2,2), (0,2,3), (1,0,0), (1,0,1), (1,0,2), (1,0,3), (1,1,0), (1,1,1), (1,1,2), (1,1,3), (1,2,0), (1,2,1), (1,2,2), (1,2,3)]` relative to the origin. Index values equal to `-1` indicate no block, causing any existing block to remain upon loading. This occurs when structure voids are saved, and is the case for most blocks in the second layer. Both layers share the same palette. +> > +> > > ![List][list] of ![Integer][int] Indices for blocks in the primary layer. +> > > +> > > ![List][list] of ![Integer][int] Indices for blocks in the secondary layer. This layer is usually empty, except for water when the block here is waterlogged. +> > +> > ![List][list] of ![Compound][compound] `entities`: List of entities as NBT, stored exactly the same as entities in the world file itself. Tags like `Pos` and `UniqueID` are saved, but replaced upon loading. +> > +> > ![Compound][compound] `palette`: Contains multiple named palettes, presumably to support multiple variants of the same structure. However, currently, only `default` is saved and loaded. +> > +> > > ![Compound][compound] A single palette (currently only named `default`). +> > > +> > > > ![List][list] `block_palette`: List of block states. This list contains the ordered entries that the block indices are referring to. +> > > > +> > > > > ![Compound][compound] A single block state. +> > > > > +> > > > > > ![String][string] `name`: The block's identifier, such as `minecraft:planks`. +> > > > > > ![Compound][compound] `states`: The block's states as keys and values. Examples: `wood_type:"acacia"`, `bite_counter:3`, `open_bit:1b`. The values are the appropriate NBT type for the state: strings for enum values, integers for scalar numbers, and bytes for boolean values. +> > > > > > ![Integer][int] `version`: Compatibility versioning number for this block (currently `17959425` as of writing, in 1.19). +> > > > +> > > > ![Compound][compound] `block_position_data`: Contains additional data for individual blocks in the structure. Each key is an integer index into the flattened list of blocks inside of `block_indices`. Layer is unspecified as it is irrelevant. +> > > > +> > > > > ![Compound][compound] ``: A single piece of additional block data, applied to the block at its index position. +> > > > > +> > > > > > ![Compound][compound] `block_entity_data`: Block entity data as NBT, stored the same as block entities in the world file itself. Position tags are saved, but replaced upon loading. No other objects seem to exist adjacent to this one at this time. +> +> ![List][list] `structure_world_origin`: List of three integers describing where in the world the structure was initially saved. Equal to the position of the saving structure block, plus its offset settings. This is used to determine where entities should be placed when loading. An entity's new absolute position is equal to its old position, minus these values, plus the origin of the structure's loading position. +> +> > ![Integer][int] Structure origin X position. +> > ![Integer][int] Structure origin Y position. +> > ![Integer][int] Structure origin Z position. + +### What Happens If... + +Results from testing to see what happens when modified structure files are loaded: + +- If the dimensions in `size` exceed the vanilla save the limit of `64*256*64`, the structure can still be loaded just as expected. +- If the values in the block layer lists are not int tags, all values are treated as `0`. +- If a value in the block layer list is equal to or larger than the palette size or less than `-1`, an air block is placed. +- If the `default` palette is not present, loading the structure results in no blocks being placed. +- If any of the tags that have constant names are unspecified or are the wrong tag type, the structure fails to load with the following content log error: + +``` +[Structure][error]-Loading structure '` from behavior pack: '' | "" field, a required field, is missing from the structure. +``` + +- If `block_indices` does not contain exactly two values, the structure fails to load with the following content log error: + +``` +[Structure][error]-Loading structure '` from behavior pack: '' | The "block_indices" field should be an array with 2 arrays and instead we have arrays. +``` + +- If the values inside of `block_indices` do not list tags, the structure fails to load with the following content log error: + +``` +[Structure][error]-Loading structure '` from behavior pack: '' | The "block_indices" field's first array is either missing or not a list. +``` + +- If the length of the two lists in `block_indices` are not equal, the structure fails to load with the following content log error: + +``` +[Structure][error]-Loading structure '` from behavior pack: '' | The "block_indices" field's arrays need to both be the same size. +``` + +- If the length of the two lists in `block_indices` does not equal the product of the structure's dimensions, the structure fails to load with the following content log error: + +``` +[Structure][error]-Loading structure '` from behavior pack: '' | The "block_indices" field should have as many elements as defined by the "size" field. +``` + +## NBT Editors + +You can find download links for some NBT editors [here](/meta/useful-links#software-installed). + +--- + +[Original Credit](https://gist.github.com/tryashtar/87ad9654305e5df686acab05cc4b6205) diff --git a/docs/wiki/nbt/nbt-in-depth.md b/docs/wiki/nbt/nbt-in-depth.md new file mode 100644 index 00000000..d2792d29 --- /dev/null +++ b/docs/wiki/nbt/nbt-in-depth.md @@ -0,0 +1,88 @@ +--- +title: About NBT (Named Binary Tag) +category: NBT in Depth +mentions: + - ConsoleTerm + - SmokeyStack + - ThomasOrs +tags: + - expert +--- + +NBT (Named Binary Tag) is a name for data encoding format at the binary level, you certainly know format JSON which is based on the text level. Therefore, we will be able to use the JSON format for some examples, you may also notice that minecraft itself uses JSON to represent NBT in commands such as java commands or simplified bedrock commands ( `/give`, `/replaceitem`). See [NBT Commands](/commands/nbt-commands) . In this article, we will show NBT in much more detail than you will ever expect, because what you could see in the commands is far from NBT, and we will show you how NBT works and how to read it, also how `Minecraft BE` itself uses it as well. + +## NBT Tags and Data Types +NBT, just like JSON, has given types and knows how to read them, for example JSON knows that a compound object starts with the symbol `{` and ends with `}`, it also knows that when it has to read a string, the string always starts with the symbol ", this means that we want to learn to read and understand NBT so you need to know when a composite object starts, and how to read individual types. +Now let's look at the table of NBT tags for NBT types and how they are marked in NBT. +As it was said, NBT works on a binary level, so you need to know that the smallest data type is a byte, which is 8 bits in size. And individual types can contain multiple bytes, but they can never be 1/2 byte extra or less, not possible! : ) +We also cannot say how the tags should be named, because everyone can call NBT tags differently, but they must always have the same binary base (`id`), id is represented by one byte. + +| Name | Binary ID | Binary Size | Description | +| :----------------: | --------: | :---------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Byte | 0x01 | 1 byte (8-bits) | One byte size type | +| Int16 (short) | 0x02 | 2 bytes (16-bits) | A two-byte type | +| Int32 (intiger) | 0x03 | 4 bytes (32-bits) | A four-byte type | +| Int64 (long) | 0x04 | 8 bytes (64-bits) | An eight-byte type | +| Float | 0x05 | 4 bytes (32-bits) | A four-byte type with regular decimal precision | +| Double | 0x06 | 8 bytes (64-bits) | An eight-byte type with higher decimal precision | +| String | 0x08 | Predefined | A string type that has a predefined size. Text uses UTF-8 encoding | +| List | 0x09 | Predefined | A list type with a predefined size and defining type for the elements in the list | +| Compoud | 0x0A (10) | Undefined | Type compound, the compound does not have a predefined size, so it is necessary to read the keys and values until we do not encounter the tag for ending the compound. | +| End of the Compoud | 0x00 | 0 bytes | This tag is not a type but only a tag and can only be used depending on the compound. It marks the end of a compound | +| Byte List | 0x07 | Predefined | List type of Byte and predefined size, not commonly used by Minecraft BE | +| Int List | 0x0B (11) | Predefined | List type of Int and predefined size, not commonly used by Minecraft BE | +| Long List | 0x0C (12) | Predefined | List type of Long and predefined size, not commonly used by Minecraft BE | + +You may notice that there is no boolean value like in JSON and that means we will express true false values as 1 and 0 using Byte. + +## How to read/write NBT tags +The same reading method applies to all numbers, read as many bytes as the number tag type is large, such as: Int16 (short) is 2 bytes in size, so I will read 2 bytes, but you need to know that Minecraft BE uses the [little-endian](#little-endian), unlike Java, it uses big-endian. [Little-endian](#little-endian) is a way to write or read bytes of numbers. + +### Reading Types +Type is always one byte in size, so we read the type and find out what to read next for the tag. + +### Reading Numbers +When reading a number, it is necessary to know what type of number we are reading, we can find out by reading the type *([Reading types](#reading-types))*. Then when we know what type of number we have to read, we read it, for example, if we know that we want type `3`, then we look in the table and we know that type 3 is a number of 4-bytes size, so we read 4 bytes. All numbers ***BE*** reads/writes with [little-endian](#little-endian) method. + +### Reading Strings +When reading a string, you need to know its length in bytes, this string length is always written with Int16 (short) `2 bytes` ([how to read numbers](#reading-numbers)) before the string, i.e. first we read the number, then we read the number of bytes of the number we read before, after we know the bytes we can stuff them through UTF-8 encoding and we get text from them. + +### Reading Lists +When reading a list, we must first read the list ([type](#reading-types)), whether this list contains numbers or other lists or strings, etc. So first we read the type of this list, then we read the [number](#reading-numbers) of elements which is written as an Int32 (int) number, so we read 4 bytes, now we know the type of our elements and their count, so we read this type as many times as we know from the readed number before. Reading the size of a list is not the same as reading the size of a string! Should read Int32 no Int16! This solution does not apply to `Byte-List, Int-List, Long-List`! + +### Reading Compouds +Compound has all properties named so when reading an property it is always necessary to read its name as well. The procedure for reading Compoud is rather simple. First, we read the type, the type can be anything, but if it is equal to an empty byte, then it is the end of the compound and then we jut stop reading, but if the type is not equal to the Compoud Ending tag, then the significant type of the property that we will read. The read property is always followed by the name (key), which needs to be read as a [string](#reading-strings), and after the string is read, then we can read value. + +## Minecraft BE NBT files +When reading Minecraft NBT files, it is always important to be careful if there is no Bedrock Header at the beginning of the file, see [Bedrock NBT Header](#bedrock-nbt-file-header), but not all MCBE NBT files contain this header, for example `.mcstructure` also does not contain a Bedrock NBT header, unlike `level.dat`. +You also need to pay attention to the root element in the file, i.e. the list or compoud, +The root element also looks like a property, so you need to read the name of this root property, although Bedrock does not use these names, so these names are empty, but they are there. +Here is how .mcstructure looks like where JSON represents NBT. +```json +"":{ + "format_version":1, + "size":[],//... + "structure":{},//... + "structure_world_origin":[]//.. +} +``` +:::warning +This example shows that it is also necessary to read the name of the basic element, although it is usually unused and empty. +::: + +## Writing NBT +There is no certain procedure for writing, because it is the same mothods as when reading, but backwards. That's why we recommend first understanding NBT and learning to read it correctly, then it won't be difficult to write NBT. + +## Bedrock NBT File header +The NBT bedrock Header is indicated by two 4-byte numbers, the first is always 8 and the second indicates the size of the nbt structure in bytes. E.g. + - `08 00 00 00` - `bf 00 00 00` + - < always 8 > < always the size of the NBT structure - exclude headers 8 bytes> + +## Little-Endian +Little-Endian is the common method of writing numbers in bytes to streams or files. +It's not a science and it's easy to understand. So if Int16 `(short)` of value `0x5a72` then we convert it to bytes [`0x5a`, `0x72`] and then reverse their order that means [`0x72`, `0x5a`] and write d file: `72 5a`. It may seem illogical, but little-endian is almost always used when writing and reading from files. A single `byte` is the same in both methods because it is one byte in size. For example: +- Int64 (long) `0x11223344aabbccdd` +- Split to 8 bytes `0x11 0x22 0x33 0x44 0xAA 0xBB 0xCC 0xDD` +- Reverse `0xDD 0xCC 0xBB 0xAA 0x44 0x33 0x22 0x11` +- Write `dd cc bb aa 44 33 22 11` +- Done (when reading the number just go backwards this example.) diff --git a/docs/wiki/nbt/step-by-step-example.md b/docs/wiki/nbt/step-by-step-example.md new file mode 100644 index 00000000..79871331 --- /dev/null +++ b/docs/wiki/nbt/step-by-step-example.md @@ -0,0 +1,84 @@ +--- +title: Reading NBT Example +category: NBT in Depth +mentions: + - ConsoleTerm +tags: + - expert +--- + +Before going through this example, it is necessary to first familiarize yourself with NBT in its full beauty. See *[NBT in Depth](/nbt/nbt-in-depth)*. +Now we will show you how to read NBT, step by step, the format of what we will read will look something like this: +```json +"":{ + "myText":"My NBT text", + "my Int32 Number":456, +} +``` +When we don't know what to read, then we read the next byte. + +![](/assets/images/nbt/VS_Editor_images/step1.png) + +What did we read? We read number 10 and that means we will read compoud. We also know that we are at the root element property of this file now, so we need to read the name of our root element property. Name is string, so first we have to read the length of the text in bytes, and that is written by Int16 *(Short)*. + +![](/assets/images/nbt/VS_Editor_images/step2.png) + +The name size of our root element property is zero so we won't read any more bytes. We don't know what to read, so let's read another byte. + +![](/assets/images/nbt/VS_Editor_images/step3.png) + +We already know that the next property in our root compound is type of string, but before we read our property value, we first read its name written such as string. So we read another 2 bytes to get the length of the string name from of our property. + +![](/assets/images/nbt/VS_Editor_images/step4.png) + +We see that length of property name, it is 6 bytes long. So let's read the next 6 bytes. + +![](/assets/images/nbt/VS_Editor_images/step5.png) + +So we have read the Name of our property, which we can get in text form using UTF-8 encoding, that is: `myText`, then remember that the type of our property is string, so we repeat the process. +I'll read the next Int16 (2 bytes) again and we'll find out the length of our string value. + +![](/assets/images/nbt/VS_Editor_images/step6.png) + +The string length of our property is 0x0B, so 11, so read another 11 bytes. + +![](/assets/images/nbt/VS_Editor_images/step7.png) + +When we push our read bytes through UTF-8 encoding, it again returns the value: `My NBT text`, +what now? You don't know? So read the next byte to find out what to do next. + +![](/assets/images/nbt/VS_Editor_images/step8.png) + +So we read type 3, the 3 type is Int16 which contains 4 bytes. But before we read our number We have to find out the name of this property again. So? +Read the next two bytes to get the length of the name for this property. + +![](/assets/images/nbt/VS_Editor_images/step9.png) + +So we know the length of the name 0x0f (15), Let's read the next 15 bytes and push it through UTF-8 encoding. + +![](/assets/images/nbt/VS_Editor_images/step10.png) + +Now we have the name of this property: `my Int32 Number`. Next let's read that Int32 => 4 bytes. + +![](/assets/images/nbt/VS_Editor_images/step11.png) + +We read an Int32 that has the value `0x01c8` (456). +Again You don't know what to do next? Then just read another type of next property, so? 1 byte. + +![](/assets/images/nbt/VS_Editor_images/step12.png) + +We read 0x00 (an empty byte), and that marks the end of the root compound. Then the reading of the compound ends, and since it is the ***root*** compound, we can finish reading it completely and have the entire NBT file read. +### NBT Example File +This is file what we use here for this example. + +Download NBT File + +:::tip Important points to keep in mind + - The file may contain an NBT Bedrock Header, so be aware that such a situation may occur. See [NBT in Depth](/nbt/nbt-in-depth)>[NBT Bedrock Headers](/nbt/nbt-in-depth#bedrock-nbt-file-header). + - The closing null byte does not terminate the reading of the NBT as such, but merely marks the end of the current compound. + - All the numbers you read need to be read with little-endian, See [NBT in Depth](/nbt/nbt-in-depth)>[little-endian](/nbt/nbt-in-depth#little-endian). + - The first root NBT element in a file can only be a compound or a list. The root element/property in NBT files also has its own name, even though it is mostly empty, but it still needs to be read and avoid complications. +::: diff --git a/docs/wiki/nbt/structure-limits.md b/docs/wiki/nbt/structure-limits.md new file mode 100644 index 00000000..6238c374 --- /dev/null +++ b/docs/wiki/nbt/structure-limits.md @@ -0,0 +1,47 @@ +--- +title: Extending Structure Limits +category: Tutorials +mentions: + - MedicalJewel105 +tags: + - easy +--- + +[structure]: /assets/images/nbt/structure.png +[int]: /assets/images/nbt/int.png +[list]: /assets/images/nbt/list.png +[compound]: /assets/images/nbt/compound.png +[string]: /assets/images/nbt/string.png + +:::warning DEPRECATED +This method no longer works after 1.20.50 update. +::: + +By default, Minecraft doesn't allow you to save structures that are more than 64x255x64 in size. +In this guide you will learn how to extend structure box size for structure blocks. + +## Editing NBT + +1. Put a structure block into structure and export it. +2. Open your structure with NBT editor (NBT Studio in our case) and find your structure block. + +If the only block you have in your structure is structure block, you will find its data here: + +![][structure] extending_structure_block.mcstructure +> ![][compound] structure +> > ![][compound] palette +> > > ![][compound] default +> > > > ![][compound] block_position_data +> > > > > ![][compound] 0 + +![](/assets/images/nbt/structure-limits/nbt-screenshot-1.png) + +3. Set `xStructureSize`, `yStructureSize` and `zStructureSize` values to what you want. +4. Save the structure and load it in game. + +![](/assets/images/nbt/structure-limits/result.png) + +## Tips + +You can get this structure block to your inventory by pressing mouse scroll button while holding Ctrl. +It is recommended to use structure loading animations (Place by Block) when loading a huge structure. This will minimize lags. diff --git a/docs/wiki/particles/disabling-particles.md b/docs/wiki/particles/disabling-particles.md new file mode 100644 index 00000000..f34a753b --- /dev/null +++ b/docs/wiki/particles/disabling-particles.md @@ -0,0 +1,40 @@ +--- +title: Disabling Particles +category: Tutorials +tags: + - beginner +mentions: + - SirLich + - Joelant05 + - MedicalJewel105 +--- + +In the event that you want to disable a particle, it is recommended to do so from the particle file itself as opposed to simply making the particle texture transparent in `particles.png`. Additionally, disabling a particle might offer a slight performance boost compared to making it transparent, as transparent particles are still emitted (but not visible). + +The basic idea of disabling a particle from emitting is as follows: + +RP/particles/some_vanilla_particle.json + +```json +{ + "format_version": "1.10.0", + "particle_effect": { + "description": { + "identifier": "minecraft:some_vanilla_particle", + "basic_render_parameters": { + "material": "particles_alpha", + "texture": "textures/particle/particles" + } + }, + "components": { + "minecraft:emitter_lifetime_expression": { + "activation_expression": 0, + "expiration_expression": 1 + }, + "minecraft:emitter_rate_manual": { + "max_particles": 0 + } + } + } +} +``` diff --git a/docs/wiki/particles/index.md b/docs/wiki/particles/index.md new file mode 100644 index 00000000..83230842 --- /dev/null +++ b/docs/wiki/particles/index.md @@ -0,0 +1,10 @@ +--- +title: Particles +categories: + - title: General + color: blue + - title: Tutorials + color: green + - title: Documentation + color: red +--- diff --git a/docs/wiki/particles/particles-and-sounds.md b/docs/wiki/particles/particles-and-sounds.md new file mode 100644 index 00000000..8630ee07 --- /dev/null +++ b/docs/wiki/particles/particles-and-sounds.md @@ -0,0 +1,336 @@ +--- +title: 'Particles and Sounds' +category: General +tags: + - outdated +mentions: + - SirLich + - Joelant05 + - destruc7ion + - MedicalJewel105 + - aexer0e + - solvedDev +--- + +:::danger +Some information from this page was copied [here](/visuals/animation-effects) +::: + +## Particles in Animation + +Minecraft Particles can be used in entity animations. For example, the phantom has an animation which emits the minecraft:phantom_trail particle constantly. Let's try to add a particle to our entity's attack animation. + +`part of RP/entity/description/` + + + +```json + "particle_effects": { + "l_explosion": "minecraft:large_explosion" + }, +``` + +This piece of code is located in our resource entity file. Here we defined the shortname ("l_explosion") for the particle we are going to use, "minecraft:large_explosion". + +You can test a particle in-game with the `/particle ~ ~2 ~` command. You can view the full list of Vanilla Particles [here](https://minecraft.wiki/w/Particles). + +Now for the Blockbench part. + +- Right click the bone were your particle will be emitted from, and choose 'Add Locator' with the anchor icon. Name it something distinct, like 'l_expl_emitter'. Now move the emitter to the desired location. + +![](/assets/images/guide/custom_particles_1.png) + +_Note: you can also use locators to define where a lead will leash to, if you name your locator 'lead'._ + +- In the 'Animate' section, choose 'Animate Effects' on your timeline, then click on the '+' icon near the 'Particle' object. + +![](/assets/images/guide/custom_particles_2.png) + +- You will see this menu on your left. 'Effect' asks for your particle's shortname, and 'Locator' asks for the name of your Locator/Emitter object. + +![](/assets/images/guide/custom_particles_3.png) + +_Note: you can add sounds to animations in a similar way._ + +![](/assets/images/guide/custom_particles_4.jpg) + +Now you're good to go! Save the model and the animations. If you did everything correctly, the defined particle will spawn whenever the entity attacks. _Of course you could put another particle on the walking animation's timeline (for example, hooves making dust) in the same way._ + +## Custom Particles + +Custom particles are defined in the `RP/particles` folder. As mentioned earlier on this page, you can summon particles using the '/particle' command (e.g in Behavior Animations) or using Resource Animation emitters. The best way to learn custom particles is to play around with the example files from the [Vanilla Example resource pack](https://www.minecraft.net/en-us/addons) and the Particle Example Pack, and of course, from the documentation on [bedrock.dev](http://bedrock.dev/r/Particles). + +_Note: Skip to the end of this section for a tool to generate particle files visually._ + +File structure: + +- "identifier" is exactly what you'd expect: I'll use "wiki:curvy_particle" and "wiki_pink_hit" for the tutorial. File names do not matter. +- "texture" defines the texture file. Not that a single image file can hold textures for many particles. +- "material" is usually set to "particles_alpha" for particles. + +![](/assets/images/guide/custom_particles_5.png) + +That is the texture I'm going to use, it's size is `16x16`. (`RP/particles/wiki_particles.png`). As you can see, it has 4 different textures in it, each of them being a `8x8`. The upper row (_starting/top left corner at at 0, 0_) is the flipbook texture for "wiki:curvy*particle" and the bottom row (\_top left corner at/starting at 0, 8*). We'll define this in the "billboard_texture" component. + +RP/particles/curvy_particle.json + +```json +{ + "format_version": "1.10.0", + "particle_effect": { + "description": { + "identifier": "wiki:curvy_particle", + "basic_render_parameters": { + "material": "particles_alpha", + "texture": "textures/particle/wiki_particles" + } + }, + "components": { + "minecraft:emitter_rate_instant": { + "num_particles": 50 + }, + "minecraft:emitter_lifetime_once": { + "active_time": 0 + }, + "minecraft:emitter_shape_sphere": { + "radius": 0.3, + "direction": "outwards" + }, + "minecraft:particle_initial_speed": "Math.random(0.0, 15.0)", + "minecraft:particle_initial_spin": { + "rotation": "Math.random(0, 360)", + "rotation_rate": "Math.random(-300, 300)" + }, + "minecraft:particle_lifetime_expression": { + "max_lifetime": "Math.random(1.0, 4.0)" + }, + "minecraft:particle_motion_dynamic": { + "linear_acceleration": [0, 2.0, 0], + "linear_drag_coefficient": 5, + "rotation_drag_coefficient": 0.3 + }, + "minecraft:particle_appearance_billboard": { + "size": ["0.11", "0.11"], + "facing_camera_mode": "lookat_xyz", + "uv": { + "texture_width": 16, + "texture_height": 16, + "flipbook": { + "base_UV": [0, 0], + "size_UV": [8, 8], + "step_UV": [8, 0], + "frames_per_second": 2, + "max_frame": 2, + "stretch_to_lifetime": true, + "loop": false + } + } + }, + "minecraft:particle_appearance_lighting": {} + } + } +} +``` + +Here's the code for our first particle, "wiki:curvy_particle". Our texture file is defined. + +The components are quite complicated here, but they're explained well on the [Particle doc](http://bedrock.dev/r/Particles). Let's move forward to the `"minecraft:particle_appearance_billboard"` component for now. + +- "texture_width" and "texture_height" defines the size of the image file itself. +- "base_UV" in "flipbook" defines the top-left corner of the particle texture. For this particle it's at 0, 0, which is the upper left corner of the image itself. For the second particle, "wiki:pink_hit", "base_UV" will be at 0, 8, which is 8 pixels lower then the first location. +- "size_UV" defines the size of the particle's texture(8*8) on the image file(which is 16*16). +- "step_UV" is how far the flipbook needs to step in order to get the next particle texture. In this case it's 8, 0, which is 8 pixels to the right. +- "frames_per_second" is quite self-explainable. "max_frame" is the total number of frames for the particle. + +The second particle, "wiki:pink_hit". + +RP/particles/pink_hit.json + +```json +{ + "format_version": "1.10.0", + "particle_effect": { + "description": { + "identifier": "wiki:pink_hit", + "basic_render_parameters": { + "material": "particles_alpha", + "texture": "textures/particle/wiki_particles" + } + }, + "components": { + "minecraft:emitter_rate_steady": { + "spawn_rate": 520, + "max_particles": 48 + }, + "minecraft:emitter_lifetime_once": { + "active_time": 0.15 + }, + "minecraft:emitter_shape_point": { + "offset": [0.0, "Math.random(-0.9, -0.5)", 0.0], + "direction": [ + "Math.random(-0.75, 0.75)", + "Math.random(-1.0, 1.0)", + "Math.random(-0.75, 0.75)" + ] + }, + "minecraft:particle_initial_speed": "Math.random(10.0, 20.0)", + "minecraft:particle_lifetime_expression": { + "max_lifetime": "6.0 / (Math.random(0.0, 16.0) + 12.0)" + }, + "minecraft:particle_motion_dynamic": { + "linear_acceleration": [0, -12.0, 0], + "linear_drag_coefficient": 10 + }, + "minecraft:particle_appearance_billboard": { + "size": [ + "0.10 + v.particle_random_1*0.05", + "0.10 + v.particle_random_1*0.05" + ], + "facing_camera_mode": "lookat_xyz", + "uv": { + "texture_width": 16, + "texture_height": 16, + "flipbook": { + "base_UV": [0, 8], + "size_UV": [8, 8], + "step_UV": [8, 0], + "frames_per_second": 8, + "max_frame": 2, + "stretch_to_lifetime": true, + "loop": false + } + } + }, + "minecraft:particle_appearance_tinting": { + "color": { + "gradient": [ + [ + "v.particle_random_1*0.3 + 0.6", + "v.particle_random_2*0.3+ 0.6", + "v.particle_random_2*0.3+ 0.6", + 1.0 + ], + ["v.particle_random_1*0.3 + 0.6", 0.5, 0.3, 1.0] + ], + "interpolant": "v.particle_age/v.particle_lifetime" + } + }, + "minecraft:particle_appearance_lighting": {} + } + } +} +``` + +Done! Now you have two custom particles that can be used in animations! + +It's rather tiresome to create particles that way, comparable to creating models without Blockbench. Luckily, you can use [Snowstorm](https://jannisx11.github.io/snowstorm/), a Visual Particle Generator. It's especially convenient to download the [VSC Snowstorm Extension](https://marketplace.visualstudio.com/items?itemName=JannisX11.snowstorm), which is going to create an interactive UI in Visual Studio Code itself for `.particle.json` files. + +![](/assets/images/guide/custom_particles_6.jpg) +`/particle wiki:pink_hit ~ ~2 ~` + +![](/assets/images/guide/custom_particles_7.jpg) +`/particle wiki:curvy_particle ~ ~2 ~` + +--- + +## Defining Custom Sounds + +_You can find a more in-depth tutorial on custom sounds on [wiki.bedrock.dev](/concepts/sounds)._ + +Minecraft can read sound files in the `.ogg` (recommended) or `.wav` format. (You can look up an .mp3 to .ogg converter online). Personally, I usually get my sound effects from ZapSplat.com. + +Sound files are located in subfolders of the `RP/sounds/` folder. My skele_yaklin sound files are located under `RP/sounds/mob/yaklin_moo.ogg` and `RP/sounds/mob/yaklin_moo_2.ogg`. (I don't have more sound effects currently, thus I will be using same ones over and over, but ideally one would need more of those). + +### Sound Definition + +Now to define the sound's shortnames! This process is similar to defining block texture shortnames. It's done in `RP/sounds/sound_definitions.json`. + +RP/sounds/sound_definitions.json + +```json +{ + "format_version": "1.14.0", + "sound_definitions": { + "mob.yaklin.idle": { + "category": "neutral", + "max_distance": 12.0, + "sounds": ["sounds/mob/yaklin_moo", "sounds/mob/yaklin_moo_2"] + }, + "mob.yaklin.death": { + "category": "neutral", + "max_distance": 12.0, + "sounds": ["sounds/mob/yaklin_moo"] + }, + "mob.yaklin.hurt": { + "category": "neutral", + "max_distance": 12.0, + "sounds": "sounds/mob/yaklin_moo" + } + } +} +``` + +We have 3 sound shortnames in total: + +1. `mob.yaklin.idle`, which refers to a random sound file from the "sounds": [] array. +1. `mob.yaklin.death` can be heard from the distance of 12 blocks: `max_distance": 12.0`. +1. And, lastly, `mob.yaklin.hurt`. + +### sounds.json + +Now we are about to call our sounds. We can do it either through the `/playsound <>` slash command or automatically in `RP/sounds.json`. Once again, this resembles block resource definition. + +![](/assets/images/guide/custom_particles_8.png) + +^ the file's structure. I recommend checking out the same file in the Example Resource Pack. + +RP/sounds.json/"entities": {}/"wiki:skele_yaklin": {} + +```json + "wiki:skele_yaklin": { + "volume": 1.0, + "pitch": [ + 1.0, + 1.0 + ], + "events": { + "ambient": "mob.yaklin.idle", + "hurt": "mob.yaklin.hurt", + "death": "mob.yaklin.death", + "step": { + "sound": "mob.cow.step", + "volume": 0.15, + "pitch": 1.0 + } + } + } +``` + +Let's see how the sounds of the skele_yaklin are called in the entity's object. + +- The first "volume" and "pitch" are global, they are the starting point for every other of the entity's sounds. If you want the sounds to play exactly how they are, set both of them to 1; +- "events" include the automatic sounds to be played. There are a couple Vanilla events that will trigger automatically(you can see the whole list on the wiki.bedrock.dev page linked bove). All of the events call a sound's shortname. +- "ambient" plays occasionally, for example the sheep "baah" sound. +- "hurt" plays when the entity is hurt. +- "death" plays on death. +- "step" is the sound of the mob walking. I used the cow step sound, already included in the base game. + +That's it! Turn up your Sound volume in Settings>Audio, spawn in your mobs, and listen to the melodic cacophony of their new voices! + +--- + +--- + +## Your progress so far + +**What you've done:** + +- Learned to include Particles in Animations +- Created two Custom Particles and learned to create more +- Defined custom Sounds for your custom entity; + +**What are you to do next:** + +- Create custom biomes +- Create custom generated Structures +- Be introduced to Scripting diff --git a/docs/wiki/particles/particles.md b/docs/wiki/particles/particles.md new file mode 100644 index 00000000..3fa4f7a7 --- /dev/null +++ b/docs/wiki/particles/particles.md @@ -0,0 +1,43 @@ +--- +title: 'Intro to Particles' +category: General +tags: + - guide +mentions: + - SirLich + - MedicalJewel105 + - TheItsNameless +--- + +## Particle Systems + +A [particle system](https://www.wikiwand.com/en/Particle_system) is a technique in game physics, motion graphics, and computer graphics that uses many small sprites to create convincing effects such as smoke, fire, or swarms of insects. You can create new particle systems in the Bedrock Edition of Minecraft by using your own custom textures, and your own movement logic. This makes particles extremely fun and powerful! + +The Molang integration in particles is also extremely well developed, which allows you to pass data between different particles, or between an entity and a particle. + +### Particles + +A 'particle', or a 'particle instance' is a single sprite (texture) which is placed in 3D space, and has its own logic for how to move about and change its appearance. Some examples of a particle could include: + +- A single snowflake +- A single raindrop +- A single wisp of smoke + +### Emitters + +An 'emitter' or 'particle emitter' is a system that can spawn many particles, either all at once (explosion), or over time (steady). Emitters have their own logic for how to move, how many particles to spawn, and where. Some examples of emitters could include: + +- A snowstorm (creates snowflakes) +- A rainstorm (creates raindrops) +- A smokey chimney (creates smoke wisps) + +## Creating your First Particle + +To create a particle, you need a resource pack, a texture, and a particle definition file: + + diff --git a/docs/wiki/particles/vanilla-particles.md b/docs/wiki/particles/vanilla-particles.md new file mode 100644 index 00000000..2637d02b --- /dev/null +++ b/docs/wiki/particles/vanilla-particles.md @@ -0,0 +1,225 @@ +--- +title: Vanilla Particles +category: Documentation +--- + +Here is the complete list of Bedrock particles from the vanilla resources. Please be aware that not all of these particles function properly, as many require molang context from their host entity. + +:::tip Playing via /particle: +For some reason, Bedrock requires the leading `minecraft` namespace, and the coordinates in the `/particle` command. + +It doesn't have autocomplete for particles. +::: + +### Working Particles + +These particles can be spawned directly in-world, without any issues. + +| Working Particles | +| ------------------------------------------- | +| minecraft:basic_flame_particle | +| minecraft:basic_portal_particle | +| minecraft:basic_smoke_particle | +| minecraft:bleach | +| minecraft:blue_flame_particle | +| minecraft:camera_shoot_explosion | +| minecraft:campfire_smoke_particle | +| minecraft:campfire_tall_smoke_particle | +| minecraft:candle_flame_particle | +| minecraft:critical_hit_emitter | +| minecraft:crop_growth_emitter | +| minecraft:dragon_breath_trail | +| minecraft:dragon_death_explosion_emitter | +| minecraft:dragon_destroy_block | +| minecraft:dragon_dying_explosion | +| minecraft:endrod | +| minecraft:end_chest | +| minecraft:evocation_fang_particle | +| minecraft:evoker_spell | +| minecraft:cauldron_explosion_emitter | +| minecraft:egg_destroy_emitter | +| minecraft:falling_border_dust_particle | +| minecraft:falling_dust_dragon_egg_particle | +| minecraft:falling_dust_gravel_particle | +| minecraft:falling_dust_red_sand_particle | +| minecraft:falling_dust_sand_particle | +| minecraft:falling_dust_scaffolding_particle | +| minecraft:falling_dust_top_snow_particle | +| minecraft:heart_particle | +| minecraft:honey_drip_particle | +| minecraft:huge_explosion_lab_misc_emitter | +| minecraft:huge_explosion_emitter | +| minecraft:ice_evaporation_emitter | +| minecraft:knockback_roar_particle | +| minecraft:lab_table_misc_mystical_particle | +| minecraft:large_explosion | +| minecraft:lava_drip_particle | +| minecraft:lava_particle | +| minecraft:llama_spit_smoke | +| minecraft:magnesium_salts_emitter | +| minecraft:mob_portal | +| minecraft:mycelium_dust_particle | +| minecraft:obsidian_glow_dust_particle | +| minecraft:obsidian_tear_particle | +| minecraft:redstone_ore_dust_particle | +| minecraft:redstone_repeater_dust_particle | +| minecraft:redstone_torch_dust_particle | +| minecraft:redstone_wire_dust_particle | +| minecraft:rising_border_dust_particle | +| minecraft:sculk_sensor_redstone_particle | +| minecraft:snowflake_particle | +| minecraft:spore_blossom_ambient_particle | +| minecraft:spore_blossom_shower_particle | +| minecraft:stalactite_lava_drip_particle | +| minecraft:stalactite_water_drip_particle | +| minecraft:totem_particle | +| minecraft:villager_angry | +| minecraft:villager_happy | +| minecraft:water_drip_particle | +| minecraft:water_evaporation_bucket_emitter | +| minecraft:water_splash_particle_manual | + +### Particles with Issues + +The following particles can be spawned, but might spam you with content log errors because they rely on variables that `/particle` cannot set: + +| Particles with issues | +| ----------------------------------------------- | +| minecraft:arrow_spell_emitter | +| minecraft:balloon_gas_particle | +| minecraft:basic_crit_particle | +| minecraft:conduit_absorb_particle | +| minecraft:conduit_attack_emitter | +| minecraft:dragon_breath_fire | +| minecraft:dragon_breath_lingering | +| minecraft:electric_spark_particle | +| minecraft:enchanting_table_particle | +| minecraft:elephant_tooth_paste_vapor_particle | +| minecraft:death_explosion_emitter | +| minecraft:eyeofender_death_explode_particle | +| minecraft:explosion_particle | +| minecraft:falling_dust_concrete_powder_particle | +| minecraft:lab_table_heatblock_dust_particle | +| minecraft:misc_fire_vapor_particle | +| minecraft:mobspell_emitter | +| minecraft:mob_block_spawn_emitter | +| minecraft:note_particle | +| minecraft:portal_directional | +| minecraft:portal_reverse_particle | +| minecraft:rain_splash_particle | +| minecraft:shulker_bullet | +| minecraft:silverfish_grief_emitter | +| minecraft:soul_particle | +| minecraft:sparkler_emitter | +| minecraft:splash_spell_emitter | +| minecraft:water_evaporation_actor_emitter | +| minecraft:water_splash_particle | +| minecraft:water_wake_particle | +| minecraft:wax_particle | +| minecraft:wither_boss_invulnerable | + +### Bubble Particles + +The following particles are various bubbles that only show up underwater. Some of them spam content log errors: + +| Bubble particles | +| -------------------------------------- | +| minecraft:basic_bubble_particle | +| minecraft:basic_bubble_particle_manual | +| minecraft:bubble_column_bubble | +| minecraft:bubble_column_down_particle | +| minecraft:bubble_column_up_particle | +| minecraft:cauldron_bubble_particle | +| minecraft:cauldron_splash_particle | +| minecraft:dolphin_move_particle | +| minecraft:eye_of_ender_bubble_particle | +| minecraft:fish_hook_particle | +| minecraft:fish_pos_particle | +| minecraft:glow_particle | +| minecraft:guardian_attack_particle | +| minecraft:guardian_water_move_particle | +| minecraft:sponge_absorb_water_particle | +| minecraft:squid_flee_particle | +| minecraft:squid_ink_bubble | +| minecraft:squid_move_particle | +| minecraft:underwater_torch_particle | + +### Permanent Particles + +The following particles are permanent and will not be removed once spawned until you exit the game: + +| Permanent particles | +| -------------------------------- | +| minecraft:mobflame_emitter | +| minecraft:nectar_drip_particle | +| minecraft:phantom_trail_particle | +| minecraft:stunned_emitter | + +## Broken Particles + +The following particles exist in-game but cannot be spawned because they require context that cannot be provided by `/particle` or are simply bugged: + +| Broken particles | +| -------------------------------- | +| minecraft:block_destruct | +| minecraft:block_slide | +| minecraft:breaking_item_icon | +| minecraft:breaking_item_terrain | +| minecraft:cauldron_spell_emitter | +| minecraft:ink_emitter | +| minecraft:portal_east_west | +| minecraft:portal_north_south | +| minecraft:vibration_signal | +| minecraft:colored_flame_particle | + +--- + +[Original Credit](https://www.reddit.com/r/MinecraftCommands/comments/cbd56p/i_need_a_list_of_bedrock_particles/etg8rt7/) + +## Component Particles + +The following is a list of pre-defined short names for Vanilla particles that can be used in certain components. +**These have all been proven to generally work. This may not be a full list.** + +| Short names | Notes | +| --------------------- | ---------------------------------------------------------- | +| mobspellambient | Color determined by any present potion ID in the component | +| villagerangry | | +| bubble | Only shows underwater | +| evaporation | | +| crit | | +| dragonbreath | Only seems to work for the AoE component for Projectiles | +| driplava | | +| dripwater | | +| reddust | | +| enchantingtable | | +| endrod | | +| mobspell | Color determined by any present potion ID in the component | +| largeexplode | | +| hugeexplosion | | +| fallingdust | Color determined by any present potion ID in the component | +| waterwake | | +| flame | | +| villagerhappy | | +| heart | | +| mobspellinstantaneous | Color determined by any present potion ID in the component | +| iconcrack | | +| slime | | +| snowballpoof | | +| largesmoke | | +| lava | | +| mobflame | | +| townaura | | +| note | | +| explode | | +| portal | | +| rainsplash | | +| smoke | | +| watersplash | | +| ink | | +| terrain | Pulls texture from atlas.terrain | +| totem | | +| witchspell | | +| soul | | +| spit | | +| sneeze | | diff --git a/docs/wiki/servers/index.md b/docs/wiki/servers/index.md new file mode 100644 index 00000000..5a614fa1 --- /dev/null +++ b/docs/wiki/servers/index.md @@ -0,0 +1,3 @@ +--- +title: Servers & Realms +--- diff --git a/docs/wiki/servers/raknet-and-mcpe.md b/docs/wiki/servers/raknet-and-mcpe.md new file mode 100644 index 00000000..ad3b55c7 --- /dev/null +++ b/docs/wiki/servers/raknet-and-mcpe.md @@ -0,0 +1,126 @@ +--- +title: RakNet and MCPE +mentions: + - ZestiiSpaghett + - MedicalJewel105 + - SmokeyStack + - ThomasOrs + - Adrian8115 +--- + +Minecraft Bedrock uses a protocol known as [RakNet](http://www.jenkinssoftware.com/) +Unlike Minecraft Java edition, Bedrock uses UDP on the port 19132 + +You can find a list of Minecraft Bedrock server softwares [here](/servers/server-software#active-software). + +## RakNet Notes + +- All strings are prefixed with an unsigned short depicting their length. +- The offline message id will always be: 00ffff00fefefefefdfdfdfd12345678 (hex) - this series of bytes will be referred to as *Magic* +- The offline message id is sent with unconnected messages such as unconnected pings and pongs. +- The GUIDS used by RakNet are 8 bytes long. +- The first byte is used to identify the type of message. + +## Data Types + +| Type | Size | Range | Notes | +| -------------- | ---- | --------------- | -------------------------------------------------------------- | +| Byte | 1 | 0-255 | An unsigned integer | +| Long | 8 | -2^63 to 2^63-1 | Signed 64 bit integer | +| Magic | 16 | | 00ffff00fefefefefdfdfdfd12345678 - Will always be those bytes | +| Short | 2 | -32768 to 32767 | | +| Unsigned Short | 2 | 0 to 65535 | | +| String | N/A | N/A | A string prefixed by a short which depicts the length. | +| Boolean | 1 | 0-1 | 0x00 is False while 0x01 is True | +| Address | 7 | | 1 byte for the ip version 4/6, 4 for the IP and 2 for the port | +| uint24le | 3 | | 3-byte little-endian unsigned integer | + +## Contents + + + +- [x] Unconnected Pings +- [x] Unconnected Pongs +- [x] Open Connection Request 1 +- [x] Open Connection Reply 1 +- [x] Open Connection Request 2 +- [x] Open Connection Reply 2 +- **From here on, the RakNet connection is established and all RakNet messages are contained in a [Frame Set Packet](https://wiki.vg/Raknet_Protocol#Frame_Set_Packet).** +- [x] Connection Request +- [x] Connection Request Accepted + + + +### Unconnected Pings + +Minecraft Bedrock will send out a message to all listed servers (and the local network) to check if any games are available and retrieve the MOTD from the game. These messages are known as unconnected pings and are structured in this format: + +`0x01 | client alive time in ms (unsigned long long) | magic | client GUID` + +### Unconnected Pongs + +After this message, the server will respond with something called an unconnected pong. The reason these messages are unconnected is because the client has not established a connection to the server. This is the format of an unconnected pong: + +`0x1c | client alive time in ms (recorded from previous ping) | server GUID | string length | Edition (MCPE or MCEE for Education Edition);MOTD line 1;Protocol Version;Version Name;Player Count;Max Player Count;Server Unique ID;MOTD line 2;Game mode;Game mode (numeric);Port (IPv4);Port (IPv6);` + +Example: + +`MCPE;Dedicated Server;527;1.19.1;0;10;13253860892328930865;Bedrock level;Survival;1;19132;19133;` + +The client doesn't seem to use the gamemode or the numeric value for the gamemode. + +### Open Connection Request 1 + +The client sends this when attempting to join the server + +`0x05 | Magic | Protocol version (currently 10 or 0x0a) | RakNet Null Padding` + +The null padding seems to be used to discover the maximum packet size the network can handle. + +The client will send this to the server with decreasing null padding until the server responds with a + +## Open Connection Reply 1 + +The server responds with this once the client attempts to join + +`0x06 | magic | server GUID | use encryption boolean (normally false) | RakNet Null Padding Size (Unsigned short, I use 1400)` + +This is the first half of the handshake between the client and the server. + +### Open Connection Request 2 + +The client responds with this after they receive the open connection reply 1 packet. + +`0x07 | magic | server address | RakNet Null Padding Size | client GUID` + +### Open Connection Reply 2 + +This is the last part of the handshake between the client and the server. + +`0x08 | magic | server GUID | client address | Null Padding Size | use encryption` + +### Connection Request + +This is the part where the client sends the connection request. + +`0x09 | client GUID | Request timestamp (Long) | Secure (Boolean, I use 0x00)` + +### Connection Request Accepted + +The server sends this packet in response to the incoming connection request. + + `0x10 | client Address | System index (Short, unknown what this does. 0 works as a value) | System adresses ([]Address) | Request timestamp (Long) | Accepted timestamp (Long)` + +## Sources +::: tip +If you are interested and want to read more about it here is the documentation for the Bedrock Protocol and RakNet: + +[RakNet Protocol Documentation](https://wiki.vg/Raknet_Protocol) + +[Newer Bedrock Protocol Documentation for 1.20.50](https://prismarinejs.github.io/minecraft-data/?d=protocol&v=bedrock_1.20.50) [(by PrismarineJS)](https://prismarinejs.github.io) ::: + +::: warning +There is also the old Bedrock Protocol Wiki which might possibly be outdated! +[Bedrock Protocol Documentation](https://wiki.vg/Bedrock_Protocol) ::: + +This page is a WIP, feel free to contribute as it is still being worked on. diff --git a/docs/wiki/servers/server-software.md b/docs/wiki/servers/server-software.md new file mode 100644 index 00000000..c8c98c41 --- /dev/null +++ b/docs/wiki/servers/server-software.md @@ -0,0 +1,212 @@ +--- +title: Bedrock Server Software +mentions: + - SirLich + - DevGod6969 + - NhanAZ + - SmokeyStack + - Joemanasdawd + - mdisprgrm + - Superice666 + - GreenFrogMCBE + - KanadeDev + - HUYDGD + - TheItsNameless + - hvlhx + - SmokeyStack + - ProtectorYT364 + - ThomasOrs + - lapismyt + - ModMaker101 + - Misledwater79 + - AzaleeX +--- + +Minecraft servers allow players to play online or via a local area network with other people. This is very common within Java Edition Minecraft, but is also possible on Bedrock. [You can download the official Mojang BDS software here.](https://www.minecraft.net/en-us/download/server/bedrock). + +Alongside the Vanilla BDS offering, many community projects exist, in a variety of languages. + +## Software by Language + +| Language | Status | +| ---------- | -------------------------------------------------------------------- | +| PHP | [Still Active](#php) : 4 < [Discontinued](#php-1) : 38 | +| Java | [Still Active](#java) : 4 < [Discontinued](#java-1) : 14 | +| C++ | [Still Active](#c) : 1 < [Discontinued](#c-1) : 5 | +| TypeScript | [Still Active](#typescript) : 4 < [Discontinued](#typescript-1) : 1 | +| Go | [Still Active](#go) : 1 < [Discontinued](#go-1) : 5 | +| JavaScript | [Still Active](#javascript) : 1 < [Discontinued](#javascript-1) : 6 | +| Rust | [Still Active](#rust) : 1 < [Discontinued](#rust-1) : 1 | +| C# | Still Active : 0 < [Discontinued](#c-2) : 3 | +| C | Still Active : 0 < [Discontinued](#c-3) : 1 | +| Python | [Still Active](#python) : 1 < [Discontinued](#python-1) : 2 | +| D | Still Active : 0 < [Discontinued](#d) : 1 | +| Kotlin | Still Active : 0 < [Discontinued](#kotlin) : 1 | + +## Active Software +### C++ + +- [LiteLoader](https://github.com/LiteLDev/LiteLoaderBDS) + +### Go + +- [DragonFly](https://github.com/df-mc/dragonfly) + +### Java + +- [JukeBoxMC](https://github.com/LucGamesYT/JukeboxMC) +- [NukkitX-version](https://github.com/NukkitX/Nukkit) +- [Nukkit PetteriM1 Edition](https://github.com/PetteriM1/NukkitPetteriM1Edition) +- [PowerNukkitX](https://github.com/PowerNukkitX/PowerNukkitX) + +### TypeScript + +- [BDSX](https://github.com/bdsx/bdsx) +- [JSPrismarine](https://github.com/JSPrismarine/JSPrismarine) +- [PowerAllay](https://github.com/PowerAllay/PowerAllay) +- [Serenity](https://github.com/SerenityJS) + +### JavaScript + +- [GreenFrogMCBE](https://github.com/GreenFrogMCBE/GreenFrogMCBE) + +### Rust + +- [Netrex](https://github.com/NetrexMC/Netrex) + +### PHP + +- [BetterAltay](https://github.com/Benedikt05/BetterAltay) +- [PocketMine-MP](https://github.com/pmmp/PocketMine-MP) +- [NetherGamesMC/PocketMine-MP](https://github.com/NetherGamesMC/PocketMine-MP) +- [Symply](https://github.com/SymplyX/Symply) +- [SynapseNet](https://github.com/DANIHEX/SynapseNet) + +### Python + +- [PieMC](https://github.com/PieMC-Dev/PieMC) + +## Discontinued Software + +### C++ + +- [AllayBE](https://github.com/AllayBE/AllayBE) +- [BedrockPowder](https://github.com/BedrockPowder/BedrockPowder) +- [Cenisys](https://github.com/iTXTech/Cenisys) +- [CenisysPro](https://github.com/GenisysPro/CenisysPro) +- [Element Zero](https://github.com/Element-0/ElementZero) + +### C# + +- [MiNET](https://github.com/NiclasOlofsson/MiNET) +- [NetherServ](https://github.com/protosleep/NetherServ) +- [Terac](https://github.com/TeracMC/Terac) + +### C + +- [Podrum](https://github.com/Podrum/Podrum) + +### D + +- [Selery](https://github.com/sel-project/selery) + +### Go + +- [GoMine](https://github.com/Irmine/GoMine) +- [Magic-Alpaca](https://github.com/PocketMiner92/Magic-Alpaca) +- [Rockit-LMS](https://github.com/cr0sh/Rockit-LMS) +- [Saddle](https://github.com/saddlemc/saddle) +- [SpecterGO](https://github.com/SpecterTeam/SpecterGO) + +### Java + +- [BukkitPE](https://github.com/BukkitPE/BukkitPE) +- [DiamondCore](https://github.com/DRAGKILLS/DiamondCore) +- [Dragonet](https://github.com/DragonetMC/Dragonet) +- [Dragonet-Legacy](https://github.com/DragonetMC/Dragonet-Legacy) +- [GoMint](https://github.com/GoMint/GoMint) +- [Jenisys3](https://github.com/FrontierDevs/Jenisys3) +- [MagmaBlock](https://github.com/PrismarineMC/MagmaBlock) +- [MCPEBukkit](https://github.com/MCPEBukkit/MCPEBukkit) +- [MineTurtle](https://github.com/MCPEBukkit/MineTurtle) +- [Nukkit](https://github.com/Nukkit/Nukkit) +- [PowerNukkit](https://github.com/PowerNukkit/PowerNukkit) +- [SpiderMine](https://github.com/QuantumWorks/SpiderMine) +- [Terracotta](https://github.com/TerracottaMC/Terracotta) +- [voxelwind](https://github.com/voxelwind/voxelwind) + + +### JavaScript + +- [BlueBird](https://github.com/BlueBirdMC/Server) +- [DirtServer](https://github.com/Falkirks/DirtServer) +- [MineJS](https://github.com/organization/MineJS) +- [NodeMine](https://github.com/NodeMine/NodeMine) +- [Numerous-alpaca](https://github.com/numerous-alpaca/numerous-alpaca) +- [PocketNode](https://github.com/PocketNode/PocketNode) + +### TypeScript + +- [LeafMCBE](https://github.com/LeafMCBE/LeafMCBE) + +### Kotlin + +- [Kookie](https://github.com/organization/Kookie) + +### PHP + +- [able-mp](https://github.com/AbleUnion/able-mp) +- [Altay](https://github.com/TuranicTeam/Altay) +- [AtmosPE](https://github.com/AtmosPE/AtmosPE) +- [BlueLight](https://github.com/BlueLightJapan/BlueLight) +- [ClearSky](https://github.com/ClearSkyTeam/ClearSky) +- [ClearSkyTeam/PocketMine-MP](https://github.com/ClearSkyTeam/PocketMine-MP) +- [CoreminePE](https://github.com/starfury1927/CoreminePE) +- [DevMine](https://github.com/MineCode-Devs/DevMine) +- [DragMine](https://github.com/DragMineTeam/DragMine) +- [DualNova](https://github.com/DualNova-Team/DualNova) +- [Elywing](https://github.com/H4PM/Elywing) +- [Elco-MP](https://github.com/elco-mp/Elco-MP) +- [Endako](https://github.com/LeronDoesGM/Endako) +- [EskoBE](https://github.com/MCPE357/EskoBE) +- [Extropy](https://github.com/ConflictPE/Extropy) +- [Freven](https://github.com/FrevenTeam/Freven) +- [FrontierEdge](https://github.com/FrontierDevs/FrontierEdge) +- [FuryMine](https://github.com/XFuryMCPE/FuryMine) +- [Genisys](https://github.com/iTXTech/Genisys) +- [GenisysPro](https://github.com/GenisysPro/GenisysPro) +- [Hydracon](https://github.com/E-DevPM/Hydracon) +- [ImagicalMine](https://github.com/ImagicalMine/ImagicalMine) +- [Leveryl](https://github.com/LeverylTeam/Leveryl) +- [LikeMP](https://github.com/LikeMP-BE/LikeMP) +- [LiteCore](https://github.com/LiteCoreTeam/LiteCore-public) +- [MechNetwork](https://github.com/MechRalph04/MechNetwork) +- [NekoMine-MP](https://github.com/Nekiechan/NekoMine-MP) +- [OpenTouch](https://github.com/pooooooon/OpenTouch) +- [ShadePE](https://github.com/ExplodingPE/ShadePE) +- [PocketMinePlusPlus-Legacy](https://github.com/PrismarineMC/PocketMinePlusPlus-Legacy) +- [Prismarine-0.12](https://github.com/PrismarineMC/Prismarine-0.12) +- [SkyLightPM](https://github.com/SkyLightMCPE/SkyLightPM) +- [StarrySky](https://github.com/StarrySky-PE/StarrySky) +- [Steadfast-Hybrid](https://github.com/yungtechboy1/Steadfast-Hybrid) +- [SteadFast2](https://github.com/Hydreon/Steadfast2) +- [T-STAR](https://github.com/TaleStar/T-STAR) +- [Turanic](https://github.com/TuranicTeam/Turanic) +- [WolfMC](https://github.com/Wolf-MC/WolfMC) + +### Python + +- [AlphaMC](https://github.com/Suppert/AlphaMC) +- [PodrumLegacy](https://github.com/Podrum/PodrumLegacy) + +### Rust + +- [Limonite](https://github.com/iTXTech/limonite) + +## Licensing + +:::tip License +This page is licensed under the `GNU Lesser General Public License v3.0`. + +The original source was authored `xinghao2003`, and may be [found here.](https://github.com/xinghao2003/MCBE-ServerSoftware-List) +::: diff --git a/docs/wiki/visuals/animated-entity-texture.md b/docs/wiki/visuals/animated-entity-texture.md new file mode 100644 index 00000000..ff951547 --- /dev/null +++ b/docs/wiki/visuals/animated-entity-texture.md @@ -0,0 +1,123 @@ +--- +title: Entity Texture Animations +mentions: + - MedicalJewel105 + - IlkinQafarov + - TheItsNameless + - SmokeyStack +tags: + - intermediate +category: + - Tutorials +--- + +## Whats on this page? + +From this page you will learn how to make an animated texture for an entity. Animated, like a flipbook texture for blocks. + +## Source + +This page is based on content by [AgentMindStorm](https://www.youtube.com/channel/UC-ljddYkFdTQl-MVEaVvbuQ). + + + +## Textures + +First let's draw some new texture frames for our entity. In this tutorial it will be a cow, which is looking around. + + + +We need to place our textures vertically, like for blocks in flipbook textures. +In this case we have 4 frames. + +## Materials + +We will need to modify materials in this guide. However due to render dragon materials became outdated, so **use it at your own risk**. + +To use animated texture, we need to change the entity material to one, that has `USE_UV_ANIM` property. +Let's simply add a new material: + +RP/materials/entity.material + +```json +{ + "materials":{ + "version":"1.0.0", + "custom_animated:entity":{ + "+defines":[ + "USE_UV_ANIM" + ] + } + } +} +``` + +Or you can add this to existing ones, check default material file. + + + +```json +"+defines":[ + "USE_UV_ANIM" +] +``` + +Download default entity.material file + +:::warning +It is not that easy for every entity! +Some entities have multiple materials and if you want to make its texture animated, you will need to add this property to all materials of this entity. +::: + +## Client Entity File + +Before we go next, we need to define a new material in our client entity file. + +RP/entity/cow.json#description + +```json +"materials": { + "default": "custom_animated" +} +``` + +## Render Controllers + +After that all, we need to edit a render controller. + +Here we will add `uv_anim` component with offset and scale properties: + +RP/render_controllers/cow.render_controllers.json#controller.render.cow + +```json +"uv_anim": { + "offset": [ 0.0, "math.mod(math.floor(q.life_time * frames_per_second),frame_count) / frame_count" ], + "scale": [ 1.0, "1 / frame_count" ] +} +``` + +Where `frames_per_second` is a count of frames you want to change in one second and `frame_count` is a total frame count. +This formula calculates the offset and the size of the texture depending on life time. + +## Testing + +Now, it is time to test your creation! + +![](/assets/images/visuals/animated-entity-texture/result.gif) + +## Download Example + +Download diff --git a/docs/wiki/visuals/animation-effects.md b/docs/wiki/visuals/animation-effects.md new file mode 100644 index 00000000..a6d2bc33 --- /dev/null +++ b/docs/wiki/visuals/animation-effects.md @@ -0,0 +1,181 @@ +--- +title: Effects in Animations +mentions: + - MedicalJewel105 +category: + - General +--- + +## Effects in Animations + +Sometimes it is much easier to use particles or sounds in animation rather than in animation controller. +Animations can have effects in them, such as: + +- Particles +- Sounds + +### Particles + +Minecraft Particles can be used in entity animations. For example, the phantom has an animation which emits the minecraft:phantom_trail particle constantly. Let's try to add a particle to our entity's attack animation. + +RP/entity/my_entity.json + +```json +"particle_effects": { + "flames": "minecraft:mobflame_emitter" +} +``` + +Here we defined a shortname for particle that we are going to use. + +You can find a list of particles [here](https://minecraft.wiki/w/Particles) or [here](/particles/vanilla-particles). + +:::warning Warning! +Not every particle works there. If you have problems, consider trying another particle. For example, use this one. +Also note that some particles emit constantly. +::: + +### Sounds + +If you want to use a sound, you need to define it too. + +RP/entity/my_entity.json + +```json +"sound_effects": { + "meow": "mob.cat.meow" +} +``` + +:::warning Warning! +Not every sound works there. If you have problems, consider trying another sound. For example, use this one. +::: + +## Adding Effects to Animation + +You can add particles or sounds to your animation mainly or in Blockbench. + +### Mainly + +You need to add the following to your animation: + +RP/animations/my_animation.json#my.animation + +```json +"particle_effects": { + "0.0": { + "effect": "flames", + "locator": "" //You need to add a locator in your model + } +} +``` + +RP/animations/my_animation.json#my.animation + +```json +"sound_effects": { + "0.0": { + "effect": "meow" + } +} +``` + +You can call more than one particle at the same time: + +```json +"particle_effects": { + "0.0": [ + { + "effect": "particle_1", + "locator": "locator_1" + }, + { + "effect": "particle_2", + "locator": "locator_2" + } + ] +} +``` + + + +RP/animations/my_animation.json + +```json +{ + "format_version" : "1.8.0", + "animations" : { + "animation.sheep.grazing" : { + "animation_length" : 2.0, + "loop" : true, + "particle_effects": { + "0.0": { + "effect": "flames", + "locator": "body" + } + }, + "sound_effects": { + "0.0": { + "effect": "meow" + } + }, + "bones" : { + "head" : { + "position" : { + "0" : [ 0.0, 0.0, 0.0 ], + "0.2" : [ 0.0, -9.0, 0.0 ], + "1.8" : [ 0.0, -9.0, 0.0 ], + "2" : [ 0.0, 0.0, 0.0 ] + }, + "rotation" : { + "0.2" : { + "post" : [ "180.0 * (0.2 + 0.07 * math.sin(q.key_frame_lerp_time * 1644.39))", 0.0, 0.0 ], + "pre" : [ 36.0, 0.0, 0.0 ] + }, + "1.8" : { + "post" : [ 36.0, 0.0, 0.0 ], + "pre" : [ "180.0 * (0.2 + 0.07 * math.sin(q.key_frame_lerp_time * 1644.39))", 0.0, 0.0 ] + } + } + } + } + } + } +} +``` + + + +### In Blockbench + +First let's add a locator for our particle. Go to "Edit" section, select a group, right-click and choose "Add Locator": + +![](/assets/images/visuals/animation-effects/add-locator.png) + +Rename it and move where you want. + +Then go to "Animate" section, choose an animation and click on a magic stick icon: + +![](/assets/images/visuals/animation-effects/add-effect.png) + +Now click "+" to open menu and specify the data: + +![](/assets/images/visuals/animation-effects/specify-data.png) + +You can attach a sound to animation the same way. + +Now save your animation and launch the game! + +![](/assets/images/visuals/animation-effects/showcase.png) + +## Offscreen Updating + +You can set `"should_update_bones_and_effects_offscreen"` to `true` inside entity rp scripts for particle and sound effects to update offscreen, by default both of them will stop playing if the entity isn't being rendered on display. + +RP/entity/my_entity.json#description + +```json +"scripts": { + "should_update_bones_and_effects_offscreen": true +} +``` diff --git a/docs/wiki/visuals/bedrock-modeling.md b/docs/wiki/visuals/bedrock-modeling.md new file mode 100644 index 00000000..723d9216 --- /dev/null +++ b/docs/wiki/visuals/bedrock-modeling.md @@ -0,0 +1,122 @@ +--- +title: Bedrock Modeling +nav_order: 2 +category: + - General +mentions: + - SirLich + - solvedDev + - MedicalJewel105 +--- + +This will guide tips, tricks, and things you should know when modeling for Minecraft Bedrock Edition. + +## Texture Glitch + +Sometimes the texture on some (smaller) faces is glitched or invisible. This is because the size of cubes is floored for the UV map calculation. This means that any size smaller than 1 will result in a 0 pixel wide UV map, which will look glitchy. To prevent this, make sure all of your cubes are at least 1 unit long in each direction. To create smaller cubes, use the Inflate slider. +Another trick to solve this if you _must_ have smaller textures is by **increasing the element size by 1 in each direction** and then **inflating the element by -1** though note that this will make you have smaller pixels textured incorrectly will lead to mixels. + +## Vertex Snap + +Vertex snap is a handy tool in blockbench any modeler should use. It's beneficial when doing rounded things like wheels. +You can find this tool right top next to the movement & scale tools. It has 2 modes, Move & Scale. How this tool works can be seen in the following gif. +![](/assets/images/visuals/bedrock-modeling/vertex_snap.gif) +## Transparency + +If you use semi-transparent textures (like colored glass), you need to move elements with that texture to the bottom of the element list. Otherwise, elements behind these semi-transparent ones won't render in-game. + +## Texturing + +When learning to texture, your best bet is practicing with references on how others textured similar objects & surfaces. Patterns for wood & metal are different, and you should consider that. Good guides are +[Masteriano's Texturing Tips](https://www.blockbench.net/wiki/guides/minecraft-style-guide) +and in general, any on pixel art. + +## Materials + +Whether or no the transparency or emissive textures in your models work in-game, it's decided by the materials applied to them. + +| Material | Description | +| --------------------- | -------------------------------------------------------------------------------------------------------- | +| entity | basic opaque material | +| entity_alphatest | supports transparent pixels | +| entity_alphablend | supports translucent pixels | +| entity_emissive | solid, alpha channel is used as the emissive channel | +| entity_emissive_alpha | alpha channel is used for emissiveness, completely black + transparent pixels are rendered transparently | + +## Z-fighting + +Z-fighting is called when you have the face of 2 elements in the same place, and you can see both or half of them at the same time, as seen in the following picture. +![](/assets/images/visuals/bedrock-modeling/z-fighting.png) +You can solve this by inflating one of them by `0.01` or `-0.01` depending on which one should prioritize. + +## Basics of Animations + +When animating in Blockbench, you can set each keyframe by hand, or you can use variables & functions. +Here you will learn the basics. +Let's start with this picture. + +![](/assets/images/visuals/bedrock-modeling/animations-1.png) + +the name or `animation.cuack` is essential. You can't have symbols or caps there, and it must start with `animation.` for the animations to work without problems. Now the function we will be using is + +`Base + Math.sin((q.life_time + Offset) * Speed) \_ pitch` + +- Base is the starting rotation/position the bone has +- Sin is the math function we all know +- `q.life_time` is a variable. Is a number that will be increasing as the animation continues +- Offset is a number we use to have the animation start earlier or later than its "original" position +- Speed is the time it will take from going from top to down +- Pitch is how far it goes from the origin + +![](/assets/images/visuals/bedrock-modeling/animations-2.gif) + +Function used: + +`Math.sin((q.life_time+0.5)*150)*15` + +one on position & the other on rotation. + + + +Don't forget that for the animation to be a perfect loop. It would help if you correlated the sin equation `speed` & the animation `time`. +Here's a table with values to get a perfect loop, though there are more you can discover. + +| Speed | Time | Group | +| ----- | ---- | ----- | +| 150 | 2.4 | 1 | +| 100 | 3.6 | 2 | + +These numbers can be multiplied but not divided, so these will also work +But only multiples of the same option + +| Speed | Time | Group | +| ----- | ---- | ----- | +| 150 | 4.8 | 1 | +| 200 | 3.6 | 2 | +| 300 | 2.4 | 1 | +| 300 | 3.6 | 1 & 2 | + +Now not all of these will "loop" together. And that is the Group column. The ones with the same number will work together. Otherwise, they will have a visible "glitch" in the loop. + +:::tip +You can have an animation in the loop by clicking on the following setting: +![](/assets/images/visuals/bedrock-modeling/setting-loop.png) +::: + +With this function & creativity, animals & dinosaurs are animated into walking, running & attacking. +You can learn more about queries & functions [here](https://bedrock.dev/docs/stable/Molang). + +## Animation Speed + +To easily change the speed of an animation you can simply multiply the default value of `anim_time_update` (defaults to `q.delta_time + q.anim_time`) inside our animation: + +RP/animations/myentity.animation.json#animations + +```json +"animation.myentity.myanimation": { + "anim_time_update":"2 * q.delta_time + q.anim_time" + //Your animation goes here! +} +``` + +This will make the animation run 2 times faster. We can tweak the value to any buoyant float, so we can even slow down animations. With 0.5, for example, the animation will run 2 times slower, etc. \ No newline at end of file diff --git a/docs/wiki/visuals/custom-skin-packs.md b/docs/wiki/visuals/custom-skin-packs.md new file mode 100644 index 00000000..a094d0a6 --- /dev/null +++ b/docs/wiki/visuals/custom-skin-packs.md @@ -0,0 +1,137 @@ +--- +title: Skin Packs +mentions: + - MedicalJewel105 + - SirLich + - Joelant05 + - TheItsNameless +category: + - General +--- + +Many people wrongly assume that skin packs are only available for creation to Marketplace Partners. No! It's a very easy process, which can easily be fully automated by python. But that's not it. Let's learn how to make a skin pack! + +:::warning +The `development_skin_packs` doesn't seem to function correctly. You need to use `skin_packs` folder and reload Minecraft every time you made a change. +::: + +## What is needed + +Here is what is needed: + + + +## manifest.json + +skin_packs/tutorial_skin_pack/manifest.json + +```json +{ + "format_version": 2, + "header": { + "name": "Tutorial Skin Pack", + "uuid": "bb9616eb-327c-4a81-9f00-064cae820cd5", + "version": [ + 1, + 0, + 0 + ] + }, + "modules": [ + { + "type": "skin_pack", + "uuid": "e4bc71b6-8f9b-4094-9d47-dc3824f8a3dc", + "version": [ + 1, + 0, + 0 + ] + } + ] +} +``` + +- `format_version` can be 1 too, as v2 doesn't change much for skin packs. +- `name` is self explanatory. However, it isn't of great importance. +- `uuid` and `version` are already familiar to us. Both UUIDs in the manifest need to be different. You can generate them via a generator linked in [useful links](/meta/useful-links). As a reminder, you CANNOT use the same UUID TWICE. +- `type` in `modules` needs to be set to `skin_pack`, of course. + +## skins.json + +This file is used to define textures and shortnames for skins. Most of the options are, however, hard-coded or unchangeable. + +skin_packs/tutorial_skin_pack/skins.json + +```json +{ + "geometry": "geometry.json", + "serialize_name": "Tutorial Skin Pack", + "localization_name": "tutorial", + "skins": [ + { + "localization_name": "tutorial_skin_1", + "geometry": "geometry.humanoid.custom", + "texture": "goggled_gecko_no_goggles.png", + "type": "free" + }, + { + "localization_name": "tutorial_skin_2", + "geometry": "geometry.humanoid.customSlim", + "texture": "goggled_gecko.png", + "type": "free" + } + ] +} +``` + +- The `geometry` object must be the same as on the example code in every object. Mojang removed the ability to add custom geometries via skin packs, because the feature was abused. +- `serialize_name` is for marketplace. +- `localization_name` is a pack identifier. **Don't use in other skin packs** as it affects translations. +- `skins` array, where you define your each skin. The skins will be displayed in the same order in minecraft as they are defined here. + > - `localization_name` is going to be used in the .lang file. Think of it as the skins identifier. + > - `geometry` you can use `geometry.humanoid.custom` and `geometry.humanoid.customSlim` here. + > - `texture` is the name of the image file, located in the main skin pack folder. + > - `type` is only accessible to marketplace partners, leave it as `free`, otherwise it will be locked. + +## texts/en_US.lang + +Finally, we'll define the names of the skin pack and every skin in the `.lang` file. Of course "en_US" can be replaced with any language. + +skin_packs/tutorial_skin_pack/texts/en_US.lang + +``` +skinpack.tutorial=Tutorial Skin Pack + +skin.tutorial.tutorial_skin_1=Skin 1 +skin.tutorial.tutorial_skin_2=Skin 2 +``` + +The first line defines the pack's name itself. It's done in this format: + +`skinpack.[pack localization_name]=Actual Pack Name` + +The other lines define the skins' names: + +`skin.[pack localization_name].[skin localization_name]=Actual Skin Name` + +Done! Now, when you open Character Creator, you'll see your skins available to be chosen! + +## Troubleshooting + +If you play on MC version lower than 1.18.30, you might experience a bug when "Equip" button is not showing. You need to download a special texture pack. + +![](/assets/images/visuals/skin-packs/troubleshooting-1.png) + +Download Equip Button Fix + +![](/assets/images/visuals/skin-packs/troubleshooting-2.png) diff --git a/docs/wiki/visuals/death-animations.md b/docs/wiki/visuals/death-animations.md new file mode 100644 index 00000000..24cf9a9e --- /dev/null +++ b/docs/wiki/visuals/death-animations.md @@ -0,0 +1,390 @@ +--- +title: Custom Death Animations +tags: + - intermediate +category: + - General +mentions: + - SirLich + - Joelant05 + - Dreamedc2015 + - MedicalJewel105 + - aexer0e + - Xterionix + - ChibiMango + - SmokeyStack + - ThomasOrs +--- + +Death animation refers to the rotation of the entity as it dies. This is accompanied by a red coloring and followed shortly after by the disappearance of the entity geometry and the appearance of the death particles. + +## Cancelling Death Animations + +This part will explain how to remove death animations at all. + +### Teleporting the Entity + +A fairly common way to remove entities without causing death effects is to teleport them into the void. This can be done from animation controllers by using `!q.is_alive` like: +`/teleport @s ~ ~-1000 ~` + +Please note that this will remove all death effects, including sound, particles, loot, and the visual death of the entity. + +### minecraft:instant_despawn + +If you want to make entity just disappear, you can add component group with `"minecraft:instant_despawn":{}` and run an event which will add this component group. + +Please note that this will remove all death effects, including sound, particles, loot, and the visual death of the entity. + +### Transformation to another entity + +Similar to teleporting, the entity is triggering an entity transform on death. Use `!q.is_alive` in animation controller to send an event which will add component group with `"minecraft:transformation"` component. With this component entity will convert into another: + + + +```json +"minecraft:transformation": { + "into": "wiki:death_animation_entity", + "transformation_sound" : "converted_to_zombified", + "keep_level": true, + "drop_inventory": true, + "preserve_equipment": false, + "drop_equipment": true, + "delay": { + "block_assist_chance": 0.0, + "block_radius": 0, + "block_max": 0, + "value": 10 + } +} +``` + +### Cancelling the Animation + +We can also cancel the rotational value of the entity, allowing the entity to die more conventionally (particles, red-coloring, loot) without the 90-degree spin. + +If you need more information about triggering animations from entity death, see [this document](/animation-controllers/death-commands) on death effects. + +Rotation needs to be applied to a bone parent to all other bones, with a pivot at [0,0,0], and the animation should only start when `!q.is_alive`. + +Animation: + + + +```json +"rotation" : [ 0, 0, "Math.min(Math.sqrt(Math.max(0, q.anim_time * 20 - 0.5) / 20 * 1.6), 1) * -90" ] +``` + +Animation Controller: + +(q.all_animations_finished is only needed for respawning entities, like players) + +RP/animation_controllers/custom_death.animation.controllers.json + +```json +{ + "format_version": "1.10.0", + "animation_controllers": { + "controller.animation.player.cancel_death_animaton": { + "initial_state": "default", + "states": { + "default": { + "transitions": [ + { + "cancel_animation": "!q.is_alive" + } + ] + }, + "cancel_animation": { + "animations": ["my.animation"], + "transitions": [ + { + "default": "q.is_alive && q.all_animations_finished" + } + ] + } + } + } + } +} +``` + +Note that you will need attach animation and animations controller in `.entity.json` file of resource pack. + +## Custom Death Animations + +This part will explain how to customize death animation. + +### Changing Damage Color Overlay + +You can remove/customize entity damage color overlay. + +Before starting, you must have the basics of render controller so check out the [tutorial](/entities/render-controllers) of render controllers. + +To remove the damage overlay color of any entity you want when it gets damaged, we will use `is_hurt_color` and remove the damage overlay color when an entity receives damage from lava or fire use `on_fire_color`. +First, you need to make the rgba values to 0 +Here's the example of removing the damage and fire overlay color. + +RP/render_controllers/custom_death.render_controllers.json + +```json +{ + "format_version": "1.8.0", + "render_controllers": { + "controller.render.sample": { + "geometry": "Geometry.default", + "materials": [{ "*": "Material.default" }], + "textures": ["Texture.default"], + "is_hurt_color": {}, + "on_fire_color": {} + } + } +} +``` + +The code above will remove the red damage overlay color. + +You can also change the damage color overlay to different colors just by putting different values in rgba. You can check out various websites to get the rgba values of all colors. +Here's another example in which the damage color overlay becomes pink. + +RP/render_controllers/custom_death.render_controllers.json + +```json +{ + "format_version": "1.8.0", + "render_controllers": { + "controller.render.kbg": { + "geometry": "Geometry.default", + "materials": [{ "*": "Material.default" }], + "textures": ["Texture.default"], + "is_hurt_color": { + "r": "1.0", + "g": "0.4", + "b": "0.7", + "a": "0.5" + }, + "on_fire_color": { + "r": "1.0", + "g": "0.4", + "b": "0.7", + "a": "0.5" + } + } + } +} +``` + +### Using Damage Sensor to Trigger Instant Despawn and One Item Drop + +You can use the damage_sensor component to trigger an event upon fatal damage; this event adds a particular despawning component group containing the spawn_entity and instant_despawn components. Spawn_entity with 0 wait time will drop an item just before the entity is despawned. For simple entities like furniture, which only need one item, this is very convenient. + +When an entity recieves fatal damage, an event is triggered that adds a dummy component. We can then use this dummy component to play the animation and using `minecraft:timer` we can have it despawn. + +Please note that you will have to find another work for entities with an inventory. You should also ensure that the despawn component group is not added when the entity is spawned using the entity_spawned event. If you have a entity that performs other actions (movement and attacks) you will likely want to remove those components as well. + +Here an example file in the BP + +BP/entities/entity.json + +```json +{ + "format_version":"1.14.0", + "min_engine_version":"1.16.100", + "minecraft:entity":{ + "description":{ + "identifier":"wiki:entity", + "is_spawnable":true, + "is_summonable":true, + "is_experimental":true + }, + "component_groups":{ + "wiki:death":{ + "minecraft:spawn_entity":{ + "max_wait_time":0, + "min_wait_time":0, + "spawn_item":"egg", + "single_use":true + }, + "minecraft:is_sheared":{}, + "minecraft:timer":{ + "looping":true, + "time":[ + 2.56, + 2.56 + ], // Change this to match your animation's time + "time_down_event":{ + "event":"wiki:despawn" + } + } + }, + "wiki:despawn":{ + "minecraft:instant_despawn":{} + } + }, + "components":{ + "minecraft:type_family":{ + "family":[ + "cart", + "inanimate" + ] + }, + "minecraft:collision_box":{ + "width":0.8, + "height":0.5 + }, + "minecraft:health":{ + "value":8, + "max":8 + }, + "minecraft:physics":{}, + "minecraft:pushable":{ + "is_pushable":true, + "is_pushable_by_piston":true + }, + "minecraft:damage_sensor":{ + "triggers":{ + "on_damage":{ + "filters":{ + "all_of":[ + { + "test":"has_damage", + "value":"fatal" + } + ] + }, + "target":"self", + "event":"wiki:death", + "deals_damage":false, + "cause":"fatal" + } + } + } + }, + "events":{ + "wiki:death":{ + "add":{ + "component_groups":[ + "wiki:death" + ] + }, + "wiki:despawn":{ + "add":{ + "component_groups":[ + "wiki:despawn" + ] + } + } + } + } + } +} +``` + +Here an example file for the animation controller. + +RP/animation_controllers/animation_controller.entity.json + +```json +{ + "format_version": "1.10.0", + "animation_controllers": { + "controller.animation.entity": { + "states": { + "default": { + "blend_transition": 0.2, + "transitions": [ + { + "dead": "q.is_sheared" + } + ] + }, + "death": { + "blend_transition": 0.2, + "animations": [ + "death" + ] + } + } + } + } +} +``` + +Note: You can also spawn custom spawn egg items using the `minecraft:spawn_entity` component by setting `"spawn_item"` +to be your entity's id and an affix of `spawn_egg`, and it will look something like this. + +BP/entities/my_entity.json#components + +```json +{ + "minecraft:spawn_entity": [ + { + "min_wait_time": 0, + "max_wait_time": 0, + "spawn_item": "wiki:custom_zombie_spawn_egg", + "single_use": true + } + ] +} +``` + +If you want to drop a loot table, you can trigger an event (as shown below) and summon another entity that have this component: + + + +```json +{ + "minecraft:behavior.drop_item_for":{ + "seconds_before_pickup":0.0, + "cooldown":5, + "drop_item_chance":1, + "offering_distance":0.0, + "minimum_teleport_distance":1024.0, + "target_range":[ + 64.0, + 64.0, + 64.0 + ], + "teleport_offset":[ + 0.0, + 1.0, + 0.0 + ], + "speed_multiplier":1.0, + "search_range":64, + "search_height":64, + "search_count":0, + "goal_radius":64.0, + "entity_types":[ + { + "filters":{ + "test":"is_family", + "subject":"other", + "value":"player" + }, + "max_dist":64 + } + ], + "priority":1, + "loot_table":"loot_tables/entities/example.loot_table.json", + "time_of_day_range":[ + 0.0, + 1.0 + ] + }, + "minecraft:timer": { + "time": 2, + "time_down_event": { + "event": "wiki:my_despawn_event" + } + } +} +``` + +And then despawn it through adding component group with instant_despawn through `wiki:my_despawn_event`. + +### Detecting Death with Commands + +View \ No newline at end of file diff --git a/docs/wiki/visuals/deferred-qna.md b/docs/wiki/visuals/deferred-qna.md new file mode 100644 index 00000000..54a827f2 --- /dev/null +++ b/docs/wiki/visuals/deferred-qna.md @@ -0,0 +1,248 @@ +--- +title: Deferred Technical Preview Q&A 2024/02/23 +mentions: + - SmokeyStack +--- + +This Q&A took place in the [Bedrock Add-Ons discord](https://discord.gg/uZF75ZxcJq). Six Mojang/Microsoft employees joined us to answer questions about the Deferred Technical Preview API. Questions were community sourced. + +:::warning +Not all messages were copied over, and some were copy-edited. If you want to see everything, join the above discord, and get the "events archive" role. +::: + +## How Long Has the Deferred Rendering Pipeline Been in Development + +- **Q**: How long has the Deferred Rendering Pipeline been in development? What were the challenges in making this pipeline? +- **A**: The Deferred pipeline has been in development in various forms since 2020. Parts of it were born out of optimizations to the RTX pipeline but other parts were born out of the pipeline used for Minecraft Legends. Development started in earnest in March of 2022. + +## Supported Platforms + +- **Q**: Will any platforms not be supported? +- **A**: There's no official announcements right now on what will or will not be supported. As mentioned in another thread, we aim to make deferred as widely available as possible on devices that can support it, but ensure that the visuals and perf are where they should be for a good playing experience. + +- **Q**: I solely play Minecraft on my phone and ray tracing, shaders, etc look so cool! But I have never been able to experience them 😞 Will deferred lighting be available for Android devices? +- **A**: Yes! The deferred preview is currently available on Android and can be accessed as part of the Beta program. Also available in Preview on Xbox, iOS, and PC! + +- **Q**: Is deferred available on chrome book? +- **A**: We don't have any news to share on when new platforms will be available right now, but we are definitely testing and looking into adding additional platforms that can handle deferred. We want to make sure as many players as possible can experience the new graphics mode but also that the playing experience will be solid. + +## Molang in Deferred Rendering + +- **Q**: Please add the ability to use Molang queries in global.json or any other files! It would be useful for detecting specific moon phases and create local/unique experiences! +- **A**: Appreciate the suggestion, but we don't have any news to share on Molang integration right now. We have quite a few constraints with perf and other things that we have to be mindful of with deferred. + +## Features Left + +- **Q**: How many features are left for deferred? +- **A**: There's some hints across the other threads, but I'll make a cheat sheet here 🙂 + Right now, in the works to share with you we have: Color grading, Water lighting + movement, Subsurface scattering, Reflections, and Texture Set support for Items and particles. + +## Optimization + +- **Q**: I wonder when optimization for deferred will begin aajabrams said it would be when y’all get all of deferreds features implemented but idk when that is. +- **A**: AJ is right, we're definitely working on getting all the features out before really hammering at optimizations. No timeline to share right now, but definitely on our roadmap! + +## Pom Effects + +- **Q**: Will Pom Effects Such As Paralax Be Added? +- **A**: We don't have anything to share on POM techniques at this time, but thank you for the suggestion! + +## Deferred PBR + +- **Q**: Can you expand deferred PBR capabilities with e.g. subsurface scattering, porosity, POM/tessellation, etc.? +- **A**: Been answered in a few places already, mostly here: https://discord.com/channels/523663022053392405/1209533667224068188/1210658737103048805 +- **A**: Yes! We will be expanding the current model to include a Sub Surface Scattering approximation, and we will also be enabling a unique lighting model for water geometry. Water will operate on properties like how much algae is present. + +- **Q**: "unique lighting model for water geometry" what about POM/tessellation for blocks? +- **A**: We don't have any plans regarding POM/tessellation to share at this time. Thank you for the suggestion, though! + +## Super Duper Graphics Pack Cancellation + +- **Q**: Why was the super duper graphics package canceled? +- **A**: This [link](https://www.minecraft.net/en-us/article/super-duper-graphics-pack-ceasing-development) is probably still the best info for what happened with SDGP. + +## Data Driven Renderer Folder + +- **Q**: Will the renderer folder be exposed for us to use in resource packs? Doing so will allow many unique packs and configs for creators to experiment with. +- **A**: Not the renderer folder itself, but there will be more data-driving capabilities that we expose to resource packs over time, yes. + +## Weirdest Bugs + +- **Q**: What is the weirdest rendering bug you have seen while developing the Deferred Rendering Pipeline? +- **A**: Early experiments with indirect specular ended up lighting the whole scene! ![](/assets/images/visuals/deferred-qna/deferred-qna-media1.gif) +- **A**: We also see NaNs that get seeded and sometimes spread through the world. Don't divide by zero, friends. 😉 ![](/assets/images/visuals/deferred-qna/deferred-qna-media2.png) +- **A**: Who's that ~~Pokemon~~ Minecraft mob? ![](/assets/images/visuals/deferred-qna/deferred-qna-media3.png) +- **A**: No screenshot, but another was when we had phantom shadows from mobs on the other side of the world! At first we thought they were mobs with invisibility status and their shadow just needed to be hidden, but the corresponding mob was sometimes 1000s of blocks away with no invisibility! Ended up being a transform-inversion issue. That was a fun one to track down. + +## Light Contrast and Saturation For the Sun/Moon and Pointlight + +- **Q**: Will deferred ever see the likes of contrast and/or saturation control for all lights? For example increasing the contrast and/or saturation for colors from the sun/moon to have more bright and/or a somewhat vibrant color, or increasing Saturation for colors to standout. + + I have noticed that colors from the sun is quite dull, and not even changing the tone-mapper helps a bit. +- **A**: Not per light source, but, like Veka mentioned, we will be doing it on the full scene as part of tonemapping. And why stop at contrast and saturation? We are working on a full HDR color grading suite, complete with contrast, saturation, gain, offset and split-tone grading. This feature will be data-drivable in your resource packs. + +## Focus Parameter + +- **Q**: Will a focus mode be added to the Object ? +- **A**: We don't have anything to share regarding focus or other camera-related properties at this time. Thank you for the suggestion! + +## Customizable Clouds + +- **Q**: As of right now, Clouds are not really customizeable for deferred, is there plans to add volumetric Clouds. +- **A**: No plans on clouds to share right now, but appreciate the suggestion here! Definitely lots to explore here. + +- **Q**: Will deferred have a multiple clouds layers like SDGP as config? that's feels more like aesthetic things that might gonna fit well with some packs. +- **A**: Thanks for the suggestion! Nothing to share right now on clouds + +## Any Plans for Deferred to be Scriptable + +- **Q**: When client side apis come out, are their any plans to add a api for deferred to allow us to manipulate it through scripting? +- **A**: The answer to this is similar to our Molang response: https://discord.com/channels/523663022053392405/1209532356403142656 + + > Appreciate the suggestion, but we don't have any news to share on Molang integration right now. We have quite a few constraints with perf and other things that we have to be mindful of with deferred. + +## Global Illumination + +- **Q**: Are there any plans for implementing some form of global illumination? Something for more accurate skylight, reflected sunlight or ambient blocklight. Perhaps you already have a specific technique in mind? 👀 +- **A**: Global Illumination is such a broad topic, so technically the answer is, yes! More specifically, we are working on adding reflections, both IBL-based and screen-space. We have discussed many other forms of GI internally, but don't have anything to share on other applications at this time. + +## Is the graphical team fully dedicated to the DRP? + +- **Q**: This is an indirect way to ask if we can finally have some non-official confirmation that a certain other graphical system we have explicitly asked not to talk about in <#1208794326361055324> is not being worked on at all by the team. + + Actually also curious what percentage of the graphics team is dedicated to the DRP knowing that there are at the same time a fair number of graphical bugs, quirks and optimizations to be had in the base RenderDragon. +- **A**: No. The graphics team owns initiatives like DTP, but also is responsible for maintaining the RenderDragon engine as well as the rendering of the core game. We do have a dedicated group of engineers within the graphics team that is fully dedicated to the DTP however. + +## Accurate Sky Model + +- **Q**: As of right now , deferred uses vanilla style sky model which stitches the moon and sun sky semi globes together which is fine for vanilla but looks unappealing in deferred and causes issues when stitching the sky in deferred. + Are there any plans you have in mind to deal with it? +- **A**: Thanks for the feedback! There are definitely some visual bugs and enhancements to the sky we've got to buff out. 🙂 + +## Unique Techniques and Features + +- **Q**: Were there any graphical techniques developed in-house rather than relying on existing solutions? For example, deferred atmosphere seems quite unique, was it created from scratch or is it an implementation of already existing model? +- **A**: Many of the techniques we've employed are derived from whitepapers and talks presented at various technical conventions (like Siggraph, GDC, etc.), so nothing we've done is technically truly novel (this is usually the case for Graphics development in the game industry in general). + + That said, we've put a Minecraft specific slant on many of the techniques employed to ensure parity with Vanilla lighting (e.g. light falls off in a similar way, some visual emphasis on "blockiness", scenes that are dark in Vanilla lighting look dark in Deferred lighting too, etc.) + + There are also opportunities for novel approaches (like lighting in the nether/end dimensions) but at this time we don't have any additional information we can share. + +## Deferred Upscaling + +- **Q**: Could you implement other optional upscaling techniques (like AMD FSR or Intel XeSS) and sharpness slider like many games that implement upscaling +- **A**: Thanks for the suggestion, it could be valuable for performance. We'll be taking this into consideration! + +## Better Water + +- **Q**: Deferred now still uses the default water from the initial release in the preview and there are only a few changes, so will there be additional features such as screenspace reflection, caustic, waves and underwater effects which are much better than before? +- **A**: Yes! We are definitely working on updating the water lighting model and other effects in deferred. These are some great suggestions, and would love to hear more about what other effects and control you'd like to have with water in the deferred preview! +** A**: These are all great ideas for water improvement! I'm happy to say that many of these are already on our roadmap: caustics, noise, volumetric rays, reflections, refractions. + +- **Q**: I know I'm asking a lot, but you might consider adding snell's window? +- **A**: Yes. 😉 + +## Will We See Items Getting Material Support? + +- **Q**: Items are now the last *major* thing to not receive any official PBR support in deferred. It is still *possible* to give items PBR capabilities with some workarounds (ex: attachables, as well as tools like MIAM1 ), but I’m curious if it stay that way, or if there is a plan to eventually give items these PBR features. +- **A**: Yes! This is something we are working on. And don't forget about Particles! Those will be getting PBR support as well, likely sooner than Items. + +## Enable/disable Deferred Graphics Options For Each Packs? + +- **Q**: I would like to ask wether there is any plan to add support for the toggle that is enabling and disabling deferred-graphics for each packs. + Since shader packs are too heavy for some devices, I thought it would be wonderful if there were such option for each packs. +- **A**: Deferred graphics resource packs will stack like any other resource pack with the pack being higher on the stack overriding the properties of the pack below it. Your description of pack overriding behavior sounds right! + +## Are There Any Plans To Fix Volumetric Fogs That Use Height Rather Than Uniformity From Blinding You? + +- **Q**: To add more context. When you set up a fog and it uses the height parameters rather than being uniform, their thickness goes to the maximum upon entering the biome then fades into the proper height the further in you go. Is this intentional or a bug? +- **A**: Interpolation at biome transitions aren't the most polished right now (what you're describing is likely a bug). We'll be working on more polished transitions closer to final release! + +## Entities: Spot/Point lights + +- **Q**: Are entities planned to be involved? such as conditionally shining flashlights from players, glowing mobs, etc. + (I just imagine a lethal company style flashlight through fog in minecraft and get excited lol) +- **A**: No, we do not have plans to include spot lights or attachable lights to entities at this point in time. Thank you for your suggestion! + +## How Customizable Will Deferred Be On Release? + +- **Q**: Seeing that there are **a lot** of configs for deferred inside the game’s files, will we be able to edit those fully through resource packs in the future? +Something else I was wondering is if we will get more customizations in the future (for example: More lighting Config, Renderer Config, etc). +- **A**: While we won't end up exposing everything, we are still looking into expanding some of the data-driving to give Creators additional control. What are some of the specific configurations that you would like to see exposed that would give you the most additional creative control? + +## Reloading Resource Packs +- **Q**: Will there ever be a F3+T feature in bedrock edition? i feel like the ability to reload resource packs without leaving the world should be added to bedrock edition, it's already in java from the start but never made it to bedrock. +- **A**: We definitely know that reloading resource packs is a pain. Not a great development flow. We want to do things here to make this easier, but nothing really to announce today. And this sort of thing is pretty gnarly to work on. + +- **Q**: What about `/reload all` in Editor mode? (I'm not even sure if that's related in any way.) +- **A**: Yeah we have some tech that can reload some things, but not all things. And yeah, you're on the right line of thinking that if we do light up these features, Editor would be the safest place for us to do it. + +## Identifier-Based Configuration + +- **Q**: More of a feature request with the "Are there any plans to…" prefix, but identifier-based configurations would be quite useful. There are times when I want to change lighting configurations based on gameplay. Some command or something to switch configurations would be needed. Maybe scripting only. + + Directional lights especially come to mind as something I'd like to change due to world events. Maybe a "world destroyer" boss should change the very way that light is cast in the Overworld. As an example of these identifier-based files: + + ```json + { + "format_version": "1.20.80", + + "minecraft:directional_lights": { + "description": {"identifier": "bao:world_destroyer_event"}, + + "sun": {}, + "moon": {} + } + } + ``` + + And then something like: + + ```swift + /renderer lighting set bao:world_destroyer_event + ``` + + Essentially, this would be using the same kind of ideas as fogs, wherein it isn't enough to just map them to biomes. They need to be freestanding for application when appropriate. +- **A**: Yes! This is something we are working on and will be enabling in both our lighting and atmospherics JSONs. The identification will be very similar to how Fog is identified. Creators should expect that when this change comes out, that they will have to update their current PBR packs to make use of the identifiers as it will be a breaking schema change. Though it will be straight forward and we will provide guidance on how to do it. + +## Dimension Based Config + +- **Q**: Similar to , I think it would be cool if blocks could have 3 pbr textures and config, one for each dimension. This would help enhance each dimension to be unique. + + Having point light emit different colours based on dimension as one example + + This is similar to my Molang post, but currently there is no molang query to detect dimension as far as I know +- **A**: We're currently working on being able to provide unique configurations per biome and I believe these will allow you to configure properties unique to other dimensions like the nether or the end dimensions. + + We're still exploring how lighting will work in other dimensions with a big focus on the overworld presently! +- **A**: And as we also look at custom biomes and custom dimensions (no timeline or promises, just things on the list) we will also consider how deferred graphics will be utilized by these creator things. + +## Vanilla PBR + +- **Q**: Is Mojang planning on releasing PBRs for the *massive* collection of textures in this game? Getting started with PBR as a "technical artist" without just ripping PBRs with someone else's pack sucks if not just because of the sheer volume. + + (This is not a request for vanilla features. I figured the team had some internal pack they use for testing when in deferred. So I'm more asking for this as a developer resource.) +- **A**: Unfortunately we don't have any plans to share a PBR resource pack anytime soon for testing, I hear your feedback though and apologize it's not so easy to test right now. +You can however set default values for all blocks and entities that don't have a specific texture set in the global lighting file, which may help in some scenarios! + +## Preview Atmosphere in Real Time + +- **Q**: Currently, as a creator, when authoring atmosphere config there is no way to preview changes in real time. The workflow is: edit json -> reload the world -> observe changes. This process is quite annoying, as you don't see the changes instantly - it makes it harder to know how json changes translate to atmosphere visuals, as well as makes the iteration process take much longer than necessary. + + It would've been better if we could preview how different json configs and values affect atmosphere look in real time. Are there any plans (that you can share) that address this issue? E.g. some kind of in-game atmosphere editor or a plugin for <#1084090299120373760>? Or even an official (or not) standalone tool/webapp similar to blockbench or snowstorm. And if someone like me wanted to make such tool, what are the conditions or requirements for that, specific license to use for Bedrock's shader code? +- **A**: Yes, we hear you and feel your pain. 🙏 We do intend to integrate the Deferred Technical Preview more with the Bedrock Editor so that creators can more easily customize their packs and see changes in real-time. + +## Trailer + +- **Q**: Will deferred be getting a trailer anytime soon? +- **A**: Good question! It's still too early to think about marketing materials. Right now our focus is just building these features and getting feedback from you all! But I'd love to see community made trailers, hint hint! 😄 +- **A**: I frequently search YouTube for videos of the latest updates and community packs! Also all the tutorials that help others get the deferred preview on their own devices too 🙂 + +## Increases to Keyframe Periods + +- **Q**: Any plans to customize keyframes *across days*? (I'm hoping this didn't change since the last time I tested it.) I'd noticed before I was limited with keyframes to a single looping day. I was hoping I could vary directional lights by moon phases and was disappointed when I couldn't. + + I figured that the period could automatically be adjusted based on the largest resolved time key in the keyframe object. For example, `7.5` would cause a period of 8 days, with *all* of the listed times for that one keyframe object adhering to that period. + + Essentially, this would be not too dissimilar to how an animation automatically sets its total duration by looking at the largest given timeline value. Except these will be rounded up to a full day. +- **A**: Unfortunately we don't have plans to expand keyframing outside of a single day in the near to mid term. But that idea around moon phases is super awesome, something I hadn't thought of yet! diff --git a/docs/wiki/visuals/glowing-texture.md b/docs/wiki/visuals/glowing-texture.md new file mode 100644 index 00000000..f43b5c20 --- /dev/null +++ b/docs/wiki/visuals/glowing-texture.md @@ -0,0 +1,100 @@ +--- +title: Glowing Entity Texture +category: Tutorials +mentions: + - LeGend077 + - MedicalJewel105 +--- + +In this tutorial, you will learn how to make a glowing texture, like enderman's eyes have for an entity by using materials and textures. + +## Texture + +To make your entity's texture glow, you need to open your texture in an advanced image editor (here, Blockbench) to half-erase the pixels alpha. + +- Open your entity's texture file. + + _Don't mind strange bones rotation, Mojang likes to render models correctly through animations._ + +- Find the __Eraser__ tool and set its opacity/alpha to something low like 71 or 23. + +![](/assets/images/visuals/glowing-texture/eraser.png) + +![](/assets/images/visuals/glowing-texture/opacity.png) + +- Then, erase the part of the texture you want it to glow. The less visible a pixel is the more it glows, but be sure it is not 100% erased. + +![](/assets/images/visuals/glowing-texture/erase-pixels.png) + +Example Pig texture: + +![](/assets/images/visuals/glowing-texture/pig.png) + +## Material + +We need to modify the `RP/entity/my_entity.entity.json` file of the mob we want to glow. Now, find `"materials":{}` and set the values to `"entity_emissive_alpha"`. (Be sure to check if the textures are properly defined). + +RP/entity/pig.entity.json#description + +```json +"materials": { + "default": "entity_emissive_alpha" +} +``` + + + +RP/entity/pig.entity.json + +```json +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "minecraft:pig", + "min_engine_version": "1.8.0", + "materials": { + "default": "entity_emissive_alpha" // replace "pig" with "entity_emissive_alpha" + }, + "textures": { + "default": "textures/entity/pig/pig", + "saddled": "textures/entity/pig/pig_saddle" + }, + "geometry": { + "default": "geometry.pig.v1.8" + }, + "animations": { + "setup": "animation.pig.setup", + "walk": "animation.quadruped.walk", + "look_at_target": "animation.common.look_at_target", + "baby_transform": "animation.pig.baby_transform" + }, + "scripts": { + "animate": [ + "setup", + { + "walk": "q.modified_move_speed" + }, + "look_at_target", + { + "baby_transform": "q.is_baby" + } + ] + }, + "render_controllers": ["controller.render.pig"], + "spawn_egg": { + "texture": "spawn_egg", + "texture_index": 2 + } + } + } +} +``` + + + +## Testing + +Now, load up Minecraft and open a word with this resource pack enabled. Set the time to _midnight_ or find a nearby cave and test it out. The entity should glow as expected. + +![](/assets/images/visuals/glowing-texture/result.png) diff --git a/docs/wiki/visuals/index.md b/docs/wiki/visuals/index.md new file mode 100644 index 00000000..376f7465 --- /dev/null +++ b/docs/wiki/visuals/index.md @@ -0,0 +1,14 @@ +--- +title: Visuals +categories: + - title: General + color: blue + - title: Tutorials + color: green + - title: Ideas + color: orange +--- + +Welcome to the Entity Visuals section! + +Get Started! diff --git a/docs/wiki/visuals/introduction.md b/docs/wiki/visuals/introduction.md new file mode 100644 index 00000000..878be81b --- /dev/null +++ b/docs/wiki/visuals/introduction.md @@ -0,0 +1,17 @@ +--- +title: Introduction to Entity Visuals +nav_order: 1 +tags: + - guide +category: + - General +mentions: + - SirLich + - MedicalJewel105 + - Overload1252 +--- + +## What is this section about? + +Welcome, stranger. You have entered entity visuals section. +Here you can learn how to improve visual part of your content. This section is important as good expression is mostly formed of how everything looks in add-on. \ No newline at end of file diff --git a/docs/wiki/visuals/leash-position.md b/docs/wiki/visuals/leash-position.md new file mode 100644 index 00000000..0428352b --- /dev/null +++ b/docs/wiki/visuals/leash-position.md @@ -0,0 +1,53 @@ +--- +title: Leash Position +category: + - Tutorials +mentions: + - MedicalJewel105 + - SirLich + - Overload1252 +tags: + - easy +--- + +Have you ever wanted to change position of a leash on your entity? +If so, this page is for you! + +## Blockbench Part + +To set a leash position, we will use Blockbench. +Open your model, in this case it will be a llama model. + +*Don't mind strange bones rotation, mojang likes to render models correctly through animations.* + +![](/assets/images/visuals/leash-position/model-1.png) + +Now search for locator `lead`. + +![](/assets/images/visuals/leash-position/model-2.png) + +If it doesn't exist, you can + + + +1. Select a group. +2. Right-click on it. +3. Choose "Add Locator" option. +![](/assets/images/visuals/leash-position/locator-1.png) +4. Rename it to `lead` + + + +The last thing will be to move the locator where you want and save the model. + +![](/assets/images/visuals/leash-position/model-3.png) + +## Testing + +Before: + +![](/assets/images/visuals/leash-position/result-0.png) + +After: + +![](/assets/images/visuals/leash-position/result-1.png) diff --git a/docs/wiki/visuals/material-creations.md b/docs/wiki/visuals/material-creations.md new file mode 100644 index 00000000..8325befe --- /dev/null +++ b/docs/wiki/visuals/material-creations.md @@ -0,0 +1,223 @@ +--- +title: Material Creations +tags: + - expert +category: + - General +--- + +:::warning +Materials are not for the faint of heart. Be prepared for potential crashes, content log errors, and long loading times. +::: + +On this page you can find material creations by community. + +## Custom material that glows and works with semi transparency. + +Note: this also works by disabling culling so you don't run into those weird culling issues where you can't see entities and things behind the texture the material is applied to. + +Note: Texture needs to have semi transparency in it to add the glow effect. + +"customblend" is what you would call in your entity as a material. + + + + + +```json +{ + "customblend:entity_alphablend": { + "+defines": [ + "USE_EMISSIVE" + ], + "+states": [ + "Blending", + "DisableCulling", + "DisableDepthWrite", + "DisableAlphaWrite" + ] + } +} +``` + + + +Credit: StealthyX. + +## Alpha Channel Textures with Render Dragon + +Material that allows for alpha channel textures with render dragon: + + + + + +```json +{ + "ambient_alpha:entity": { + "+states": [ + "Blending", + "DisableCulling" + ], + "vertexShader": "shaders/color_uv.vertex", + "vrGeometryShader": "shaders/color_uv.geometry", + "fragmentShader": "shaders/color_texture.fragment", + "blendSrc": "SourceAlpha", + "blendDst": "OneMinusSrcAlpha", + "vertexFields": [ + { + "field": "Position" + }, + { + "field": "Color" + }, + { + "field": "Normal" + }, + { + "field": "UV0" + } + ], + "variants": [ + { + "skinning": { + "+defines": [ + "USE_SKINNING" + ], + "vertexFields": [ + { + "field": "Position" + }, + { + "field": "BoneId0" + }, + { + "field": "Color" + }, + { + "field": "Normal" + }, + { + "field": "UV0" + } + ] + } + } + ] + } +} +``` + + + +After some more testing was found out that this only works in 3rd person, but still useful since vanilla blending materials still were broken regardless of perspective. + +Credit: Ambient. + +## overlay_color in render controllers + +Material that doesn't permit overlay_color to be used in render controllers: + + + + + +```json +{ + "materials": { + "version": "1.0.0", + "ambient_no_overlay": { + "defines": [ + "ALPHA_TEST" + ], + "vertexShader": "shaders/entity.vertex", + "vrGeometryShader": "shaders/entity.geometry", + "fragmentShader": "shaders/entity.fragment", + "vertexFields": [ + { + "field": "Position" + }, + { + "field": "Normal" + }, + { + "field": "UV0" + } + ], + "variants": [ + { + "skinning": { + "+defines": [ + "USE_SKINNING" + ], + "vertexFields": [ + { + "field": "Position" + }, + { + "field": "BoneId0" + }, + { + "field": "Normal" + }, + { + "field": "UV0" + } + ] + } + }, + { + "skinning_color": { + "+defines": [ + "USE_SKINNING" + ], + "+states": [ + "Blending" + ], + "vertexFields": [ + { + "field": "Position" + }, + { + "field": "BoneId0" + }, + { + "field": "Color" + }, + { + "field": "Normal" + }, + { + "field": "UV0" + } + ] + } + } + ], + "msaaSupport": "Both", + "+samplerStates": [ + { + "samplerIndex": 0, + "textureFilter": "Point" + }, + { + "samplerIndex": 1, + "textureWrap": "Repeat" + } + ] + } + } +} +``` + + + +May be useful for applying to a specific bone and not the entire geometry. + +Credit: Ambient. + +## entity_alphablend_nocolorentity_static Material + +Using the `entity_alphablend_nocolorentity_static` material will reliably crash Minecraft. + +Credit: Gecko. diff --git a/docs/wiki/visuals/materials.md b/docs/wiki/visuals/materials.md new file mode 100644 index 00000000..1c9f3e92 --- /dev/null +++ b/docs/wiki/visuals/materials.md @@ -0,0 +1,239 @@ +--- +title: Materials +tags: + - expert +category: + - General +mentions: + - SirLich + - Joelant05 + - MedicalJewel105 + - Luthorius +--- + +:::warning +Materials are not for the faint of heart. Be prepared for potential crashes, content log errors, and long loading times. +::: + +## Overview + +Materials are used to specify the shaders that render the different parts of the game, along with states and settings the shaders should consider for each element. +At the moment, most things in the game are hard-coded to use specific material and may not be assigned new ones. The only way to change how these elements are rendered is by editing their materials directly (potentially having unintentional effects on other parts) or creating new shaders (an old experimental feature no longer officially supported by Mojang). The only elements that allow default or custom materials to be assigned or removed are entities and particles. + +If you are not prepared to go in-depth with the ins and outs, material presets can be found [here](/documentation/materials). + +## Syntax and Structure + +Most materials inherit the settings of previously defined materials, then further building off of them. This is written in the following format: + +RP/materials/name.material + +```json +{ + "materials": { + "version": "1.0.0", + ":": { + + } + } +} +``` + +:::warning +Although it may look similar, do not confuse material format files in packs. There are no namespaces used in materials. +::: + +Some material files contain extensive branching trees of materials. For example, nearly all of the materials used by default entities are ultimately derivatives of the material `entity_static` in the entity.material file. If we look at the material used by the current villagers: + + + +```json +"villager_v2_masked:entity_multitexture_masked": { + "depthFunc": "LessEqual" +}, +``` + +We can see that the material's name is `villager_v2_masked` and builds off the material named `entity_multitexture_masked`. +Scrolling up in the file, we can find "entity_multitexture_masked" inheriting the settings from "entity_alphatest" and building further onto it: + + + +```json +"entity_multitexture_masked:entity_alphatest":{ + "+defines":[ + "MASKED_MULTITEXTURE" + ], + "+samplerStates":[ + { + "samplerIndex":0, + "textureWrap":"Clamp" + }, + { + "samplerIndex":1, + "textureWrap":"Clamp" + } + ] +} +``` + +"entity_alphatest" can then be followed to "entity_nocull" + + + +```json +"entity_alphatest:entity_nocull":{ + "+defines":[ + "ALPHA_TEST" + ], + "+samplerStates":[ + { + "samplerIndex":1, + "textureWrap":"Repeat" + } + ], + "msaaSupport":"Both" +} +``` + +which can be followed to plain "entity" + + + +```json +"entity_nocull:entity":{ + "+states":[ + "DisableCulling" + ] +} +``` + +which can then finally be followed to "entity_static" + + + +```json +"entity:entity_static":{ + "+defines":[ + "USE_OVERLAY" + ], + "msaaSupport":"Both" +}, + +``` + +"entity_static" doesn't have a colon followed by another material, indicating that it's the bottom of this inheritance tree. + + + +```json +"entity_static":{ + "vertexShader":"shaders/entity.vertex", + "vrGeometryShader":"shaders/entity.geometry", + "fragmentShader":"shaders/entity.fragment", + "vertexFields":[ + { + "field":"Position" + }, + { + "field":"Normal" + }, + { + "field":"UV0" + } + ], + "variants":[ + { + "skinning":{ + "+defines":[ + "USE_SKINNING" + ], + "vertexFields":[ + { + "field":"Position" + }, + { + "field":"BoneId0" + }, + { + "field":"Normal" + }, + { + "field":"UV0" + } + ] + } + }, + { + "skinning_color":{ + "+defines":[ + "USE_SKINNING", + "USE_OVERLAY" + ], + "+states":[ + "Blending" + ], + "vertexFields":[ + { + "field":"Position" + }, + { + "field":"BoneId0" + }, + { + "field":"Color" + }, + { + "field":"Normal" + }, + { + "field":"UV0" + } + ] + } + } + ], + "msaaSupport":"Both", + "+samplerStates":[ + { + "samplerIndex":0, + "textureFilter":"Point" + } + ] +} +``` + +## 1.16.100+ Notes + +Warning for anybody who uses custom materials! + +Custom material inheriting is no longer valid and causes content log errors the workaround Is to define the material fully custom with just the prefix and material name. + +This was not an issue before 1.16.100. + +```json +{ + "materials": { + "version": "1.0.0", + "prefix:window_glass:entity": { //now throws a content log error. + "+states": [ + "Blending" + ], + "defines": [ + "ENABLE_FOG", + "ENABLE_LIGHT", + "USE_ONLY_EMISSIVE" + ] + }, + "prefix:window_glass:": { //corrects the content log error. Note: may have to also define the old inherited values. + "+states": [ + "Blending" + ], + "defines": [ + "ENABLE_FOG", + "ENABLE_LIGHT", + "USE_ONLY_EMISSIVE" + ] + } + } +} +``` \ No newline at end of file diff --git a/docs/wiki/visuals/math-based-animations.md b/docs/wiki/visuals/math-based-animations.md new file mode 100644 index 00000000..500cb283 --- /dev/null +++ b/docs/wiki/visuals/math-based-animations.md @@ -0,0 +1,99 @@ +--- +title: Math-based Animations +tags: + - intermediate +category: + - General +mentions: + - SirLich + - solvedDev + - Joelant05 + - MedicalJewel105 + - yanasakana + - Luthorius + - TheItsNameless + - SmokeyStack + - ThomasOrs +--- + +Math animations are a powerful alternative to keyframe animations. Generally speaking, `math-based animations` is the concept of using Molang expressions to animate entity geometry. All vanilla animations are math-based, here is an example: + + + +```json +"leftarm" : { + "rotation" : [ "((-0.2 + 1.5 * (math.abs(math.mod(q.modified_distance_moved, 13) - 6.5) - 3.25) / 3.25) * q.modified_move_speed) * 57.3 - v.agent.armxrotationfactor", 0.0, "-v.agent.armzrotation" ] +}, +``` + +As you can see, math-based animations can be quite complicated and difficult to understand. Thus, they should be treated as a _specialized-alternative_ to using key-frames - not a *total* replacement. + +This is the cost of the smooth and ideal loop of the animation. + +![](/assets/images/visuals/math-based-animations/animation-1.gif) + +## Writing Math-Animations + +### By Hand + +To write such an animation by hand, simply create an animation file and substitute keyframes for singular arrays of values; strings values are accepted, and it is in a string that one may place a math expression. The Vanilla files can prove an invaluable reference for these types of animations, and it is **strongly** recommended you download and preview them! + +As an important tip for those who wish to *visualise* their processes, the tool, [Molang Grapher](https://jannisx11.github.io/molang-grapher/) from [Jannis](https://twitter.com/jannisx11) may simulate expressions on a proper graph! + +### In Blockbench + +Blockbench allows - to a degree - for the creation and live-previewing of most math-based animations. +To begin, first create a new keyframe at frame 0 in your timeline. You may then add and edit Molang expressions in the keyframe panel on the left sidebar. Mixing keyframes and math is supported. +**Remember**, you should always omit quotation marks around expressions; they are only required in raw JSON-editing! + +Do mind that not all Molang queries are supported in Blockbench in part due to missing game-context. If you wish to preview an animation that uses a context-specific query, you may add it to the Variable Placeholders section, just underneath the keyframe panel, to simulate a value. +For example, adding `q.modified_distance_moved = time*8` simulates the `modified_distance_moved` query with a speed of 8 blocks per second. + +## Using Queries + +The largest and most useful of tools in our mathematical repertoire is the wide array of Molang "Queries". Queries can be used to add outside information into your math expression. + +Common Queries include: + +- `q.modified_distance_moved` +- `q.modified_move_speed` +- `q.anim_time` +- `q.life_time` + +These are utilised in animations to draw things such as the attack-time or distance-moved from the game-world to provide a more dynamic and synced flow. + +### Avoiding Animation Controllers + +By using queries, you can avoid the need to create animation controllers. If the entity's speed is directly related to the speed of the walk animation, then by default, an entity that isn't moving won't be animated. + +## Example + +A specific application example of a Math-Based animation may be found below. The example utilises the Molang Query, `"q.modified_distance_moved"`: + + + +```json +{ + "format_version": "1.12.0", + "animations": { + "animation.car.wheel_spin": { + "loop": true, + "bones": { + + "front_wheels": { + "rotation": [ "q.modified_distance_moved * -30", 0, 0 ] + }, + + "back_wheels": { + "rotation": [ "q.modified_distance_moved * -30", 0, 0 ] + } + + } + } + } +} +``` + +In this example, the model's bones, `front_wheels` and `back_wheels`, are rotated on the X-axis based on information passed from `q.modified_distance_moved`, then multiplied by -30. + +This means that a car at *rest* **will not** spin, and a car that is *driving* **will spin** - doing so at a rate proportional to the car's movement speed. diff --git a/docs/wiki/visuals/player-geometry.md b/docs/wiki/visuals/player-geometry.md new file mode 100644 index 00000000..a68c7a4a --- /dev/null +++ b/docs/wiki/visuals/player-geometry.md @@ -0,0 +1,517 @@ +--- +title: Player Geometry +tags: + - beginner +category: + - Tutorials +mentions: + - SirLich + - MedicalJewel105 +--- + +This tutorial will show you how to create player NPCs and add them into your world. These player NPCs will take vanilla player skins, and come included with walk-animations, attack animations, etc. + +This tutorial is a _graphical_ tutorial. Mechanics are not covered. + +:::warning +This will be a very json-heavy document. The json is intended for copy-pasting. +::: + +## Geometry File + +This json contains geometry for both the Steve and Alex versions: + +`geometry.npc.steve` + +`geometry.npc.alex` + + + + + +```json +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.cape", + "texture_width": 64, + "texture_height": 32 + }, + "bones": [ + { + "name": "body", + "pivot": [0.0, 24.0, 0.0], + "parent": "waist" + }, + { + "name": "waist", + "pivot": [0.0, 12.0, 0.0] + }, + { + "name": "cape", + "parent": "body", + "pivot": [0.0, 24.0, 3.0], + "rotation": [0.0, 180.0, 0.0], + "cubes": [ + { + "origin": [-5.0, 8.0, 3.0], + "size": [10, 16, 1], + "uv": [0, 0] + } + ] + } + ] + }, + + { + "description": { + "identifier": "geometry.npc.steve", + "visible_bounds_width": 1, + "visible_bounds_height": 2, + "visible_bounds_offset": [0, 1, 0], + "texture_width": 64, + "texture_height": 64 + }, + "bones": [ + { + "name": "root", + "pivot": [0.0, 0.0, 0.0] + }, + { + "name": "body", + "parent": "waist", + "pivot": [0.0, 24.0, 0.0], + "cubes": [ + { + "origin": [-4.0, 12.0, -2.0], + "size": [8, 12, 4], + "uv": [16, 16] + } + ] + }, + + { + "name": "waist", + "parent": "root", + "pivot": [0.0, 12.0, 0.0] + }, + + { + "name": "head", + "parent": "body", + "pivot": [0.0, 24.0, 0.0], + "cubes": [ + { + "origin": [-4.0, 24.0, -4.0], + "size": [8, 8, 8], + "uv": [0, 0] + } + ] + }, + + { + "name": "cape", + "pivot": [0.0, 24, 3.0], + "parent": "body" + }, + { + "name": "hat", + "parent": "head", + "pivot": [0.0, 24.0, 0.0], + "cubes": [ + { + "origin": [-4.0, 24.0, -4.0], + "size": [8, 8, 8], + "uv": [32, 0], + "inflate": 0.5 + } + ] + }, + { + "name": "leftArm", + "parent": "body", + "pivot": [5.0, 22.0, 0.0], + "cubes": [ + { + "origin": [4.0, 12.0, -2.0], + "size": [4, 12, 4], + "uv": [32, 48] + } + ] + }, + { + "name": "leftSleeve", + "parent": "leftArm", + "pivot": [5.0, 22.0, 0.0], + "cubes": [ + { + "origin": [4.0, 12.0, -2.0], + "size": [4, 12, 4], + "uv": [48, 48], + "inflate": 0.25 + } + ] + }, + { + "name": "leftItem", + "pivot": [6.0, 15.0, 1.0], + "parent": "leftArm" + }, + { + "name": "rightArm", + "parent": "body", + "pivot": [-5.0, 22.0, 0.0], + "cubes": [ + { + "origin": [-8.0, 12.0, -2.0], + "size": [4, 12, 4], + "uv": [40, 16] + } + ] + }, + { + "name": "rightSleeve", + "parent": "rightArm", + "pivot": [-5.0, 22.0, 0.0], + "cubes": [ + { + "origin": [-8.0, 12.0, -2.0], + "size": [4, 12, 4], + "uv": [40, 32], + "inflate": 0.25 + } + ] + }, + { + "name": "rightItem", + "pivot": [-6, 15, 1], + "locators": { + "lead_hold": [-6, 15, 1] + }, + "parent": "rightArm" + }, + + { + "name": "leftLeg", + "parent": "root", + "pivot": [1.9, 12.0, 0.0], + "cubes": [ + { + "origin": [-0.1, 0.0, -2.0], + "size": [4, 12, 4], + "uv": [16, 48] + } + ] + }, + { + "name": "leftPants", + "parent": "leftLeg", + "pivot": [1.9, 12.0, 0.0], + "cubes": [ + { + "origin": [-0.1, 0.0, -2.0], + "size": [4, 12, 4], + "uv": [0, 48], + "inflate": 0.25 + } + ] + }, + + { + "name": "rightLeg", + "parent": "root", + "pivot": [-1.9, 12.0, 0.0], + "cubes": [ + { + "origin": [-3.9, 0.0, -2.0], + "size": [4, 12, 4], + "uv": [0, 16] + } + ] + }, + { + "name": "rightPants", + "parent": "rightLeg", + "pivot": [-1.9, 12.0, 0.0], + "cubes": [ + { + "origin": [-3.9, 0.0, -2.0], + "size": [4, 12, 4], + "uv": [0, 32], + "inflate": 0.25 + } + ] + }, + + { + "name": "jacket", + "parent": "body", + "pivot": [0.0, 24.0, 0.0], + "cubes": [ + { + "origin": [-4.0, 12.0, -2.0], + "size": [8, 12, 4], + "uv": [16, 32], + "inflate": 0.25 + } + ] + } + ] + }, + + { + "description": { + "identifier": "geometry.npc.alex", + "visible_bounds_width": 1, + "visible_bounds_height": 2, + "visible_bounds_offset": [0, 1, 0], + "texture_width": 64, + "texture_height": 64 + }, + "bones": [ + { + "name": "root", + "pivot": [0.0, 0.0, 0.0] + }, + { + "name": "waist", + "parent": "root", + "pivot": [0.0, 12.0, 0.0] + }, + { + "name": "body", + "parent": "waist", + "pivot": [0.0, 24.0, 0.0], + "cubes": [ + { + "origin": [-4.0, 12.0, -2.0], + "size": [8, 12, 4], + "uv": [16, 16] + } + ] + }, + { + "name": "head", + "parent": "body", + "pivot": [0.0, 24.0, 0.0], + "cubes": [ + { + "origin": [-4.0, 24.0, -4.0], + "size": [8, 8, 8], + "uv": [0, 0] + } + ] + }, + { + "name": "hat", + "parent": "head", + "pivot": [0.0, 24.0, 0.0], + "cubes": [ + { + "origin": [-4.0, 24.0, -4.0], + "size": [8, 8, 8], + "uv": [32, 0], + "inflate": 0.5 + } + ] + }, + { + "name": "rightLeg", + "parent": "root", + "pivot": [-1.9, 12.0, 0.0], + "cubes": [ + { + "origin": [-3.9, 0.0, -2.0], + "size": [4, 12, 4], + "uv": [0, 16] + } + ] + }, + { + "name": "rightPants", + "parent": "rightLeg", + "pivot": [-1.9, 12.0, 0.0], + "cubes": [ + { + "origin": [-3.9, 0.0, -2.0], + "size": [4, 12, 4], + "uv": [0, 32], + "inflate": 0.25 + } + ] + }, + + { + "name": "leftLeg", + "parent": "root", + "pivot": [1.9, 12.0, 0.0], + "cubes": [ + { + "origin": [-0.1, 0.0, -2.0], + "size": [4, 12, 4], + "uv": [0, 16] + } + ], + "mirror": true + }, + { + "name": "leftPants", + "parent": "leftLeg", + "pivot": [1.9, 12.0, 0.0], + "cubes": [ + { + "origin": [-0.1, 0.0, -2.0], + "size": [4, 12, 4], + "uv": [0, 48], + "inflate": 0.25 + } + ] + }, + + { + "name": "leftArm", + "parent": "body", + "pivot": [5.0, 21.5, 0.0], + "cubes": [ + { + "origin": [4.0, 11.5, -2.0], + "size": [3, 12, 4], + "uv": [32, 48] + } + ] + }, + { + "name": "leftSleeve", + "parent": "leftArm", + "pivot": [5.0, 21.5, 0.0], + "cubes": [ + { + "origin": [4.0, 11.5, -2.0], + "size": [3, 12, 4], + "uv": [48, 48], + "inflate": 0.25 + } + ] + }, + { + "name": "leftItem", + "pivot": [6, 14.5, 1], + "parent": "leftArm" + }, + { + "name": "rightArm", + "parent": "body", + "pivot": [-5.0, 21.5, 0.0], + "cubes": [ + { + "origin": [-7.0, 11.5, -2.0], + "size": [3, 12, 4], + "uv": [40, 16] + } + ] + }, + { + "name": "rightSleeve", + "parent": "rightArm", + "pivot": [-5.0, 21.5, 0.0], + "cubes": [ + { + "origin": [-7.0, 11.5, -2.0], + "size": [3, 12, 4], + "uv": [40, 32], + "inflate": 0.25 + } + ] + }, + { + "name": "rightItem", + "pivot": [-6, 14.5, 1], + "locators": { + "lead_hold": [-6, 14.5, 1] + }, + "parent": "rightArm" + }, + + { + "name": "jacket", + "parent": "body", + "pivot": [0.0, 24.0, 0.0], + "cubes": [ + { + "origin": [-4.0, 12.0, -2.0], + "size": [8, 12, 4], + "uv": [16, 32], + "inflate": 0.25 + } + ] + }, + + { + "name": "cape", + "pivot": [0.0, 24, -3.0], + "parent": "body" + } + ] + } + ] +} +``` + + + +## Entity File + +Use this entity file if you would like to have animations for your geometry. This file includes error-free animations for: + +- walking +- looking at player +- idle + +If you need a more complete set of animations, consider copying the default player RP-entity file, and trying to work with the animations by hand. + + + + + +```json +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "wiki:npc", + "materials": { + "default": "villager_v2" + }, + "geometry": { + "default": "geometry.npc.alex" + }, + "render_controllers": ["controller.render.single_texture"], + "textures": { + "default": "textures/entity/npc/introduction" + }, + "scripts": { + "scale": "0.9375", + "pre_animation": [ + "v.tcos0 = (math.cos(q.modified_distance_moved * 38.17) * q.modified_move_speed / v.gliding_speed_value) * 57.3;" + ], + "animate": [ + "move.arms", + "move.legs", + "look_at_target_default", + "bob" + ] + }, + "animations": { + "look_at_target_default": "animation.humanoid.look_at_target.default", + "move.arms": "animation.player.move.arms", + "move.legs": "animation.player.move.legs", + "bob": "animation.player.bob" + } + } + } +} +``` + + diff --git a/docs/wiki/visuals/remove-shadows.md b/docs/wiki/visuals/remove-shadows.md new file mode 100644 index 00000000..ecd5f628 --- /dev/null +++ b/docs/wiki/visuals/remove-shadows.md @@ -0,0 +1,122 @@ +--- +title: Remove Entity Shadows +tags: + - intermediate +category: + - Tutorials +mentions: + - SirLich + - solvedDev + - Joelant05 + - MedicalJewel105 + - SmokeyStack + - ThomasOrs +--- + +There are quite a few ways to remove shadows from entities, and nearly all of them have undesirable effects. There is no foolproof way to perfectly remove shadows from specific entities, without causing side effects. + +This document will showcase some of the various ways to remove shadows, and any possible effects from doing this. + +## Small Collision Box + +One possibility is to make the size of the collision component very small. This will make it hard to interact/hit the entity, but it will make the shadow disappear! + + + +```json +"minecraft:collision_box": { + "width": 0.1, + "height": 0.1 +} +``` + +You can also add the [custom hit test component](https://bedrock.dev/docs/stable/Entities#minecraft:custom_hit_test). The `custom_hit_test` component will allow you to hit the entity, although you will not be able to interact with it. The `custom_hit_test` will not create a shadow. + + + +```json +"minecraft:custom_hit_test": { + "hitboxes": [ + { + "pivot": [0, 0.5, 0],//This is the position of the hitbox, you can change the X, Y and Z values. + "width": 0.8, + "height": 0.7 + }//And you can add many more hitboxes as you want, just copy-paste the hitbox inside the "hitboxes" array. + ] +} +``` + +## Teleport underground + +If you have a dummy entity (invisible) that you need to interact with, you can teleport like `/teleport @x ~ ~-0.01 ~`. This will slightly insert the entity into the ground, and stop shadows from showing. + +## Using runtime identifier + +Some entities don't have shadows, or very small shadows at least. By using the runtime identifier of these entities, we can remove the shadows. The downside is taking on that entities hard-coded behaviors, which can sometimes be very problematic. See the [runtime identifiers document](/entities/runtime-identifier) for more information. + +## Using Materials + +:::danger +This method is no longer supported. With the advent of render-dragon, materials like this no longer function. Please do not attempt to use this code in a serious way, and definitely do not attempt it on a marketplace map. +::: + +:::warning + - This folder is NOT included in the vanilla RP Pack examples and must be exported from a APK files or added by hand. + - This has not been tested for blocks and has only been verified for entities. If you find it works on blocks too please let us know so we can add that in. +::: + + + +#### Working shadow code: Shadows for ALL entities: + +RP/materials/shadows.material + +```json +"shadow_overlay":{ + "+states":[ + "DisableDepthTest", + "DisableCulling", + "Blending", + "EnableStencilTest" + ], + "vertexShader":"shaders/color.vertex", + "vrGeometryShader":"shaders/color.geometry", + "fragmentShader":"shaders/shadow_stencil_overlay.fragment", + "blendSrc":"DestColor", + "blendDst":"Zero", + "frontFace":{ + "stencilFunc":"Equal", + "stencilPass":"Replace" + } +} +``` + +#### Disabled shadow code: No Shadows for ALL entities: + + + +```json +"shadow_overlay":{ + "+states":[ + "DisableDepthTest", + "DisableCulling", + "Blending", + "EnableStencilTest" + ], + "vertexShader":"", + "vrGeometryShader":"", + "fragmentShader":"", + "blendSrc":"DestColor", + "blendDst":"Zero", + "frontFace":{ + "stencilFunc":"Equal", + "stencilPass":"Replace" + } +} +``` + + + +#### Geometry + Materials Workaround + +You can hide entity shadows if you apply a model on your entity to cover the shadow and use `"banner_pole"` material. \ No newline at end of file diff --git a/docs/wiki/visuals/retexturing-spawn-eggs.md b/docs/wiki/visuals/retexturing-spawn-eggs.md new file mode 100644 index 00000000..127f188c --- /dev/null +++ b/docs/wiki/visuals/retexturing-spawn-eggs.md @@ -0,0 +1,59 @@ +--- +title: Retexturing Spawn Eggs +tags: + - beginner +category: + - Tutorials +mentions: + - SirLich + - Joelant05 + - MedicalJewel105 + - aexer0e +--- + +Custom entities will automatically be given a spawn egg. This spawn egg can be found inside of the creative menu, with a name like `item.spawn_egg.entity.wiki:my_entity.name`. If you want to rename your spawn egg as well as set a texture, you can do so in the lang files. + +In this tutorial we are going to retexture the spawn egg so it looks more like your spawned item, and less like an egg. + +## Creating the Texture + +You can easily take a screenshot of your entity using the Blockbench software. Load the mode, and select export screenshot from the drop-down. + +If you don't want an image like this, you can also create your own pixel art, or use any image you like. + +## Adding the Texture + +Add the texture file under `textures/items/`. I personally suggest creating an `eggs` folder to contain all the spawn egg textures. For example, `textures/items/eggs/my_entity.png`. The file itself should be square. + +## Giving the Texture a Name + +Now we need to give our texture a short-name. This can be done in item_texture file: + +RP/textures/item_texture.json + +```json +{ + "resource_pack_name": "My Map Name", //I don't actually know if this field does anything. + "texture_name": "atlas.items", + "texture_data": { + "my_entity": { //"my_entity" is the short-name of the texture, which we can reference later + "textures": "textures/items/egg/my_entity" + } + //Add more spawn egg textures here + } +``` + +## Using the new texture: + +Now we can use our new texture inside of the Resource Pack entity file: + +RP/entity/my_entity.json#description + +```json +"spawn_egg": { + "texture": "my_entity", //"my entity should match the texture short-name we created in step-1. + "texture_index": 0 +} +``` + +Go and test it now! \ No newline at end of file diff --git a/docs/wiki/visuals/structure-presentation.md b/docs/wiki/visuals/structure-presentation.md new file mode 100644 index 00000000..508ef0ce --- /dev/null +++ b/docs/wiki/visuals/structure-presentation.md @@ -0,0 +1,53 @@ +--- +title: Structure Presentation +category: Ideas +mentions: + - MedicalJewel105 + - LeGend077 + - ThomasOrs +--- + +## Why this page exists + +Presenting features of an add-on clearly has same importance in showcasing quality. If people can understand an add-on and it's features they might be more likely to try it. This page will demonstrate a way of presenting structures. + +## Presentation Methods + +There are lots ways of you could showcase structures to people. You can: + +- Take in-game screenshots of the structure. +- Take a screenshot inside of a structure block. +- Create a 3D object of your structure. + +Below all three methods will be shown using the Pillager outpost structure as an example. + +### In-Game Screenshot + +This is the simplest method because it is quick and easy. It also lets you showcase the structure in the context of the world, there are some disadvantages however. You may need to find a good place to take a screenshot or have difficulty finding a good angle. + +![](/assets/images/visuals/structure-presentation/in-game.png) + +### In a Structure Block + +This method avoids some of the disadvantages of a screenshot in the world, you are able to focus entirely on the structure without other blocks in the view. + +![](/assets/images/visuals/structure-presentation/structure-block-0.png) + +By making [JSON UI](/json-ui/json-ui-intro) edits you can change the background color and remove other elements to further improve this method. + +![](/assets/images/visuals/structure-presentation/structure-block-1.png) + +### Rendered 3D Object + +Structures can be exported as a 3d model. If 3D export button is not working for you, you can try applying a 3d-export-fix pack. + +Download Pack + +![](/assets/images/visuals/structure-presentation/model-render.png) + +This method is mostly available for pc users. You can create a simple render in Paint 3D or a more advanced in blender. In this case we can represent our structure in a fast and easy way. + +⬇ If you have any other methods, contribute them below. diff --git a/docs/wiki/vr/editing-your-first-model.md b/docs/wiki/vr/editing-your-first-model.md new file mode 100644 index 00000000..eeccd70b --- /dev/null +++ b/docs/wiki/vr/editing-your-first-model.md @@ -0,0 +1,145 @@ +--- +title: Editing Your First Model +category: Tutorials +mentions: + - TheDoctor15 + - MedicalJewel105 + - TheItsNameless + - SmokeyStack +tags: + - expert +--- + +This tutorial will show you how to make your first VR model. +For the sake of this tutorial we will be editing the right hand model. + +:::tip +This tutorial makes use of the program [Blender](https://www.blender.org/download/), make sure you have it before following this tutorial. +::: + +## Viewing the model in Blender + +First you need to import the model into Blender: + +![](/assets/images/vr/tutorial-hand-right/import-1.png) +![](/assets/images/vr/tutorial-hand-right/import-2.png) +![](/assets/images/vr/tutorial-hand-right/import-3.png) + +Your model is now imported but it misses a texture. +To add a texture you will go to the Shading tab in blender. +There you are going to add a texture element like this: + +![](/assets/images/vr/tutorial-hand-right/shading-add-texture-element.png) +![](/assets/images/vr/tutorial-hand-right/texture-element.png) + +In that element you press open and select your texture in our case it is `something\VRpackTemplate\textures\hologram_hands.png`. +Make sure you change linear to closest, otherwise your texture will look blurry. +In the end it will look like this: + +![](/assets/images/vr/tutorial-hand-right/texture-element-complete.png) + +Now its time to add the texture to the models material. +You hold the yellow dot and connect it to the other yellow dot like this: + +![](/assets/images/vr/tutorial-hand-right/texture-base-connect.png) + +If everything went good your model should now look like this: + +![](/assets/images/vr/tutorial-hand-right/texture-on-model.png) + +## Editing the model + +With editing the model you have almost total freedom, the only requirement is that the model only uses 1 texture. + +### Editing the model (easy) + +Since this is the easy tutorial, we will show you how to make the hand into an arm. + +First we need to figure out the dimensions of this object. + +![](/assets/images/vr/tutorial-hand-right/model-dimensions.png) + +This image shows us that 3 pixels is equivalent to 18.75 meters in Blender, an arm is 12 pixels long so this means an arm is `4 * 18.75 = 75 meters` in Blender. +When editing the dimensions it will look like this: + +![](/assets/images/vr/tutorial-hand-right/edited-dimensions-1.png) + +If we import it into minecraft the arm will be to far away. This is because the original model is made for a hand not an arm. So we need to move it `3 * 18.75 = 56.25 meters` down. + +![](/assets/images/vr/tutorial-hand-right/edited-dimensions-2.png) + +#### Texturing + +Since this is an arm we will use the steve arm model, you import it the same way like we did above. + +![](/assets/images/vr/tutorial-hand-right/hologram-hands-steve.png) + +![](/assets/images/vr/tutorial-hand-right/steve-texture-stretched.png) + +Now you might notice your texture is stretched out. to fix this we will go to UV-editing and edit the uv map. +UV-editing looks almost the same to blockbench. + +![](/assets/images/vr/tutorial-hand-right/uv-map.png) + +:::tip +Its handy to turn on this magnet looking icon so its more precise. +![](/assets/images/vr/tutorial-hand-right/magnet-icon.png) +::: + +We start with selecting the top and the bottom of the hand. + +![](/assets/images/vr/tutorial-hand-right/uv-map-top-selected.png) + +Next we select the move tool. + +![](/assets/images/vr/tutorial-hand-right/uv-map-pos.png) + +Now we move the top face and bottom face to the top of the texture. + +![](/assets/images/vr/tutorial-hand-right/uv-map-top-move-up.png) + +The same for the sides of the arm. + +Your new uv map should look something like this: + +![](/assets/images/vr/tutorial-hand-right/uv-map-side-up.png) + +If we look how the arm look we see all is now fixed. + +![](/assets/images/vr/tutorial-hand-right/uv-map-done.png) + +#### Export it! + +It is time to now export your model first put the steve arm texture inside `VRpackTemplateRP\textures`. +Call it `hologram_hands.png`. + +![](/assets/images/vr/tutorial-hand-right/export-texture.png) + +Now lets export the model. + +![](/assets/images/vr/tutorial-hand-right/export-model-1.png) + +Call the model `hologram_hand_right.obj`. + +![](/assets/images/vr/tutorial-hand-right/export-model-2.png) + +#### Testing it in game + +Load the pack into minecraft and try it out if it looks like this you succeeded in this tutorial! + +![](/assets/images/vr/tutorial-hand-right/export-done.png) + +Get guide end results! + +## Your progress so far + + + +- [x] Setup Minecraft VR +- [x] Setup the pack +- [x] Edit the models + + diff --git a/docs/wiki/vr/index.md b/docs/wiki/vr/index.md new file mode 100644 index 00000000..93b7e735 --- /dev/null +++ b/docs/wiki/vr/index.md @@ -0,0 +1,11 @@ +--- +title: Virtual Reality +categories: + - title: General + color: blue + - title: Tutorials + color: green +--- + diff --git a/docs/wiki/vr/installing-bedrock-vr.md b/docs/wiki/vr/installing-bedrock-vr.md new file mode 100644 index 00000000..91f8afd0 --- /dev/null +++ b/docs/wiki/vr/installing-bedrock-vr.md @@ -0,0 +1,49 @@ +--- +title: Enabling VR +category: General +nav_order: 1 +mentions: + - TheDoctor15 + - MedicalJewel105 +tags: + - guide +--- + +Minecraft VR was formerly available for download via the Oculus store, but that version hasn't been updated in a long time. This article will show you how to enable VR in the most recent version of Minecraft on your Windows PC. + +:::warning +If you are on Playstation you don't need to follow this guide. +::: + +## Creating the desktop shortcut + +Right-click on your desktop and create a new shortcut: + +![](/assets/images/vr/install/vr_desktop.png) + +As location you fill in `minecraft://Mode/?OpenXR=true`. + +![](/assets/images/vr/install/vr_shortcut_path.png) + +You can name it how ever you want, in the end you should have a shortcut looking like this: + +![](/assets/images/vr/install/vr_shortcut_icon.png) + +## Opening Minecraft in VR + +First make sure you connected your headset properly: + +![](/assets/images/vr/install/vr_headset.png) + +When your headset is all setup it is time to open the shortcut. + +## Your progress so far + + + +- [x] Setup Minecraft VR +- [ ] Setup your VR resource pack +- [ ] Create custom hands +- [ ] Create a custom living room + + diff --git a/docs/wiki/vr/pack_setup.md b/docs/wiki/vr/pack_setup.md new file mode 100644 index 00000000..14a1a207 --- /dev/null +++ b/docs/wiki/vr/pack_setup.md @@ -0,0 +1,57 @@ +--- +title: Setting Up the Pack +category: General +mentions: + - TheDoctor15 + - MedicalJewel105 + - TheItsNameless + - SmokeyStack +tags: + - expert +--- + +To start making your addon you should download this template. +This template contains all the required assets for a start on making the VR pack. + +Get the template! + +:::warning +Dont delete `contents.json` and `textures_list.json` from the template. +::: + +## What does the template contain? + +The template contains 2 editable folders; `holograms` and `textures`, +these folders contain the models and textures for the vr objects. + +![](/assets/images/vr/setup/vr-template-contents.png) + +## Holograms + +This folder contains all the models the VR version of Minecraft uses, for example the VR hands. + +![](/assets/images/vr/setup/vr-template-holograms.png) + +## Textures + +This folder stores all textures for the models. + +![](/assets/images/vr/setup/vr-template-textures.png) + +## Merging the VR template with your own pack + +This pack depends on the `contents.json` and `textures_list.json` to work. All assets from your pack, that the game will use, need to be defined in there. +If you have 2 of the same files you are ought to combine them. + +## Your progress so far + + + +- [x] Setup Minecraft VR +- [x] Setup the pack +- [ ] Edit the models + + diff --git a/docs/wiki/world-generation/biome-tags.md b/docs/wiki/world-generation/biome-tags.md new file mode 100644 index 00000000..d181343e --- /dev/null +++ b/docs/wiki/world-generation/biome-tags.md @@ -0,0 +1,166 @@ +--- +title: Biome Tags +category: Documentation +mentions: + - MedicalJewel105 +--- + +This page was created with [Wiki Content Generator](https://github.com/Bedrock-OSS/bedrock-wiki-content-generator). If there are issues, contact us on [Bedrock OSS](https://discord.gg/XjV87YN) Discord server. + *Last updated on 08 August 2023* + +## Biome tag per Biome + +| Biome | Biome Tags | +| -------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| bamboo_jungle | animal, bamboo, jungle, monster, overworld | +| bamboo_jungle_hills | animal, bamboo, hills, jungle, monster, overworld | +| basalt_deltas | nether, basalt_deltas, spawn_many_magma_cubes, spawn_ghast | +| beach | beach, monster, overworld, warm | +| birch_forest | animal, birch, forest, monster, overworld, bee_habitat | +| birch_forest_hills | animal, birch, forest, hills, monster, overworld, bee_habitat | +| birch_forest_hills_mutated | animal, birch, forest, hills, monster, mutated, overworld_generation | +| birch_forest_mutated | animal, birch, forest, monster, mutated, bee_habitat, overworld_generation | +| cold_beach | beach, cold, monster, overworld | +| cold_ocean | cold, monster, ocean, overworld | +| cold_taiga | animal, cold, forest, monster, overworld, taiga | +| cold_taiga_hills | animal, cold, forest, hills, monster, overworld, taiga | +| cold_taiga_mutated | animal, cold, forest, monster, mutated, taiga, overworld_generation | +| crimson_forest | nether, netherwart_forest, crimson_forest, spawn_few_zombified_piglins, spawn_piglin | +| deep_cold_ocean | cold, deep, monster, ocean, overworld | +| deep_frozen_ocean | deep, frozen, monster, ocean, overworld | +| deep_lukewarm_ocean | deep, lukewarm, monster, ocean, overworld | +| deep_ocean | deep, monster, ocean, overworld | +| deep_warm_ocean | deep, monster, ocean, overworld, warm | +| desert | desert, monster, overworld | +| desert_hills | desert, hills, monster, overworld | +| desert_mutated | desert, monster, mutated, overworld_generation | +| dripstone_caves | caves, overworld, dripstone_caves, monster | +| extreme_hills | animal, extreme_hills, monster, overworld | +| extreme_hills_edge | animal, edge, extreme_hills, monster, mountain, overworld | +| extreme_hills_mutated | animal, extreme_hills, monster, mutated, overworld | +| extreme_hills_plus_trees | animal, extreme_hills, forest, monster, mountain, overworld | +| extreme_hills_plus_trees_mutated | animal, extreme_hills, forest, monster, mutated, overworld | +| flower_forest | flower_forest, monster, mutated, overworld, bee_habitat | +| forest | animal, forest, monster, overworld, bee_habitat | +| forest_hills | animal, hills, monster, overworld, forest, bee_habitat | +| frozen_ocean | frozen, monster, ocean, overworld | +| frozen_peaks | mountains, monster, overworld, frozen, frozen_peaks | +| frozen_river | frozen, overworld, river | +| grove | mountains, monster, overworld, grove | +| hell | nether, nether_wastes, spawn_magma_cubes, spawn_zombified_piglin, spawn_few_piglins, spawn_ghast, spawn_endermen | +| ice_mountains | frozen, ice, mountain, overworld | +| ice_plains | frozen, ice, ice_plains, overworld | +| ice_plains_spikes | frozen, ice_plains, monster, mutated, overworld | +| jagged_peaks | mountains, monster, overworld, frozen, jagged_peaks | +| jungle | animal, jungle, monster, overworld, rare | +| jungle_edge | animal, edge, jungle, monster, overworld | +| jungle_edge_mutated | animal, edge, jungle, monster, mutated, overworld_generation | +| jungle_hills | animal, hills, jungle, monster, overworld | +| jungle_mutated | animal, jungle, monster, mutated, overworld_generation | +| legacy_frozen_ocean | frozen, ocean, overworld | +| lukewarm_ocean | lukewarm, monster, ocean, overworld | +| lush_caves | caves, lush_caves, overworld, monster | +| meadow | mountains, monster, overworld, meadow, bee_habitat | +| mega_taiga | animal, forest, mega, monster, overworld, rare, taiga | +| mega_taiga_hills | animal, forest, hills, mega, monster, overworld, taiga | +| mesa | mesa, monster, overworld | +| mesa_bryce | animal, mesa, monster, mutated, overworld | +| mesa_plateau | mesa, monster, overworld, plateau, rare | +| mesa_plateau_mutated | mesa, monster, mutated, overworld, plateau, stone | +| mesa_plateau_stone | mesa, monster, overworld, plateau, rare, stone | +| mesa_plateau_stone_mutated | mesa, monster, mutated, overworld, plateau | +| mushroom_island | mooshroom_island, overworld | +| mushroom_island_shore | mooshroom_island, overworld, shore | +| ocean | monster, ocean, overworld | +| plains | animal, monster, overworld, plains, bee_habitat | +| redwood_taiga_hills_mutated | animal, forest, hills, mega, monster, mutated, taiga, overworld_generation | +| redwood_taiga_mutated | animal, forest, mega, monster, mutated, overworld, taiga | +| river | overworld, river | +| roofed_forest | animal, forest, monster, no_legacy_worldgen, overworld, roofed | +| roofed_forest_mutated | animal, forest, monster, mutated, roofed, overworld_generation | +| savanna | animal, monster, overworld, savanna | +| savanna_mutated | animal, monster, mutated, overworld, savanna | +| savanna_plateau | animal, monster, overworld, plateau, savanna | +| savanna_plateau_mutated | animal, monster, mutated, overworld, plateau, savanna | +| snowy_slopes | mountains, monster, overworld, snowy_slopes, frozen | +| soulsand_valley | nether, soulsand_valley, spawn_ghast, spawn_endermen | +| stone_beach | beach, monster, overworld, stone | +| stony_peaks | mountains, monster, overworld | +| sunflower_plains | animal, monster, mutated, overworld, plains, bee_habitat | +| swampland | animal, monster, overworld, swamp | +| swampland_mutated | animal, monster, mutated, swamp, overworld_generation | +| taiga | animal, forest, monster, overworld, taiga | +| taiga_hills | animal, forest, hills, monster, overworld, taiga | +| taiga_mutated | animal, forest, monster, mutated, taiga, overworld_generation | +| the_end | the_end | +| warm_ocean | monster, ocean, overworld, warm | +| warped_forest | nether, netherwart_forest, warped_forest, spawn_endermen | + +## Biome per Biome Tag + +| Biome Tag | Biomes | +| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| animal | bamboo_jungle, bamboo_jungle_hills, birch_forest, birch_forest_hills, birch_forest_hills_mutated, birch_forest_mutated, cold_taiga, cold_taiga_hills, cold_taiga_mutated, extreme_hills, extreme_hills_edge, extreme_hills_mutated, extreme_hills_plus_trees, extreme_hills_plus_trees_mutated, forest, forest_hills, jungle, jungle_edge, jungle_edge_mutated, jungle_hills, jungle_mutated, mega_taiga, mega_taiga_hills, mesa_bryce, plains, redwood_taiga_hills_mutated, redwood_taiga_mutated, roofed_forest, roofed_forest_mutated, savanna, savanna_mutated, savanna_plateau, savanna_plateau_mutated, sunflower_plains, swampland, swampland_mutated, taiga, taiga_hills, taiga_mutated | +| bamboo | bamboo_jungle, bamboo_jungle_hills | +| basalt_deltas | basalt_deltas | +| beach | beach, cold_beach, stone_beach | +| bee_habitat | birch_forest, birch_forest_hills, birch_forest_mutated, flower_forest, forest, forest_hills, meadow, plains, sunflower_plains | +| birch | birch_forest, birch_forest_hills, birch_forest_hills_mutated, birch_forest_mutated | +| caves | dripstone_caves, lush_caves | +| cold | cold_beach, cold_ocean, cold_taiga, cold_taiga_hills, cold_taiga_mutated, deep_cold_ocean | +| crimson_forest | crimson_forest | +| deep | deep_cold_ocean, deep_frozen_ocean, deep_lukewarm_ocean, deep_ocean, deep_warm_ocean | +| desert | desert, desert_hills, desert_mutated | +| dripstone_caves | dripstone_caves | +| edge | extreme_hills_edge, jungle_edge, jungle_edge_mutated | +| extreme_hills | extreme_hills, extreme_hills_edge, extreme_hills_mutated, extreme_hills_plus_trees, extreme_hills_plus_trees_mutated | +| flower_forest | flower_forest | +| forest | birch_forest, birch_forest_hills, birch_forest_hills_mutated, birch_forest_mutated, cold_taiga, cold_taiga_hills, cold_taiga_mutated, extreme_hills_plus_trees, extreme_hills_plus_trees_mutated, forest, forest_hills, mega_taiga, mega_taiga_hills, redwood_taiga_hills_mutated, redwood_taiga_mutated, roofed_forest, roofed_forest_mutated, taiga, taiga_hills, taiga_mutated | +| frozen | deep_frozen_ocean, frozen_ocean, frozen_peaks, frozen_river, ice_mountains, ice_plains, ice_plains_spikes, jagged_peaks, legacy_frozen_ocean, snowy_slopes | +| frozen_peaks | frozen_peaks | +| grove | grove | +| hills | bamboo_jungle_hills, birch_forest_hills, birch_forest_hills_mutated, cold_taiga_hills, desert_hills, forest_hills, jungle_hills, mega_taiga_hills, redwood_taiga_hills_mutated, taiga_hills | +| ice | ice_mountains, ice_plains | +| ice_plains | ice_plains, ice_plains_spikes | +| jagged_peaks | jagged_peaks | +| jungle | bamboo_jungle, bamboo_jungle_hills, jungle, jungle_edge, jungle_edge_mutated, jungle_hills, jungle_mutated | +| lukewarm | deep_lukewarm_ocean, lukewarm_ocean | +| lush_caves | lush_caves | +| meadow | meadow | +| mega | mega_taiga, mega_taiga_hills, redwood_taiga_hills_mutated, redwood_taiga_mutated | +| mesa | mesa, mesa_bryce, mesa_plateau, mesa_plateau_mutated, mesa_plateau_stone, mesa_plateau_stone_mutated | +| monster | bamboo_jungle, bamboo_jungle_hills, beach, birch_forest, birch_forest_hills, birch_forest_hills_mutated, birch_forest_mutated, cold_beach, cold_ocean, cold_taiga, cold_taiga_hills, cold_taiga_mutated, deep_cold_ocean, deep_frozen_ocean, deep_lukewarm_ocean, deep_ocean, deep_warm_ocean, desert, desert_hills, desert_mutated, dripstone_caves, extreme_hills, extreme_hills_edge, extreme_hills_mutated, extreme_hills_plus_trees, extreme_hills_plus_trees_mutated, flower_forest, forest, forest_hills, frozen_ocean, frozen_peaks, grove, ice_plains_spikes, jagged_peaks, jungle, jungle_edge, jungle_edge_mutated, jungle_hills, jungle_mutated, lukewarm_ocean, lush_caves, meadow, mega_taiga, mega_taiga_hills, mesa, mesa_bryce, mesa_plateau, mesa_plateau_mutated, mesa_plateau_stone, mesa_plateau_stone_mutated, ocean, plains, redwood_taiga_hills_mutated, redwood_taiga_mutated, roofed_forest, roofed_forest_mutated, savanna, savanna_mutated, savanna_plateau, savanna_plateau_mutated, snowy_slopes, stone_beach, stony_peaks, sunflower_plains, swampland, swampland_mutated, taiga, taiga_hills, taiga_mutated, warm_ocean | +| mooshroom_island | mushroom_island, mushroom_island_shore | +| mountain | extreme_hills_edge, extreme_hills_plus_trees, ice_mountains | +| mountains | frozen_peaks, grove, jagged_peaks, meadow, snowy_slopes, stony_peaks | +| mutated | birch_forest_hills_mutated, birch_forest_mutated, cold_taiga_mutated, desert_mutated, extreme_hills_mutated, extreme_hills_plus_trees_mutated, flower_forest, ice_plains_spikes, jungle_edge_mutated, jungle_mutated, mesa_bryce, mesa_plateau_mutated, mesa_plateau_stone_mutated, redwood_taiga_hills_mutated, redwood_taiga_mutated, roofed_forest_mutated, savanna_mutated, savanna_plateau_mutated, sunflower_plains, swampland_mutated, taiga_mutated | +| nether | basalt_deltas, crimson_forest, hell, soulsand_valley, warped_forest | +| nether_wastes | hell | +| netherwart_forest | crimson_forest, warped_forest | +| no_legacy_worldgen | roofed_forest | +| ocean | cold_ocean, deep_cold_ocean, deep_frozen_ocean, deep_lukewarm_ocean, deep_ocean, deep_warm_ocean, frozen_ocean, legacy_frozen_ocean, lukewarm_ocean, ocean, warm_ocean | +| overworld | bamboo_jungle, bamboo_jungle_hills, beach, birch_forest, birch_forest_hills, cold_beach, cold_ocean, cold_taiga, cold_taiga_hills, deep_cold_ocean, deep_frozen_ocean, deep_lukewarm_ocean, deep_ocean, deep_warm_ocean, desert, desert_hills, dripstone_caves, extreme_hills, extreme_hills_edge, extreme_hills_mutated, extreme_hills_plus_trees, extreme_hills_plus_trees_mutated, flower_forest, forest, forest_hills, frozen_ocean, frozen_peaks, frozen_river, grove, ice_mountains, ice_plains, ice_plains_spikes, jagged_peaks, jungle, jungle_edge, jungle_hills, legacy_frozen_ocean, lukewarm_ocean, lush_caves, meadow, mega_taiga, mega_taiga_hills, mesa, mesa_bryce, mesa_plateau, mesa_plateau_mutated, mesa_plateau_stone, mesa_plateau_stone_mutated, mushroom_island, mushroom_island_shore, ocean, plains, redwood_taiga_mutated, river, roofed_forest, savanna, savanna_mutated, savanna_plateau, savanna_plateau_mutated, snowy_slopes, stone_beach, stony_peaks, sunflower_plains, swampland, taiga, taiga_hills, warm_ocean | +| overworld_generation | birch_forest_hills_mutated, birch_forest_mutated, cold_taiga_mutated, desert_mutated, jungle_edge_mutated, jungle_mutated, redwood_taiga_hills_mutated, roofed_forest_mutated, swampland_mutated, taiga_mutated | +| plains | plains, sunflower_plains | +| plateau | mesa_plateau, mesa_plateau_mutated, mesa_plateau_stone, mesa_plateau_stone_mutated, savanna_plateau, savanna_plateau_mutated | +| rare | jungle, mega_taiga, mesa_plateau, mesa_plateau_stone | +| river | frozen_river, river | +| roofed | roofed_forest, roofed_forest_mutated | +| savanna | savanna, savanna_mutated, savanna_plateau, savanna_plateau_mutated | +| shore | mushroom_island_shore | +| snowy_slopes | snowy_slopes | +| soulsand_valley | soulsand_valley | +| spawn_endermen | hell, soulsand_valley, warped_forest | +| spawn_few_piglins | hell | +| spawn_few_zombified_piglins | crimson_forest | +| spawn_ghast | basalt_deltas, hell, soulsand_valley | +| spawn_magma_cubes | hell | +| spawn_many_magma_cubes | basalt_deltas | +| spawn_piglin | crimson_forest | +| spawn_zombified_piglin | hell | +| stone | mesa_plateau_mutated, mesa_plateau_stone, stone_beach | +| swamp | swampland, swampland_mutated | +| taiga | cold_taiga, cold_taiga_hills, cold_taiga_mutated, mega_taiga, mega_taiga_hills, redwood_taiga_hills_mutated, redwood_taiga_mutated, taiga, taiga_hills, taiga_mutated | +| the_end | the_end | +| warm | beach, deep_warm_ocean, warm_ocean | +| warped_forest | warped_forest | diff --git a/docs/wiki/world-generation/biomes.md b/docs/wiki/world-generation/biomes.md new file mode 100644 index 00000000..f92fa817 --- /dev/null +++ b/docs/wiki/world-generation/biomes.md @@ -0,0 +1,1876 @@ +--- +title: Biomes +category: General +tags: + - guide + - experimental +mentions: + - SirLich + - solvedDev + - stirante + - Joelant05 + - destruc7ion + - SmokeyStack + - MedicalJewel105 + - aexer0e + - Apex360 + - Luthorius + - TheItsNameless + - ThomasOrs + - SmokeyStack +--- + +_Last updated for 1.16.210_ + +:::warning +As of 1.18, Custom Biomes are broken for Minecraft Bedrock +::: + +:::warning +Biome customization is _experimental_. An experimental gameplay toggle must be enabled for each world that uses behavior packs containing biome definitions. What is currently available works well if declared correctly; however, incorrectly declared components and properties may result in crashing as opposed to just logged errors. Furthermore, due to issues caused by the [inheritance model](#inheritance), the schema used for custom biomes is currently not well constructed. +::: + +:::warning +[Nether biome generation](#the-nether) is bugged as of version 1.16.210. Nether biomes are now customized via the `"multinoise_generation_rules"` component. Custom biomes, however, currently cannot generate with this component. Meanwhile, usage of the old `"nether_generation_rules"` component in vanilla overrides will result in no generation of that biome in the Nether. +::: + +Behavior packs allow for the customization of biomes. A behavior pack can either create entirely new **custom biomes** or [**overrides** for previously declared biomes](#inheritance), such as the vanilla biomes. Biomes hook into critical gameplay features, such as mob spawning, data-driven gameplay, and presentation of custom blocks. Biomes also enable a powerful system for adding decorations like flowers and trees, or even structures like towers and houses; these decorations and structures are together known as [features](#/concepts/features/), which are crucial to world generation but (generally) separate in scope and construction from biomes. + +While both overrides and custom biomes provide generally the same power, custom biomes are the recommended means for creating entirely new gameplay experiences. Overrides should retain the original biome’s identity and intentions and should only be reserved for: + +- Mild surface, heightmap, or climate adjustments +- Redistribution of biome rarity in world generation +- Addition of new features or mobs, but only if thematically appropriate + +Custom biomes should be used when _any_ unique gameplay experience is desired or if an adjustment to a previously declared biome would fundamentally change its nature. Examples of situations where custom biomes shine include: + +- A new or radical terrain is required to achieve an aesthetic. +- Custom features, like a new tree type, need somewhere to generate. +- An alternate or more challenging gaming experience is desired, potentially using new mobs and structures. + +> There are some exceptions to these recommendations due to oversights in the biomes schema. For example, it might seem as though only vanilla overrides are necessary when attempting to force a vanilla Overworld biome to generate in additional locations, but this may be impossible because of [how biomes register themselves to be generated](#regions). This means the biome’s aesthetic may have to be cloned over several iterations of biome definition files, each with their generation rules adjusted as needed. + +## Biome Definitions + +Biomes are declared in a file of the form `*biome_name*.json` or `*biome_name*.biome.json` in the top-level `biomes` directory of a behavior pack. Subdirectories may not be used within the `biomes` directory to group biome definitions; all definitions within sub-directories of `biomes` will be ignored. + +[Because identifiers must match the filename](#description), namespace collisions may occur with other biome-declaring packs. One strategy to avoid collisions is to use a reverse-domain name scheme. _biome_name_ may contain periods for grouping biomes in nested order, like `biomes/fancycraft.fantasy_realms.magical_springs.hills.mutated.json`. Here, `fancycraft` is the developer, `fantasy_realms` is the behavior pack, `magical_springs` is the [top-level biome](#heirarchy) name, `hills` and `mutated` are the [sub-biome](#subbiome-types) types, and `json` is the required file extension. (The optional `.biome` extension was omitted from this example.) + +> Invalid JSON files declared in the top-level `biomes` directory are more likely to log errors, but they may cause crashes. Non-JSON files directly placed inside this directory are ignored. If a file exists directly inside `biomes` that begins with a `.`, the game currently always crashes. This can cause problems with files such as those used for project configuration or even the infamous [.DS_Store file](https://en.wikipedia.org/wiki/.DS_Store) on macOS. + +### Format + +Like all constructed assets in a behavior pack, biome definitions are written in JSON, such as: + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:biome": { + "description": { + "identifier": "pumpkin_pastures" + }, + + "components": { + "minecraft:surface_parameters": { + "foundation_material": "minecraft:stone", + + "top_material": "minecraft:grass", + "mid_material": "minecraft:dirt", + + "sea_floor_depth": 4, + "sea_material": "minecraft:water", + "sea_floor_material": "minecraft:sand" + }, + "minecraft:overworld_height": { + "noise_params": [0.125, 0.0625] + }, + + "minecraft:climate": { + "temperature": 0.375, + "downfall": 0.25, + "snow_accumulation": [0, 0.5] + }, + + "minecraft:overworld_generation_rules": { + "generate_for_climates": [["cold", 1]], + + "hills_transformation": "pumpkin_pastures_hills", + "shore_transformation": "pumpkin_pastures" + }, + + "overworld": {}, + "pumpkin_pastures": {}, + + "animal": {}, + "monster": {} + } + } +} +``` + +> Invalid JSON — like with all aspects of addons — causes a biome definition to fail; that biome will not generate in the world. Unfortunately, no error will be thrown. A JSON validator and/or syntax highlighter easily makes this a non-problem. + +#### Format Version + + + +```json +"format_version": "1.13.0" +``` + +The top-level property `"format_version"` describes the version specification to which the proceeding schema conforms. The latest issued `"format_version"` for biomes is `"1.13.0"`. + +> A previous version for 1.12 existed but has been deprecated and is unusable in newer versions. In it, the biome identifier acted as the key for a top-level object property, which itself contained the format version, components, and tags directly. This document exclusively uses the `"1.13.0"` format, but the deprecated one may be seen elsewhere. + +The version must be of the form `*release*.*major*.*minor*`, where either _minor_ or both _major_ and _minor_ are optional. All 3 identifiers must be integers, but the completed version numbers do not have to represent a real version of Minecraft. Currently, any version number greater than or equal to `1.13.0` may be used and will refer to the `1.13.0` specification, but it is recommended to only use the value `1.13.0` or the version targeted during development: future versions may affect the overall schema. + +#### Biome Specification + + + +```json +"minecraft:biome": { + … +} +``` + +The other top-level property is `"minecraft:biome"`, which establishes the schema for the biome definition. + +##### Description + + + +```json +"description": { + "identifier": "pumpkin_pastures" +} +``` + +The `"description"` property of the `"minecraft:biome"` property is used as the metadata for the biome. It currently contains only one property, `"identifier"`, which is used to uniquely identify a biome. The value here must match the file name, sans the `.json` or `.biome.json` extensions. For example, if the identifier is `prairie`, the filename must be either `prairie.json` or `prairie.biome.json`. This identifier is used for referencing from a number of biome definition properties. + +> Unlike other aspects of addons, biomes do not accept a filename-ignored namespace prefix (such as `elysium:`) in their identifier. Such a prefix may be provided, but the file would have to contain the prefix, including the colon; such a filename is invalid on many Minecraft-supporting file systems, so this traditional namespace system should not be used. Consider a [reverse domain name system](#biome-definitions) instead. + +##### Components + + + +```json +"components": { + … +} +``` + +The `"minecraft:biome"` property also holds the `"components"` property, which is the meat of a biome definition. The components declared here place, shape, and style biomes. + +> Component details are scattered throughout the rest of this document; they cannot be as neatly described or organized as these wrapper properties due to intricacies in their interactions. + +Components are always object properties, even those that should seemingly act as booleans. For example, the `"minecraft:ignore_automatic_features"` component property is not assigned `true` or `false`, but instead an empty object, `{}`: + +```json +"components": { + … + + "minecraft:ignore_automatic_features": {} +} +``` + +Although the JSON may be invalid, properties of the same name representing components may be used within the `"components"` object. Although this situation should be avoided, it should be noted that only the last provided instance of a component will be used by the game: the values inside the earlier defined component(s) will be completely ignored. For example: + +```json +"components": { + … + + "minecraft:overworld_height": { + "noise_type": "ocean" + }, + "minecraft:overworld_height": { + "noise_params": [1.25, 0] + } +} +``` + +Despite the fact that the `"noise_type"` property would [typically completely override](#heightmap) the `"noise_params"` property, the preset will be ignored in this example due to the order of the components within the `"components”` object. + +When a component is used in a biome definition, _all_ of its required properties must be provided; if they aren’t, an error will be thrown and the biome will fail to generate. + +> Because of how the inheritance model works, if incomplete components across the inheritance chain for a biome definition would contain the properties needed to complete the schema for that component, the component will work correctly. Interestingly, this situation is not true when both components reside inside the same biome definition file. As described before, only the latter component will be used, even if it is missing required properties. + +###### Tags + + + +```json +"components": { + … + + "overworld": {}, + "pumpkin_pastures": {}, + + "animal": {}, + "monster": {} +} +``` + +In addition to the components that work to create a biome, the `"components"` property also allows for the addition of arbitrary tags. Tags appear like empty components, e.g., `"animal": {}`. Tag names must conform to the regular expression `[a-z0-9_.:]+`, that is: lowercase Latin letters, Arabic numerals, underscores, periods, and colons. + +> For future-proofing, it is not recommended to create a tag with the prefix `minecraft:` to ensure a tag does not clash with a future Mojang-defined component. Furthermore, it is suggested to use a pack-specific namespace with these tags to minimize collisions with other behavior packs, such as `"betterbiomes:arboreal"`. + +### Inheritance + +Biome definition files can act as initial definitions or overrides depending on behavior pack ordering. The earliest appearance of a biome definition in a behavior pack stack marks the creation of a custom biome; subsequent definitions of the same biome in the behavior pack stack can modify or override earlier definitions through inheritance. + +Only components and tags in the `"components"` property are inherited. Properties within an individual component are also usually inherited. Unfortunately, some components or component property objects require complete redeclaration of all their properties to work, meaning it is often better to redeclare an entire component when overriding. Inheritance always occurs unless a new component would interfere with a previously existing component, as is typically the case with [surface builders](#inheritance-considerations). + +There is no way to indicate a property should be removed from earlier definitions. This can especially be troublesome with [tags](#tagging) due to their usage in signifying biome placement and how they power other gameplay elements like mob spawning. If conflicts arise due to inheritance issues, it is recommended to extract the desired elements of a biome into a new custom biome and attempt to remove the old biome from [world generation](#generation). + +Biome files may uselessly be empty if overriding a previously declared biome. If a biome definition, initial or override, contains any components, it must contain the top-level `"format_version"` property and down to the `"identifier"` property. Initial definitions of a biome must contain at least one component or tag; the required declaration is small because defaults for almost every biome aspect are available for fallback. + +## Generation + +The rules for how a biome is selected for placement in a world depend on 3 things: + +1. The dimension(s) for which the biome registers itself +2. The potential for a biome to generate within a particular slot, relative to any other biomes also registered for that slot _across all behavior packs applied to a world at the time a chunk is loaded_ +3. The immutable random noise surfaces used by that slot that are derived from the seed of the world + +> A **slot** may represent an entire dimension or a subset of its surface area. The concept of slots does not exist in the actual documentation or schemas. This term is used here to represent a dedicated region for which a biome can be selected from a pool or where a collection of biomes are independently connected for a singular purpose. + +_Biome layout is not randomized per world, only per seed._ This means that if the same addons containing the same custom biome definitions are applied to two new worlds with the same seed, each dimension in both worlds will contain the exact same biome layout. This is obvious for vanilla generation, as the same seed will always generate the same vanilla biomes in the same places. + +Minecraft currently has no way of creating new dimensions. The End does not allow for either adding new biomes or removing the default one, leaving only Overworld and Nether customization possible. + +> The `"minecraft:legacy_world_generation_rules"` component is noted in the Mojang-provided documentation to affect legacy limited worlds, but no schema is provided for this component and no vanilla biome definition uses it, leaving its purpose and behavior unknown. + +### Overworld + + + +```json +"minecraft:overworld_generation_rules": { + "generate_for_climates": [ + ["cold", 1] + ], + + "hills_transformation": "pumpkin_pastures_hills", + "shore_transformation": "pumpkin_pastures" +} +``` + +The Overworld uses concepts of [**climates**](#climates), [**regions**](#regions), and [**hierarchy**](#hierarchy) to determine how to place biomes. + +Biomes primarily interact with Overworld generation using the `"minecraft:overworld_generation_rules"` component. Here, they can register themselves as base biomes and declare their sub-biomes. The [tagging system](#tagging) unfortunately also comes into play for slotting into [regions](#regions). + +Climates and regions form independent, non-configurable maps of slots that overlap across the Overworld. A biome with a specified climate slot and region slot can only generate in the relevant intersections of those slot maps for a seed. In other words, a biome can only generate into areas of the Overworld of matching climate and region types, the climate and region bindings restricting the surface area into which a biome may generate. Biomes can be slotted directly into these intersections as base biomes, while sub-biomes can be declared in these base biomes for finer terrain detailing. + +Biomes compete over the available area of a slot intersection using [weighting](#climates). Biome instances are actually not predetermined based on the seed; instead, the available space in the relevant slot appears divided by the weights. Biome additions to a slot intersection will therefore result in _smaller_ biomes as opposed to _rarer_ biomes; the reverse is also true. Because the size of the climate and temperature maps are not configurable, adjusting biome weightings is the only way to modify biome sizing. + +#### Climates + + + +```json +"generate_for_climates": [ + ["frozen", 2], + ["cold", 1] +] +``` + +Biomes must be aligned with temperature categories to generate as base biomes. To promote a biome to a base biome that will generate in the Overworld, the biome’s definition must have the `"generate_for_climates"` array property within the `"minecraft:overworld_generation_rules"` component. This array contains array values of the form `[*climate type*, *weight*]`, where `*climate type*` is one of five climate strings and `*weight*` is a whole number value reflecting the biome’s chance to generate. Biomes are generated by weight within each declared climate category _in the biomes’s declared [region](#regions)_, generating [sub-biomes](#hierarchy) within their bounds. + +> The climate temperatures here are different from the [float property `"temperature"`](#temperature) in the `"minecraft:climate"` component, which is used for styling rather than placement. Traditionally, however, they correlate for gameplay purposes. + +> If a float value is provided for _weight_, the value will be truncated, rounding down to the closest lesser integer. If _weight_ is set to a negative value, it will behave as though it was set to `0`. + +The 5 climates are, by increasing temperature: + +| Climate | Property value | +| :------- | :------------- | +| Frozen | `"frozen"` | +| Cold | `"cold"` | +| Medium | `"medium"` | +| Lukewarm | `"lukewarm"` | +| Warm | `"warm"` | + +> The lukewarm climate is only usable in [oceans](#basic-oceans) and [deep oceans](#deep-oceans). Land only uses the other 4 climate types. + +Biome weights act as numerators to a shared denominator for a slot intersection. As an example: + +A fictional Biome X has a weight of 5. All the biomes placed in this target slot, including Biome X, have a combined weight of 20. Therefore, Biome X will have a 5 in 20, or 25%, chance of generating. + +Vanilla biomes can typically be removed by **de-weighting**: setting the weights for their `"generate_for_climates"` property to `0` across all applicable climates. However, Minecraft actually has an [aggressive fallback system](#regions) in place to prevent generation failures caused by de-weighting, so such a strategy may not be enough to remove a biome. [De-slotting](#regions) or the addition of custom biomes may be necessary to remove a biome from generation. + +> If all biomes for a climate are set not to generate, Minecraft will use biomes from other climates to fill that climate’s designated space. The fallback system can even generate biomes that were completely de-weighted or [de-slotted](#regions) into the unused climate slot, often prioritizing climate slotting over [region slotting](#regions). Because of this, it is recommended to always have at least one biome generating per climate for at least [common land](#common-land) and [oceans](#oceans). Due to its size, [rare land](#rare-land) can be ignored: vanilla generation does not even have rare land in the frozen climate. + +Minecraft only allows the player’s first load in a select few biomes: + +- Plains +- Forest +- Taiga +- Dark Forest +- Savanna +- Jungle + +The variants of these biomes, such as Shattered Savannas and Flower Forests, also allow for player load-in. If none of these biomes are present due to de-weighting (and in the case of the Plains and Forest biomes, additionally being unlisted as [sub-biomes of Deep Oceans](#islands)), the player usually will not be able to load in to the world: the game most often will search for a valid spawn location endlessly. + +> In some rare, inexplicable cases, the player will be thrown into a biome not ordained for player loading at the world origin after enough time has passed attempting to find a valid load-in spot. + +Unlike [region slots](#regions), biomes can be registered for multiple climates. This can, for example, be used to spread a biome across different climates if it would be appropriate. An example is the Plains biome, which is spread across 3 climates: + +biomes/plains.json + +```json +"generate_for_climates": [ + ["cold", 1], + ["medium", 3], + ["warm", 1] +] +``` + +If the same biome generates in two adjacent climates and these separate biome instances are next to each other, the biome will seem to combine into one with no indication of the boundaries of a climate region. + +#### Regions + +The Overworld is composed of many regions, which behave as slots for biome placement. Obviously split by land and oceans, the dedicated slots relate in a complicated fashion. + +> The nature of a biome (its aesthetic and gameplay) do not have to conform to the intention of the region in which they are placed. The “land” and “ocean” region names used here are therefore slightly misleading: biomes slotted into the [land region](#land) can be aquatic, and those slotted into [oceans](#oceans) can represent land. These are only named as such here in reference to vanilla generation. + +[As noted](#climates), biomes are directly placed into the Overworld using the `"generate_for_climates"` property in the `"minecraft:overworld_generation_rules"` component, but the values given here only affect the climate slot map. Configuring a biome to generate in a particular region is unintuitive and even undocumented by Mojang. The Overworld depends on the existence of [specific tags](#overworld-generation-aspects) to slot biomes on the region map. + +In certain circumstances, biomes can be **de-slotted** from their region in the Overworld, forcing them to generate as part of a higher priority slot. This change is irreversible by later listed behavior packs, as it relies on the [biome definition inheritance model](#inheritance). Minecraft uses an aggressive fallback system that attempts to prevent generation failures when no biomes are registered for a slot intersection. Due to the aggressiveness of the fallback system, de-slotting is in some circumstances the only means of removing an unwanted biome; [de-weighting](#climates) may not be enough. + +##### Land + +Unlike the real world, land makes up the majority of the Overworld. Land technically contains several odd sub-slots because of a mix of interactions and restrictions with oceans. As noted above, land biomes do not actually have to represent land: this is only the designation for the slot; they can be aquatic or contain ocean sub-biomes. + +There are a total of 56 vanilla land biomes, many of which are mutated or hilly forms of base biomes. + +###### Common Land + + + +```json +"generate_for_climates": [ + ["cold", 1] +] +``` + +Common land is the largest slot in the game, making up the vast majority of land. The majority of biomes in Minecraft are slotted here, such as Deserts, Dark Forests, Plains, and Swamps. _By default, all custom biomes are slotted into common land unless marked otherwise._ + +``` + When all common land biomes are instructed not to generate by setting their climate weights to `0`, Minecraft fills this slot using biomes from the [rare land](#rare-land) slot, beginning with Eroded Badlands and Giant Tree Taigas. If these biomes are then de-slotted and also set not to generate, the game descends down a fallback list of biomes: + +- Jungle variants +- The remaining Giant Tree Taiga variants +- Mushroom Fields +- Birch Forest variants +- The remaining Badlands variants +- Desert variants +- Custom biomes and their variants +- Forest variants +- Ocean variants + +The fallback biome will then generate across the entirety of land in the Overworld. The variants selected for this list may even typically act as sub-biomes in unmodified generation. Ocean biomes are the final fallback for land because of tag inheritance: there is no way to de-slot ocean biomes into the ocean slot, as they already have the `"ocean"` tag in their vanilla definitions. Rare biomes will continue to be slotted in rare land slots until they are de-slotted into oceans. +``` + +###### Rare Land + + + +```json +"minecraft:overworld_generation_rules": { + "generate_for_climates": [ + ["medium", 1] + ] + + … +}, + +"rare": {} +``` + +Rare land slots are somewhat large but very uncommon regions of the Overworld set aside for biomes. Biomes are slotted here when the `"rare"` tag is applied to them. Examples of rare biomes in vanilla generation include Jungles in the medium climate, Mesas in the warm climate, and Giant Tree Taigas in the cold climate. No rare land exists in vanilla generation for the frozen climate, but this can be added via customization: + + + +```json +"minecraft:overworld_generation_rules": { + "generate_for_climates": [ + ["frozen", 1] + ] +}, + +"rare": {} +``` + +> Rare land biomes can be de-slotted by applying the `"ocean"` tag to the declaration. This is because the `"ocean"` tag takes precedence over the `"rare"` tag. If no `"rare"`-tagged biome is available for an instance of rare land in a given climate due to de-slotting, the game will fall back to compatible common land biomes. This situation naturally occurs in the frozen and lukewarm climates, where there are no vanilla rare biomes. If, however, a rare land biome was only [de-weighted](#climates) for a particular climate, it is still possible for that biome to generate if no other biomes are available for those climates. + +##### Oceans + +The rest of the Overworld is covered in oceans. Oceans are a misnomer as they do not fully connect through the world; in Minecraft, the land region instead behaves like this to give the player more room, causing oceans to behave more as seas or lakes. Biomes are slotted into the ocean region by using the `"ocean"` tag. + +The oceans are prevalently split by normal and deep depths with about equal weight. Scattered islands can generate inside the ocean region. By default, there are ten ocean biomes in total: one for each combination of the five temperatures and two depths. Ocean biomes do not have to actually generate as aquatic biomes; they can be land. Furthermore, oceans can contain land sub-biomes. Plains, Forests, and Beaches, for example, are not exclusive to oceans but can generate as a part of ocean islands, themselves contained within the ocean regions. + +> Ocean weighting behaves differently from other distributions. Seemingly, oceans weren’t intended to compete for space: vanilla biomes have exclusively one ocean biome for each depth-climate combination. Competing oceans of similar weights are separated on a very small scale: approximately several blocks across each instance. A greater difference in weights does more cleanly separate competing biomes, but the lesser-weighted biome will still only generate in very small clumps. Generally, it is wiser to use [surface adjustments](#surface-adjustments) or [features](#features) to transform oceans. + +> If all oceans are set not to generate via [de-weighting](#climates), the game falls back to Frozen Ocean and Deep Frozen Ocean. Because of this fallback, the addition of a custom biome may be the only way to remove all the vanilla ocean biomes + +###### Basic Oceans + + + +```json +"minecraft:overworld_generation_rules": { + "generate_for_climates": [ + ["lukewarm", 1] + ] +}, + +"ocean": {} +``` + +The basic oceans make up about half of the ocean region. This region is intended to be used by aquatic biomes with a relatively shallow depth. + +> [Despite how deep ocean slotting occurs](#deep-oceans), a vanilla basic ocean biome cannot be de-slotted using the `deep` tag. It will continue to generate unless it is [de-weighted](#climates). + +###### Deep Oceans + + + +```json +"minecraft:overworld_generation_rules": { + "generate_for_climates": [ + ["frozen", 1] + ] +}, + +"ocean": {}, +"deep": {} +``` + +Biomes slotted into the deep ocean region use the `deep` tag in addition to the `ocean` tag. Deep oceans make up most of the space remaining in oceans. This slot is typically used with oceans extending deeper than others, often halfway to bedrock from the surface. + +> The `"deep"` tag on its own has no effect on generation or spawning; it must be used alongside `"ocean"`. + +###### Islands + +biomes/ocean.json + +```json +"minecraft:overworld_generation_rules": { + "hills_transformation": "tropical_island" +}, +``` + +Conceptually, islands are no different from sub-biomes in the land region. The islands that generate in vanilla are actually just “hills” in oceans! + +> While these islands do not technically form a slot and are instead sub-biomes, due to what is either a bug or an oversight, they are noted as a slot due to how they must be declared. Islands are never declared for a custom ocean biome and can only be separately grouped by ocean depth. Islands are declared using either the `hills_transformation` or `mutate_transformation` properties in the `minecraft:overworld_generation_rules` component _only_ in override definitions for the `ocean` and `deep_ocean` biomes (even if these vanilla oceans have been [de-weighted](#climates)). Islands can also be declared as [mutated hills](#mutated-hills) if rarity is desired. Islands in vanilla only generate using hills sub-biomes and only in Deep Oceans; vanilla islands can therefore entirely be disabled by pointing the `hills_transformation` in an override for Deep Oceans to the Deep Ocean biome itself: + +biomes/deep_ocean.json + + + +```json +"minecraft:overworld_generation_rules": { + "hills_transformation": "deep_ocean" +}, +``` + +Because of [how shores are prioritized when generating land](#shores), islands in the ocean may form entirely as shores unless those shores are disabled. Islands may also have their own river sub-biome; the vanilla islands and all custom biomes by default use Rivers. + +##### Mushroom Fields + +Very rarely, Mushroom Fields generate within ocean regions as their own slot. The Mushroom Fields biome itself can be disabled via de-slotting by adding the `"ocean"` tag to the biome. The Mushroom Fields Shore biome, however, cannot be [disabled by any means](#exceptions) and will cover the slot in entirety when the main biome is de-slotted; this is the only biome in the Overworld whose placement is immutable. Attempting to de-slot the Mushroom Fields Shore biome into the ocean seems to work at first, but the biome will simultaneously continue generating in the mushroom fields slot. + +> If Mushroom Fields are unwanted in a world, changing their style — most conveniently by making them to fit in with surrounding ocean — is the only course of action. + +#### Hierarchy + + + +```json +"minecraft:overworld_generation_rules": { + … + + "hills_transformation": [ + ["overgrown_forest_hills_short", 4], + ["overgrown_forest_hills_tall", 1] + ], + "shore_transformation": "rocky_shore" +} +``` + +Overworld biomes may directly or indirectly be placed by the world generator. Biomes placed directly are here referred to as **base biomes**, while those that are placed indirectly via a base biome will be called **sub-biomes**. + +If declaring a target climate temperature in the `"generate_for_climates"` property, a biome will behave as a base biome. Biomes placed directly are generally large. + +All of a base biome’s sub-biomes will exist within the bounds of the base biome and lie within its associated slot intersection. These sub-biomes therefore are indirectly placed, not declaring their own generation in the Overworld but instead relying on a base biome’s generation. + +> Biomes may be referenced without limitation: they may appear as a base biome and simultaneously be a sub-biome to multiple other biomes. + +Sub-biomes _never_ inherit any aspects of their referencing biome. If the sub-biome should appear or behave in a manner similar to its referencing biome, it must redeclare the relevant components to do so. + +##### Weighting + + + +```json +"mutate_transformation": [ + ["crater", 2], + ["lava_pit", 1] +] +``` + +Multiple sub-biomes may be declared for each transformation type. They may be given integer-valued weights when declared in a base biome to vary their occurrences. For example, the hills sub-biome is really just a small, common subregion of a base biome, so it can be used to form many different scenes. A single base biome may have, for example, both hill and lake “hills” sub-biomes. + +> Truncation occurs when float values are used for the weights. A weight of `0.5`, therefore will behave as a weight of `0` and not generate. + +The base biome may be referenced from its own weighted sub-biome declarations. [Like with base biome weights](#overworld), this has the effect of decreasing the available space afforded to actual sub-biomes, making them smaller in surface area as opposed to making them rarer by count. For a hilly base biome using hills sub-biomes, this could be used to make small, rare mountain peaks. For a dry, warm base biome using river sub-biomes, rivers could sporadically appear dried up without having to depend on hills or mutated sub-biomes. + +##### Overriding + +When overriding a previous biome definition, the value set to a particular sub-biome type — whether it is a direct biome reference or an array of weighted references — will fully replace any previous definitions for that type. This means that if multiple sub-biomes for a type were provided in both an earlier definition and a new override, the old sub-biomes will be completely overwritten with the new ones as opposed to adding to them. + +For example, if an earlier definition declared: + + + +```json +"hills_transformation": [ + ["rolling_hills", 2], + ["spiky_hills", 1] +] +``` + +And a new definition declared: + + + +```json +"hills_transformation": [ + ["tall_hills", 1], + ["short_hills", 1] +] +``` + +Only the `"tall_hills"` and `"short_hills"` sub-biomes will generate as hills transformations. The previous listing is _entirely_ ignored. If both sets are to be used together, the previous sub-biomes must be redeclared in the new definition: + + + +```json +"hills_transformation": [ + ["rolling_hills", 2], + ["spiky_hills", 1], + ["tall_hills", 1], + ["short_hills", 1] +] +``` + +##### Sub-Biome Types + +Base biomes may declare their own sub-biomes of these categories: + +| Transformation | Property value | +| :------------- | :------------------------ | +| Hills | `"hills_transformation"` | +| Mutated | `"mutate_transformation"` | +| River | `"river_transformation"` | +| Shore | `"shore_transformation"` | + +[Hills](#hills) and [mutations](#mutations) are fixed, scattered, bounded regions that may have their own sub-biomes, including [mutated hills](#mutated-hills). [Rivers](#rivers) form thin, unchangeable stretches that are spread throughout the world. The placement of [shores](#shores), meanwhile, is indirectly influenced by other biomes; they form the divide between land and oceans. + +Nesting sub-biomes has no effect. Hills cannot have further hills. The same goes for all sub-biome types. Hills, mutations, and mutated hills may all declare their own river and shore sub-biomes allowing for finely tuned changes on a sub-biome scale. Rivers and shores do not generate any sub-biomes. + +###### Hills + + + +```json +"hills_transformation": "pumpkin_pastures_hills" +``` + +Hills sub-biomes are small, common subsets of a biome generally used for elevation shifts. Despite their name, they do not have to be used to generate hilly terrain. Their chance to generate within a base biome is common enough that they can reliably be used to form large, natural generations such as lakes, craters, and more. Hills sub-biomes are used in the vanilla Deep Ocean biome to generate islands. Hills have no default value; no changes occur in generation when not declaring a hills sub-biome. + +###### Mutations + + + +```json +"mutate_transformation": "mushroom_forest_dense" +``` + +Mutated sub-biomes are large, rare subsets of a base biome that are typically used for odd variations. One vanilla example is Sunflower Plains; another is Ice Spikes. Unlike the other dependently generated biome categories, mutated sub-biomes do not generate reliably. They should not be used with an expectation that they will generate within an instance of a base biome. Like hills sub-biomes, if no mutated sub-biome is declared, no transformation will occur. + +###### Mutated Hills + +biomes/mangrove_forest.json + +```json +"hills_transformation": "mangrove_forest_hills" +``` + +biomes/mangrove_forest_hills.json + +```json +"mutate_transformation": "mangrove_forest_hills_mutated" +``` + +Hills sub-biomes may declare their own mutated sub-biomes, effectively creating a mutated hills sub-biome. This very rare sub-biome generation allows all the same interactions as hills or mutated sub-biomes including having its own river and shore. + +> Mutated hills **do not** generate if a _hills_ sub-biome is declared as part of a _mutated_ sub-biome. + +###### Rivers + + + +```json +"river_transformation": "riverbed_dry" +``` + +Rivers exist in dedicated spaces fixed to the seed of a world and are unchangeable via behavior packs. While the shape of rivers technically run everywhere in the Overworld, they only generate when intersecting with a land biome. The intersecting land biome declaration can specify a river sub-biome to apply to the stretches allocated for river generation. While the widths of rivers are not configurable, rivers may appear wider with lower [heightmap](#heightmap) configurations. + +By default, Minecraft uses the River biome if the `"river_transformation"` property is not declared as part of the `"minecraft:overworld_generation_rules"` component or if this component is not declared at all. To effectively remove rivers from a biome, the `"river_transformation"` property can point to the declaring biome itself via its identifier: + +biomes/ivory_shallows.json + +```json +{ + "format_version": "1.13.0", + + "minecraft:biome": { + "description": { + "identifier": "ivory_shallows" + }, + + "components": { + … + + "minecraft:overworld_generation_rules": { + … + + "river_transformation": "ivory_shallows" + } + } + } +} +``` + +This retains the biome’s surface builder and its specified blocks, heightmap, climate, etc., along the river’s route, generating the declaring biome smoothly without interruption. Rivers declared in a biome with the `ocean` tag have no effect on world generation; [slotting tags](#overworld-generation-aspects) added to a biome are ignored when it is used as a river. + +When multiple rivers are given to the `"river_transformation"` property, river generation will transition rapidly between the listed biomes. At equal weights, the rivers will transition every 6–8 blocks. With greater discrepancy between weights or a greater number of river sub-biomes, rivers may only generate across a few blocks before transitioning to another river biome. Use care when generating multiple river sub-biomes: generally only one should be used per base biome. + +###### Shores + + + +```json +"shore_transformation": "cliffs_steep" +``` + +Shores are special stretches of land designated to generate between a land biome and ocean biomes: biomes without the `ocean` tag and those with it. Because these locations vary under customized biome definitions, shores are the only sub-biome whose location can be influenced. This is not merely restricted to the major land and ocean regions of the Overworld but can also be used between conflicting sub-biomes. Alternations such as these could be used to generate large, shallow lakes with shores or even a transition biome between [what appears to be](#oceans) two land biomes. + +Like rivers, shores are declared as part of a land biome, this time using `"shore_transformation"`. The shores that generate between land and ocean biomes are _always_ selected from the land biome; adding shores to oceans has no effect on generation. [Slotting tag](#overworld-generation-aspects) additions have no effect on shores. Shores default to Beaches and can again be effectively removed by referencing the declaring biome: + +biomes/lava_fields.json + +```json +{ + "format_version": "1.13.0", + + "minecraft:biome": { + "description": { + "identifier": "lava_fields" + }, + + "components": { + … + + "minecraft:overworld_generation_rules": { + … + + "shore_transformation": "lava_fields" + } + } + } +} +``` + +If removed, the base biome will ease into the ocean at a slightly steeper angle, ignoring sandy shores in favor of the blocks used by the base biome’s [surface builder](#surface-builders). + +Shores are always prioritized against their referencing biome when space is small. If an area of the Overworld surface designated for a land biome would be sufficiently small, the resultant generation may just be shore, with no hint of the referencing biome in sight. This is often the case for vanilla ocean islands. + +When multiple shores are given as sub-biomes, generation can rapidly transition between them. In the lightest case — 2 shores of equal weight — the game will switch biomes every dozen to 2 dozen blocks. With more shores or larger weight discrepancies between shores, sub-biomes may become too small to be useful. More than likely, only one shore will be enough for a base biome. There are, however, some exceptions to this, such as if one shore had simple sand and a second shore were to be lightly decorated with rocks or boulders. + +##### Exceptions + +The Mushroom Fields biome cannot have river or shore sub-biomes. [The shore that generates along its coast is unremovable](#mushroom-fields); the shores dividing Mushroom Fields from its sub-biomes marked as oceans will always be Mushroom Fields Shore. The mutations Mushroom Fields does allow can have their own river and shore sub-biomes, but this is not recommended, as the mix of biomes here can become messy in such a small space. If the Mushroom Fields biome [is de-slotted](#mushroom-fields), the Mushroom Fields Shore will act as a base biome in the mushroom fields slot and may then have its own sub-biomes. + +### The Nether + + + +```json +"minecraft:nether_generation_rules": { + "target_temperature": 0.5, + "target_humidity": 0.75, + "target_altitude": -0.25, + "target_weirdness": 0, + "weight": 0.1 +} +``` + +Nether generation is far more pure and allows for far greater control than the Overworld, but this comes at the cost of significantly increased complexity. [Arbitrary systems](#strategies-considerations) should be constructed on top of [the powerful provided mathematical system](#principles) for a functioning Nether layout system to work. + +#### Principles + +Unlike the Overworld, which defines fixed overlapping slot maps for placing biomes by random chance, the Nether uses a 4-dimensional “multi-noise” biome layout system where biomes are always placed directly; no sub-biomes exist in this dimension. + +> As described in [Aspects & Targets](#aspects-targets), a biome may completely encapsulate another biome (akin to [sub-biomes](#sub-biome-types)) if both biomes are configured for this to happen. + +> Despite its appearance, Nether biomes only generate depending on the _x_ and _z_ coordinates with all _y_ values at those coordinates belonging to the same biome; it is not currently possible to place a biome vertically adjacent to another biome in the Nether. + +##### Aspects + +In the Nether’s multi-noise system, 4 independent values are assigned to every _x_-_z_ location in the Nether based on the world seed using [Perlin noise](https://en.wikipedia.org/wiki/Perlin_noise) curves, which generate values on the closed interval [-1, 1]. These values remain constant across worlds of the same seed if the Nether-declaring biomes across all applied behavior packs remain constant — they will not change per world otherwise. For convenience, these independent values will be described here as **aspects**; the documentation does not use this vocabulary. These four aspects are assigned arbitrary names for usage in behavior packs and “targeted” by a biome definition with the following properties: + +| Aspect | Targeting property | +| :---------- | :--------------------- | +| Temperature | `"target_temperature"` | +| Humidity | `"target_humidity"` | +| Altitude | `"target_altitude"` | +| Weirdness | `"target_weirdness"` | + +> The names have no correlation to the properties of a biome, i.e., setting a larger `target_temperature` will not result in a warmer climate for that biome. These names are merely a way to refer to the independent aspects. [The names can be disregarded or reinterpreted as desired.](#separation-of-concerns) + +###### Aspect Properties + +Values generated by Perlin noise exist on the interval `[-1, 1]`, but the distribution between the extremes is not even. Perlin noise on such an interval tends to distribute similarly to a bell curve with a standard deviation of about 0.4, leading to a couple of obvious conclusions: + +- Values closer to `0` are more likely to generate; values closer and closer to the extremes become _much_ less likely. +- The distribution is effectively symmetrical around `0`, yielding 2 even “paths” of rarity. + +Because Perlin noise is an interpolated process, each aspect will be smoothly generated. This means that a generated noise curve for the Nether based on the _x_ and _z_ coordinates conforms to the [Intermediate Value Theorem](https://en.wikipedia.org/wiki/Intermediate_value_theorem): values for that dimension must smoothly transition between local maxima and minima. + +> Currently, the way coordinates are mapped as inputs to the Perlin noise generators cannot be changed. This means that the distance along the horizontal plane (the _x_ and _z_ coordinates in the Nether) between local extrema is fixed; conveniently setting all biomes to be larger or smaller is impossible. Biomes may, however, appear sufficiently large with a small number of Nether-registered biomes and vice-versa. + +As an example of these properties, consider a scenario where only the 5 vanilla Nether biomes generate. [Isolating a single aspect](#ignoring-aspects) for the example, temperature, all other aspect targets will be set to `0`. The vanilla biomes will be mapped to temperatures as such: + +| Biome | Temperature | +| :-------------- | ----------: | +| Soulsand Valley | `-1` | +| Warped Forest | `-0.5` | +| Nether Wastes | `0` | +| Crimson Forest | `0.5` | +| Basalt Deltas | `1` | + +This means that Soulsand Valleys and Basalt Deltas act as extremes; they will be isolated and uncommon and form simple, often convex shapes. In the middle, Nether Wastes will often wind seemingly endlessly in a loose, wavy shape. The two forests will form large rings between the mean and extremes. In other words, because of interpolation, a player would have to move through the Warped Forest, Nether Wastes, and Crimson Forest biomes in that order to reach a Basalt Delta from a Soulsand Valley. + +Unfortunately, actual generation is much less convenient to understand. With 4 dimensions, configurability of target matching, and virtually no limit on biome count, it can be much more challenging to create a compelling Nether layout. However, by [understanding targeting](#targeting) and [constraining and isolating target values and fine-tuning the weightings](#strategies), an interesting layout can be achieved with minimal trial and error. + +##### Targeting + +With particular values set for each aspect at a spot in the Nether, Minecraft then uses biome definitions to determine which biome will be selected for generation. Unlike the Overworld, the same biomes will always generate for the same target values; there is no hidden randomness here. This is because the game uses a formula to determine the biome whose aspect targets most closely match the values at a given position. The declared targets never change in a game session, so that biome would always be selected for those values. + +> The exact formula used to determine the closest matching biome to a set of values is unknown. It can be expected to be either a simple sum of absolute value differences or a 4-dimensional distance formula. + +It can therefore be understood that every Nether biome shares a portion of the 4-dimensional space that is formed from the intersections of valid aspect values. The divides between these forms are derived from the aspect targets of “adjacent” and therefore competing biomes. + +Again [considering a single aspect](#ignoring-aspects) (Aspect 1) for the sake of simplicity, imagine attempting to distribute 3 biomes: Biome A, Biome B, and Biome C. Because of how targeting finds a closest match, success intervals are formed based on the targeted values, which is what will ultimately decide where a biome generates. + +As one specific example, imagine targeting the most extreme values on the range: + +| Biome | Aspect 1 target | Success interval | +| :------ | --------------: | ---------------: | +| Biome A | `-1` | [-1, -0.5] | +| Biome B | `0` | [-0.5, 0.5] | +| Biome C | `1` | [0.5, 1] | + +In this case, even though the targeted values are evenly spread along the range, the intervals derived from these values are not the same size. This is because the targets are pushed to the limits of the range, with midpoints between the targets of means and extremes existing at -0.5 and 0.5; it is these 2 values that ultimately divide the resultant intervals. In this scenario, Biome B will be very prevalent across the Nether, while Biomes A and C will be noticeably less common. + +Attempting to evenly distribute the intervals by approaching the problem in reverse reveals that the full noise range can be divided into thirds via [-1, -1/3], [-1/3, 1/3], [1/3, 1]. The targets must then be evenly spaced around the breakpoints, resulting in: + +| Biome | Targeted Value | Success Interval | +| :------ | -------------: | ---------------: | +| Biome A | `-0.667` | [-1, -0.333] | +| Biome B | `0` | [-0.333, 0.333] | +| Biome C | `0.667` | [0.333, 1] | + +The space (in this case just intervals on a line segment) is now evenly divided, showing how the spatial boundaries are formed between targets. + +> _However, even with the intervals being evenly spaced, [noise distribution](#aspect-properties) will still ensure the biomes don’t evenly take up 1/3 of the Nether!_ Biome B here will still be the most common, but Biomes B and C will appear more frequently than the first example. To truly evenly distribute biomes such that each would have about a 1 in 3 chance of generating, both the success interval and the noise distribution must be taken into consideration. In this example, intervals of [-1, -0.25], [-0.25, 0.25], and [0.25, 1] would approximately evenly distribute the three biomes across the Nether. + +###### Targeting Adjustment + +Biomes can also declare a fifth property in the `"minecraft:nether_generation_rules"` component to affect biome matching, `"weight"`, which can require the aspect values to more closely align with the biome’s aspect targets for the biome to generate. Weight is designed to behave on the interval [0, 1], where 0 causes the matching to behave as normal, and 1 will require an _exact_ match for the biome to generate. + +``` +Because exact matches are exceptionally rare and take up only an infinitesimal space on the map, a value of `1` will effectively disable a biome from generating unless all other biomes have radical weights, too. Using values outside the intended interval will result in further extreme situations, with only one biome of a set of radically weighted biomes being able to generate. + +It is therefore not recommended to set this property outside its intended range unless removal of a previously declared biome is desired. In such a case, a value of `1` should suffice; this strategy is akin to [de-weighting Overworld biomes](#climates). + +In the extreme case that all Nether-registered biomes are displaced with equal `"weight"`, Minecraft falls back to a single biome across the Nether in the following order based on availability: + +- Nether Wastes +- Soulsand Valley +- Crimson Forset +- Warped Forest +- Basalt Deltas +- Custom biomes +``` + +Weight adjustments can therefore only decrease a biome’s size. These adjustments are helpful when using a biome to transition between two other biomes. While a biome may be made smaller by adjusting its aspect targets, this can cause a chain reaction of constantly having to revise targets in other biomes because of how they all influence each others’ generation. Using `"weight"` is a simple, singular action. + +> Constantly using weight adjustments, however, can make the system even more complicated to understand, as an additional property will have to be taken into consideration everywhere it is used. For this reason, weight adjustments should be used sparingly. A general rule is to never use it in “successive” biomes: biomes that target more or less the same aspect values; leave the `"weight"` property to one side or the other. + +If multiple Nether biomes have the same exact aspect targets, only one of them will generate. If a targeting adjustment is given with the `"weight"` property, the biome whose `"weight"` is closest to `0` will be selected, and the other biomes will never generate. If multiple biomes are equally distant from `0`, a fixed order is used to determine the single biome that will always generate for those targets. + +> The system used for prioritizing a biome for generation under equal targets and effective weights is unknown. The biome selected does not change with each instance of a world or even a seed, so presumably it is based on the filename or biome identifier, perhaps taking behavior pack ordering into consideration, too. + +#### Strategies & Considerations + +In a vague mathematical system of unseeable values, it can be difficult to decide how to lay out the Nether. When going further and reinterpreting the aspects, there is no set direction, which can lead to an endless cycle of property readjustments. It is therefore paramount to establish strategies before beginning. + +> Due to the arbitrary nature of meaning used in the Nether, any custom system only works when all Nether-declaring biome definitions are “on the same page”. Such a system fails when biome definitions from other behavior packs follow their own agenda. Interpretations must be conservative when Nether-altering behavior packs may compete. + +> [Unlike the first player load in the Overworld](#climates), custom biomes to not need to be taken into consideration for when a player loads into the Nether anywhere via a portal; the player can enter any Nether-registered biome when first traveling through a Nether Portal. + +##### Separation of Concerns + +Because the aspects are completely independent and their given names are meaningless, the aspects can be reinterpreted as any system of independent properties. In a grimmer Nether, these aspects could be something like: + +| Actual targeting property | Reinterpretation | +| :------------------------ | :---------------- | +| `"target_temperature"` | Corruption | +| `"target_humidity"` | Living/dead ratio | +| `"target_altitude"` | Soul affinity | +| `"target_weirdness"` | Spitefulness | + +In a Nether reinterpreted as an extension of the bottom of the Overworld, the aspects could be: + +| Actual targeting property | Reinterpretation | +| :------------------------ | :----------------- | +| `"target_temperature"` | Temperature (same) | +| `"target_humidity"` | Darkness | +| `"target_altitude"` | Richness | +| `"target_weirdness"` | Dangerousness | + +So long as the arbitrary meanings always match the property names, any custom system can be used. Only after establishing the meaning of the aspects can the actual assignments of aspect targets commence. + +###### Ignoring Aspects + +Aspects can effectively be ignored for the sake of generation. By setting all targets of an aspect across all biomes definitions to the same value, such as `0`, that aspect will not play a role in determining biome layout. This can be the right option for several use cases: + +- A total of four independent parameters are not required to achieve an effect. +- Only a small number of biomes need to be considered. +- [Simple, dependable biome transitions](#containment-transitions) are desired. + +If any of these conditions are true, some aspects should be ignored to ease development. Vanilla generation itself ignores 2 of the 4 aspects, altitude and weirdness. + +###### Arbitrary Aspect Types + +It can be challenging to ensure all biomes can generate [due to uniqueness requirements in biome generation under a multi-noise layout system](#targeting-adjustment). Values can be arbitrarily adjusted per-aspect, but it is cleaner and easier to impose uniqueness expectations onto each aspect, creating non-unique and unique aspects. + +Non-unique aspects may have values that are not guaranteed to help uniquely place a biome. One usage of this is [tiered aspects](#tiering). Unique aspects, meanwhile, are to be used to find a distinct set of conditions in the Nether for a biome to generate. + +When using such a methodology, at least one unique aspect must be used. Beyond the guaranteed one unique aspect, any of the other aspects may be unique or non-unique, but this system affords the most potential when only one aspect is expected to contain unique values. + +##### Rarity + +There are two primary means of establishing the rarity of Nether biomes: per-aspect rarity and the designation of one of the aspects to represent rarity itself. The latter method enables complete control over biome weighting, not too dissimilar to [the Overworld’s layout](#overworld). + +###### Per-Aspect Rarity + +Per-aspect rarity refers to how each aspect, no matter its functional use case or arbitrary interpretation, is [independently distributed](#aspect-properties). This distribution must be taken into consideration when targeting aspect values. With 2 symmetrical distributions of rarity with Perlin noise generations, competition for available space on an interval is typically a non-issue; the negative values can be targeted if the positive values become too cluttered. A [tiering](#tiering) plan for rarity can further ease pains caused by constrained space. + +###### Independent Rarity Aspect (Weighting) + +[Usage of a unique aspect](#arbitrary-aspect-types) works especially well for setting weights for Nether biomes like how the Overworld generation works. In this system, one aspect, such as weirdness, is [re-designated](#separation-of-concerns) to represent weight. Assuming the other 3 aspects are non-unique and used to represent standalone properties of a biome, this weighting can be used to pick a particular biome dependent upon the [distribution of Perlin noise](#aspect-properties) for that re-imagined aspect. + +Generally, a meaningful selection of the other aspects shouldn’t necessitate great complexity within the weight aspect, but if there are a large number of possibilities desired for a given combination, the uniqueness of values and computed target intervals must also be considered. Essentially, every weight for a given combination of the other aspects must be unique [due to uniqueness requirements](#targeting). With this uniqueness in mind, the intervals derived from these targets need to be carefully spread to get the desired weightings exactly right. [Targeting adjustments](#targeting-adjustments) are useful here, but the weights may need to be adjusted across all biomes targeting the same combination when a new biome is added to the set. + +When no weights are needed for a combination of the non-unique aspects because only one biome matches the conditions, a value of `0` should be targeted. This gives the maximum berth possible for that biome to generate, helping to avoid interference from unwanted biomes. + +> Because masking of aspects does not exist in the Nether, this weighting system is susceptible to some minor failures caused by [the function that calculates distance in the 4-dimensional map of aspect target spaces](#targeting). For a given set of values for a point in the Nether, if a target weight is far enough from the actual value of that aspect at that point when the other 3 aspects are well-targeted, the discrepancy may cause the system to pick an undesired biome. In other words, usage of a weighting aspect is not rigid or guaranteed. However, the biome selected by the system will still be well-targeted and appropriate for the values, and the intended biome may very well show up with a smaller surface area nearby, so this system’s failures are mild. + +##### Tiering + +Tiering can be used to assign descriptive, qualified meaning to quantifiable values. Tiering further helps Nether biome development by imposing a sort of “schema” to which all targeting values for an aspect should conform. + +Using the Overworld climates as an example, one could assign numbers to temperature meanings, like the following: + +| Climate | Temperature | +| :------- | ----------: | +| Frozen | `-0.6` | +| Cold | `-0.25` | +| Normal | `0` | +| Lukewarm | `0.25` | +| Warm | `0.6` | + +In this system, all values of this aspect across all Nether-declaring biomes should be expected to use these values. Such a system would both ensure “colder” biomes won’t generate near “warmer” biomes while also conveniently allowing for [clustering](#clustering-avoidance) of similar biomes without worrying about uniqueness. At any given time, this “schema” may be extended with additional meanings, like a “flaming hot” definition with a value of `0.8`. + +##### Transitions + +As described in [Aspect Properties](#aspect-properties), transitions are guaranteed to occur across a single aspect when all other aspects are [ignored](#ignoring-aspects). This can lead to long transitions or “shorelines” between biomes, depending upon the sizing of the intervals and the targeting adjustment. Achieving this effect becomes non-trivial when only adding one more aspect to consider and almost always unmanageable when using more than 2 aspects. + +Regardless of implementation difficulty, the behaviors at play are simple to understand. Because the aspects are independent and each follows the Intermediate Value Theorem, transitions across the surface of the Nether are independently smooth _across every aspect_. When using multiple aspects in Nether generation, the transition between a point and another nearby point may result in changes across any of the aspects from one to another. [Because biomes always generate under the same conditions in the Nether](#targeting), every single aspect leading into to a target biome would have to be considered for a transition to occur to that target. + +As an example, if a biome had the following Nether generation rules: + + + +```json +"minecraft:nether_generation_rules": { + "target_temperature": 0.2, + "target_humidity": -0.6, + "target_altitude": 0.4, + "target_weirdness": 0, + "weight": 0 +} +``` + +Assuming the weirdness aspect was ignored, a transition biome would have to occur for every combination before and after each of the other 3 target aspects. Because a single biome definition cannot target multiple spots in the Nether, 8 different definitions (1 positive and 1 negative for each combination of the 3 relevant aspects) would have to be created and well adjusted to act as transitions into this target biome. Furthermore, if any of the aspect targets in this biome changed, all transition biome definitions would have to be updated to accommodate the change. + +There are, however, two different scenarios where transition biomes can be used with minimal effort or complications. + +###### Corner Transitions + +Corner transitions can occur when the biome targeted for transitioning exists at the absolute extremes of the used aspects. An example is if the target biome targeted values of +/-1 for every used aspect. In this case, a transition biome could be created by placing values “right in front of” the target biome, like at +/- 0.8 for the same aspects. + +As an example, if at target biome had the following targets (with the other 2 being ignored): + + + +```json +"target_temperature": 1, +"target_humidity": -1 +``` + +A transition biome could be established using: + + + +```json +"target_temperature": 0.8, +"target_humidity": -0.8 +``` + +###### Tiering Transitions + +Tiering transitions can be used in a [tiering system](#tiering) to separate otherwise strongly opposing tiers. Unlike corner transitions, tiering transitions are fallible due to the nature of biome selection in the Nether and how available space is delegated for aspect targeting. + +If a tiered aspect had the following schema: + +| Life force | Value | +| :--------- | ----: | +| Undead | -0.8 | +| Virile | 0.8 | + +A transition mixing these two extremes would help the change between the two be less jarring. To achieve this, simply add a new transition tier, such as “Void” with a value of `0`. + +In the case that this transition tier could be represented by more than one biome, the set of space dedicated to these transition biomes could end up being sufficiently large for the transition to almost always occur between the two extremes. If only one biome should act as this transition, however, the biome may need to be duplicated for combinations of other used aspects to reserve enough of the targeting space for the transition to frequently occur. + +##### Arrangements + +Because strict boundaries aren’t a given in the Nether’s multi-noise system, biomes are never absolutely arranged; the concept of [slotting](#regions) doesn’t exist in the Nether. However, biomes in this system can still be arranged relative to one another, so long as all targeted values across all Nether-declaring biomes are considered. + +###### Clustering + +Biome clustering is rather straightforward and becomes more obvious as the count of biomes registered for the Nether increases. Biome clustering occurs when a group of related biomes have sufficiently close aspect targets. To cluster biomes together, simply assign targets to each appropriate biome that are only mildly offset from one another, ensuring that each biome has its own unique values to avoid conflicts. + +Due to the nature of the multi-noise system, there is no guarantee that all the biomes in a designed cluster will generate together in a cluster instance, but typically more than one will. + +For biomes targeting values farther away from the averages for each aspect in the cluster, a small [target adjustment](#target-adjustment) may need to be provided to ensure the “outermost” biomes in the cluster don’t bleed too far into space that would typically be designated for biomes outside the cluster. + +###### Isolation + +Biomes may be isolated at the extremes of the values of an aspect. Setting a biome to target a value near the extremes (`-1` or `1`) of any aspect can help ensure the rarity of that biome. With a sufficiently large number of biomes per [used aspects](#ignoring-aspects), these isolated biomes will typically be smaller and form simple, discrete shapes due to Perlin noise interpolation. Such isolated biomes become increasingly smaller and rarer with each added aspect targeted with an extreme value. + +###### Avoidance + +The dual nature of the range of Perlin noise for aspects can be used to force biomes away from one another. If the biome count for the Nether is small, [transitions](#tiering-transitions) can be established to separate biomes. For larger biome counts, biomes can avoid each other by setting their targets _for a single aspect_ to opposing extremes, such as `-1` and `1`. This will effectively [isolate](#isolation) both biomes and prevent them from ever directly touching. + +> Setting the values for more than one aspect target in opposing biomes to extremes is fruitless for the actual sake of avoidance. This would only work to further isolate each biome by constraining the conditions under which each could generate due to the independence of the aspects. At the same time, the minimum distance between two instances of these biomes would not decrease but would only serve to minimize the count of “close calls” due to the now compounded rarity of the biomes. + +### Dimension Interactions + +Dimension-specific tags used for slotting have no effect across dimensions; for example, the `"ocean"` and `"rare"` tags have no effect in generation for biomes in the Nether or The End. + +Biomes may generate in multiple dimensions; they need only to register themselves for each desired place using the relevant components (currently only the Overworld and the Nether). + +## Shape & Style + +The actual look of a biome depends on its shape and its aesthetic. These concepts exist entirely separately from how a biome is placed, meaning that a single aesthetic can be reused in multiple places in the Overworld; as an example, vanilla Forests exist: independently as a base biome, as a sub-biome to Plains, or as an island in the ocean. + +Biome aesthetic is controlled by the blocks comprising the biome and the [climate](#climate) features the biome declares. Blocks comprising a biome are predominantly declared using [surface builders](#surface-builders), but eligible surface builders also allow for noise-controlled [adjustments](#surface-adjustments). + +Biome shape depends on the surface builder it declares and the biome’s heightmap settings. A biome’s shape will fluctuate per-block; these fluctuations are fixed per dimension per seed, meaning that the same shape settings for a biome at the same location in a dimension will then only vary per seed. + +### Block Types + +Blocks are declared using a simple notation or a stateful notation. The **simple notation** references the identifier for a block as a string, such as `"minecraft:grass"`. If no namespace is provided, the game attempts to find a registered block with that name across all declared namespaces. + +> It is strongly advised to always use the complete name of a block, including the namespace, to avoid unexpected issues. + +The **stateful notation** indicates block states for selecting a particular variant of a block. + +> Unfortunately, block states for vanilla blocks do not currently cover every possible true state for every block; for example, not all directionally placeable blocks have a state for their orientation, like walls. + +Stateful notations are objects with a `"name"` string property referring to the block identifier (like the basic notation) and a `"states"` object property providing state declarations. An example of a stateful declaration would be: + + + +```json +{ + "name": "minecraft:concrete", + + "states": { + "color": "red" + } +} +``` + +### Heightmap + + + +```json +"minecraft:overworld_height": { + "noise_type": "lowlands" +} +``` + +Heightmaps are customized by affecting the noise a seed gives its terrain. The Overworld heightmap is adjusted using the `"minecraft:overworld_height"` component. Noises declared here can be customized using either numeric parameters passed to the noise generator or named presets of these parameters used in vanilla generation. + +> **The heightmap for a biome can only be customized for the Overworld.** The Nether and The End set their biomes’ heightmaps to give themselves a consistent feel. + +> If a preset is used anywhere in the inheritance chain for a biome, this preset will unconditionally override declarations of numeric parameters. This can occur if both described properties are declared in a biome definition’s `"minecraft:overworld_height"` component or when attempting to override a biome initially declared earlier in a behavior pack stack. Unfortunately, most vanilla biomes use presets, restricting heightmap adjustments in these biomes only to the set of available, non-extensible presets. + +The world generator will smoothly transition between heightmaps of adjacent biomes. Gradual descents and diagonal changes in elevation are not reliably possible using heightmap adjustments. In other words, world painter-like biomes are not currently possible. + +> Heightmaps cannot be used to bring the height of a biome above a _y_ of 128. The terrain will plateau out at this level. Similarly, the heightmap bottoms out near the lowest depths of deep oceans: at about a _y_ of 32. Only [features](#features) can reach outside these limits. + +#### Noise Parameters + + + +```json +"noise_params": [0.5, 0.125] +``` + +Noise parameters are declared as a 2-valued array using the `"noise_params"` property. + +The first value represents the average height of a biome. Interestingly, this parameter does not directly use block height (the _y_ coordinate) and is scaled to where a ∆ of 1 in the value represents a ∆ of 16 blocks in the average height of a biome. Furthermore, this value is zero-set to a _y_-height of about 67, several blocks above sea level. This means that to set this value with a particular average _y_-height in mind, use the formula: + +_f_(_y_) = (_y_ - 67) / 16 + +Therefore, setting this value to `1` will result in an average _y_-height of about 83, similar to the lesser hills in the Mountains biome. Setting this value to `-2` will result in a surface like that of a Deep Ocean, well under sea level. + +> Values for the first parameters that are `-2` or less will result in bugged generation. At exactly `-2`, no heightmap is generated: only the Bedrock layer will be present. At lesser values, terrain may generate above the Bedrock layer, but giant spikes will form on biome transitions when other biomes have “normal” heightmaps. Avoid values of `-2` and less for this parameter. + +The second value of the array determines height variation. Negative values behave erratically and should generally not be used; in many cases, no terrain is formed other than the bedrock foundation. A value of `0` will make terrain variance small but not make the biome completely flat. Values up to about `0.125` will generate particularly smooth terrain; values greater than this begin to form cliffs, coves, and hollows. Larger overhangs and small floating islands form beginning at `0.25`; by `0.5`, these terrain features become more common. At `1`, the terrain begins to become jagged and difficult to traverse; large, unnatural overhangs are common. Moving toward `4`, beautiful, massive floating islands dominate the landscape at the cost of player mobility. Additionally, much of the surface dips below sea level when the first noise parameter is tamer. + +The terrain becomes more radical with larger values, which should generally not be used for several reasons: + +- If outside creative mode, player annoyance will be high due to limited mobility options in the early game. +- Typically useful Molang queries, such as `"q.heightmap()"`, becomes less helpful as Nether-like shelves of land generate instead of smoother, simpler terrain. +- Performance issues may arise with weaker computers. + +The maximum and minimum offsets from the average height when using noise parameters depends on the height variation. In general, a ∆ of 1 in the second noise parameter will result in _at most_ a ∆ of +/- 16 blocks in these offsets. + +> If a perfectly flat surface is desired within a biome, the second value given to `"noise_params"` should be set to `0` to minimize height variation. The first value should then be set to `4`, above the value of maximum effect, to guarantee unconditional height variations do not dip below the average height upper bound. Despite how flat these values will cause the biome interior to generate, the biome surface will still smoothly transition to lower adjacent biomes as needed, causing massive rises and falls unless all adjacent biomes are also modified to sit at this _y_-height of 128. + +#### Noise Presets + + + +```json +"noise_type": "ocean" +``` + +Noise presets provide a convenient way to emulate vanilla biome generation. It is not possible to create custom presets. While the exact values of these presets are hard to gauge, their names are descriptive enough to get an idea of what kind of heightmap a biome will have. + +The built-in noise presets include: + +| Preset | Value | +| :-------------- | :------------------ | +| Default | `"default"` | +| Mutated default | `"default_mutated"` | +| Lowlands | `"lowlands"` | +| Highlands | `"highlands"` | +| Mountains | `"mountains"` | +| Extreme | `"extreme"` | +| Less extreme | `"less_extreme"` | +| Taiga | `"taiga"` | +| Swamp | `"swamp"` | +| Mushroom | `"mushroom"` | +| Ocean | `"ocean"` | +| Deep ocean | `"deep_ocean"` | +| River | `"river"` | +| Beach | `"beach"` | +| Stone beach | `"stone_beach"` | + +### Surface Builders + +Whereas heightmaps are used to control the general shape of a biome, surface builders are used to style biomes. Surface builders provide two key mechanisms for this styling: a schema to which blocks can be assigned for actual terrain generation and optionally a set of large-scale adornments to make a biome stand out. + +The optional adornments allow for biome terrain features that would otherwise be impossible using only heightmap adjustments or challenging using biome features; these adornments are either intricately shaped or massive in size. Unfortunately, there is no way to create a surface builder; the provided surface builders exist solely to represent complex vanilla biome surfaces. + +> Adornmenrts created by surface builders are unfortunately fixed and not relative to the declared heightmap. This means that if the heightmap at the location of a given surface builder-created decoration is high or low enough, the decoration will not appear to exist, consumed by the land. + +##### Surface Types + +###### Default + +###### Capped + +###### Swamp + +###### Mesa + +###### Frozen Ocean + +###### The Nether + +###### The End + +###### The End + +The End surface is the designated surface for The End dimension and its lone biome. [Because the End’s foundation material is not configurable](#dimensional-considerations), the End surface only works to generate a top material + +#### Dimensional Considerations + +The Nether may be able to take on the actual surface materials of certain Overworld-specific surface builders, but the features of these surfaces, such as badlands spires, will never generate. + +The End’s foundation material is not configurable in any way, even if using the only other surface type allowed in The End, [capped surfaces](#capped). + +#### Inheritance Considerations + +Due to biome inheritance, surface builders declared in later definitions of a biome may conflict with earlier definitions. Because each surface builder type is its own component, the default resolution system for inheritance pits the builders against each other, typically leading to some strange results. + +Only the [default surface builder](#default) can be overridden. Overrides will fail if attempted for any other builder, but the inner schema of the failed override may actually yet have an effect on generation. This occurs when the schemas of two different builders share properties of the same name and type. The inheritance system here will still use the initial, un-overridable surface builder, but its block declarations will be overridden with those from matching properties from the latter-declared surface builder. + +### Surface Adjustments + + + +```json +"minecraft:surface_material_adjustments": { + "adjustments": [ + { + "materials": { + "top_material": "minecraft:podzol" + }, + + "noise_range": [0, 0.5], + "noise_frequency_scale": 0.0625, + "height_range": [72, 255] + } + ] +} +``` + +Surface adjustments allow for fine-tuning a biome's surface blocks. Despite being called "surface" adjustments, these adjustments can actually affect all blocks declared in an eligible surface builder. These adjustments cannot modify blocks outside the scope of a surface builder and therefore cannot be used to alter bedrock or air, whether the air generates in caves, above the heightmap, or between shelves of land (if the heightmap is radical enough). Currently, only the default and swamp surface builders support adjustments. + +Surface adjustments declarations are implemented using objects in the `"adjustments"` property of the `"minecraft:surface_material_adjustments"` component. These declarations contain both overrides for blocks declared in the biome’s surface builder and the conditions under which these adjustments should occur. + +Surface adjustment conditions can check against a [random noise surface](#noise-intersections) dependent on the _x_ and _z_ coordinates using `"noise_range"` and `"noise_frequency_scale"` or a [simple range](#height-restrictions) of _y_ coordinates via `"height_range"`. If all coordinates should be considered, both conditions can be used. For an adjustment to be applied to a location, every declared condition must succeed; it any fail, the condition check fails, and the game will fall back to the surface builder’s declared block for that location. + +No default surface adjustments are forced automatically upon a biome. If no adjustments are listed anywhere along the inheritance chain for a biome, no adjustments will be observed in that biome. + +#### Noise Intersections + + + +```json +"noise_range": [-1, -0.5], +"noise_frequency_scale": 0.125, +``` + +A noise curve that is dependent upon the seed of a world can be used to restrict the _x_ and _z_ components of a surface adjustment. The origin of this noise curve is centered on the world origin and [can then optionally be scaled via `"noise_frequency_scale"`](#sizing) to map onto the horizontal plane of a dimension. The noise curve can therefore only work on this horizontal plane and not on the _y_ coordinate; for that, use [height restrictions](#height-restrictions). To actually use the noise curve to restrict adjustments, a success interval must be provided using `"noise_range"`. + +The exact value generated from the noise curve at a particular location is inconsequential to the resultant surface adjustment. The only consideration is whether the value at that location meets the conditional check. + +> Although both curves are formed based on the world seed, the noise curve used for surface adjustments is not equivalent to the noise curve used with `"q.noise"`. Their correspondence cannot be depended upon for generation. + +##### Intervals + + + +```json +"noise_range": [0.5, 1] +``` + +The noise curve used for surface adjustments generates values lying on the closed interval [-1, 1]. Values on this interval are targeted via a sub-interval using the `"noise_range"` property. + +The noise curve itself has some notable properties that should be understood when using surface adjustments. Negative values generated by Perlin noise behave symmetrically with the positives; that is: an intersecting sub-interval to this curve [-0.8, -0.6] would theoretically have approximately the same shape and represent approximately the same ratio of the full range as the sub-interval [0.6, 0.8]. Intervals closer to `0` tend to form continually winding striations in the surface, while those further away tend to form small, discrete, well spread shapes. Intervals closer to `0` also intersect a larger range of the noise curve than intervals of equal length further from `0`; this means that if discrete shapes are desired, like those that are formed at the extremes of the noise curve’s range, a larger relative interval may be required than one targeting the winding paths close to `0`. + +##### Sizing + + + +```json +"noise_frequency_scale": 0.25 +``` + +The surface adjustment noise curve uses a default mapping relative to the dimension coordinates that would form extremely small transformations. The noise intersections are actually made larger by setting the sizing value to be smaller. Smaller values, such as `0.125`, are key to forming large patches of transformations, such as podzol or coarse dirt clusters. Larger values of this property are typically used to create a messier feel to the terrain. Values greater than the default `1` are not recommended unless something akin to a checkerboard pattern is desired. + +#### Height Restrictions + + + +```json +"height_range": [ + "math.random_integer(30, 40)", + "math.random_integer(60, 70)" +] +``` + +Height restrictions can be provided to limit the valid transformation region. These restrictions are independent of limitations using the noise curve and much simpler, too. Height restrictions are provided as an interval and simply target a range of _y_-heights to transform a region. The first value of the `"height_range"` array must be less than the second value or else the adjustment will fail. + +Using integers directly will create boring layers of adjustments. However, unlike the properties establishing checks against the noise curve, the `"height_range"` property accepts Molang expressions for its elements. Using math functions, intervals can be created that are randomly spread for higher quality adjustments. Additionally, a `sea_level` variable is available that returns the sea level of the dimension for that individual instance of generation: + +| Dimension | Sea level | +| :--------- | --------: | +| Overworld | 63 | +| The Nether | 32 | +| The End | 63 | + +> Unfortunately, queries cannot be used in these expressions, so adjustments cannot be made relative to either the heightmap a noise surface. + +#### Removal + +Surface adjustments from earlier definitions of a biome can be removed by matching the definitions from the biome’s [surface builder](#surface-builders) across the relevant conditions. Take, for example, the vanilla surface adjustments made to the Shattered Savanna: + +biomes/savanna_mutated.json + +```json +"minecraft:surface_parameters": { + "foundation_material": "minecraft:stone", + + "top_material": "minecraft:grass", + "mid_material": "minecraft:dirt", + + "sea_floor_depth": 7, + "sea_material": "minecraft:water" + "sea_floor_material": "minecraft:gravel", +}, +"minecraft:surface_material_adjustments": { + "adjustments": [ + { + "materials": { + "top_material": "minecraft:stone", + "mid_material": "minecraft:stone" + }, + + "noise_range": [0.212, 1.0], + "noise_frequency_scale": 0.0625 + }, + { + "materials": { + "top_material": { + "name": "minecraft:dirt", + + "states": { + "dirt_type": "coarse" + } + } + }, + + "noise_range": [-0.061, 0.212], + "noise_frequency_scale": 0.0625 + } + ] +} +``` + +To revert the surface back to its original, “paint back over” the surface with the original blocks, like: + + + +```json +"minecraft:surface_material_adjustments": { + "adjustments": [ + { + "materials": { + "top_material": "minecraft:grass", + "mid_material": "minecraft:dirt" + }, + + "noise_range": [0.212, 1.0], + "noise_frequency_scale": 0.0625 + }, + { + "materials": { + "top_material": "minecraft:grass" + }, + + "noise_range": [-0.061, 0.212], + "noise_frequency_scale": 0.0625 + } + ] +} +``` + +### Climate + + + +```json +"minecraft:climate": { + "temperature": 1, + "downfall": 0.25, + "snow_accumulation": [0.0, 0.125], + "ash": 1 +} +``` + +A biome’s climate mostly represents its ambient aesthetic. Aspects of a biome’s climate may have an effect on gameplay, but this is rarely used in vanilla. Climate adjustments work everywhere in Minecraft, even The End, but the adjustments may have no effect if a dimension doesn’t support a specific climate feature, such as [precipitation](#precipitation) outside the Overworld. + +All aspects of a biome’s climate are optional. Defaults that are sensible for the Overworld are provided as fallbacks. + +#### Temperature + + + +```json +"minecraft:climate": { + "temperature": 0.5 + … +} +``` + +The **temperature** of a biome affects various gameplay features like [precipitation type](#precipitation), the formation of ice and [snow layers](#snow-cover) when the appropriate blocks are directly exposed to sunlight, and the survivability of snow golems. It is implemented as the float property `"temperature"` and may be set without limitation: all possible float values may be used. Lower values represent colder temperatures. Freezing temperatures, such as where snow falls, occur below `0.15`. If no temperature is provided for a biome definition, the game will use a value of `0.5`; at this temperature, freezing effects cannot be observed anywhere blocks can be placed in any dimension. + +> The effects of temperature are not restricted to the Overworld, but fewer effects may be available in other dimensions: Snow Golems may even survive in the Nether if the temperature at a _y_-height in the dimension is at freezing or below. + +> The `"temperature"` property is unrelated to the climate temperatures given in either the `"generate_for_climates"` property in the `"minecraft:overworld_generation_rules"` component or the `"target_temperature"` property in the `"minecraft:nether_generation_rules"` component; the property here affects gameplay rather than biome placement. + +The temperature established with this property is not the fixed temperature of a biome, only the basis; the actual temperature at a location also depends on the _y_-height. The temperature at or below sea level is fixed to this basis. Above sea level, however, the temperature decreases by 1 / 600 every block. The formula, therefore, of the temperature, _T_, at a given _y_-height, _y_, from a declared temperature basis, _t_, for _y_-heights above sea level, _s_, is given by: + +_T_(_y_) = _t_ - ((_y_ - _s_) / 600) + +To establish a _y_-height at which a biome will freeze, use the formula: + +_t_(_y_) = 0.15 + ((_y_ - _s_) / 600) + +The value of the sea level, _s_, depends on the dimension: + +| Dimension | Sea level | +| :--------- | :-------- | +| Overworld | 63 | +| The Nether | 32 | +| The End | 63 | + +The constant 0.15 here represents the freezing temperature. Data-driven gameplay can use the temperature at the position of an entity to perform actions upon that entity using the `"is_temperature_value"` damage condition filter in an entity definition, but this is outside the scope of this document. + +Vanilla biomes only use temperature values ranging from `-0.5` to `2`. Biomes to be completely covered in snow should use values less than `0.15`; `0` is the recommended value for this case. Warm biomes, such as those that would damage snow golems, should use values greater than `1`. Deserts and Nether biomes use `2`. For biomes that should only be capped with snow layers, a value between about `0.2` and about `0.4` should be used due to [how snow layer generation is affected by temperature](#snow-cover). + +#### Precipitation + + + +```json +"minecraft:climate": { + "downfall": 0.5 + … +} +``` + +**Precipitation** is visible as rainfall or snowfall in the Overworld. The float property `"downfall"` controls the extent of precipitation within a biome. Currently, the property only behaves on the closed interval [0, 1]; values outside this interval are clamped to the nearest valid value. At `0` or less, this property disables all precipitation effects within a biome. At `1` or greater, precipitation effects will be maximized. Values between `0` and `1` scale accordingly. + +> Due to a bug, adjustments to precipitation are _never_ reflected visually in the particles that fall when raining or snowing. Precipitation particles are never visible in Desert variants, Savanna variants, or Mesa variants, no matter their overrides; particles are _always_ visible in any other biome, including custom ones. Despite this, _most_ gameplay affected by precipitation will behave appropriately. + +Examples of precipitation effects in vanilla gameplay include the addition of snow layers when snowing, the filling of exposed cauldrons in rain, and the time required for a fish to spawn when fishing. Some gameplay aspects that should consider this value will instead ignore it, such as entities with the `"in_water_or_rain"` damage filter. Lesser values of `"downfall"` will slow precipitation effects accordingly, i.e., snow layers will form a tenth as fast at a value of `0.1` as they would at `1`. + +The type of precipitation occurring at a location depends on its _y_-coordinate. If the value is [freezing, `0.15`, or below](#temperature), snow will fall at that location; otherwise, rain will fall. + +#### Snow Cover + + + +```json +"minecraft:climate": { + "snow_accumulation": [1, 0.5], + … +} +``` + +When a biome is generated, blocks that are [at a freezing temperature](#temperature) typically have **snow cover** above them: snow layers stacked atop eligible blocks. The `"snow_accumulation"` property is used to adjust this snow cover. Snow covering seems to occur as one of the final passes to biome generation, meaning snow will cover features as well as the biome’s surface. + +> Snow can also cover a biome post-generation as a part of [snow precipitation](#precipitation), but the `"snow_accumulation"` property has no effect in this situation. Use the [`"precipitation"` property](#precipitation) to adjust snow formation rate. + +This property takes a two-valued array of float values, [*a*, *b*], where _a_ affects the average height of snow covering eligible blocks and _b_ seemingly affects the distribution of the snow. + +In particular, _a_ represents the maximum block count of snow layers above blocks at a freezing temperature. On average, the snow layer block height will actually be about 40% of this value. Blocks having no snow covering will be uncommon, and blocks having the maximum snow covering will be almost impossibly rare. Because this value represents block height and each actual snow layer is only one-eighth of a block tall, float values must be used for targeting shallower snow covering. For example, to have snow cover that is at most 4 layers tall, use a value of `0.5`. At this value, almost all eligible blocks will have a covering that is either 2 or 3 layers thick. + +The second value of the array, _b_, is intended to adjust snow distribution, but many values for _b_ cause erratic behavior, and even well-behaved values have little impact on generation. Values of `0` or less always result in a single layer of snow cover above eligible blocks, entirely disregarding the value set for _a_. Values exclusively between `0` and `0.125` cause a seemingly random spread of entire chunks to be only covered in a single layer of snow, while all other chunks respect the value set for _a_. Values at `0.125` or greater cause mild adjustments in snow cover that are not relative to the value set for _a_; in other words, extreme values of _a_ make alterations caused by _b_ to be virtually unnoticeable. Furthermore, the adjustments caused by _b_ only apply to a small spread of blocks, making this value rather useless at best and buggy at worst. _It is therefore recommended to just set this value to 0.5 wherever `"snow_acucmulation"` is declared._ + +> There is no way to conveniently avoid snow cover in frozen areas. Snow cover will not effect blocks not suitable for snow layer placement. To avoid snow, choose a warmer [`"temperature"` value](#temperature). + +#### Particle Decorations + + + +```json +"minecraft:climate": { + … + + "white_ash": 0.5 +} +``` + +**Particle decorations** are storms of ambient particles visible within a biome. These properties are solely decorative; unlike other aspects of a biome’s climate, particle decorations have no effect on gameplay. If not provided, no particle effects will be present in a biome. Custom particles currently may not be used. 4 different particle decorations from vanilla biomes are available to use anywhere: + +| Decoration type | Property name | +| :-------------- | :-------------- | +| Ash | `"ash"` | +| White ash | `"white_ash"` | +| Red spores | `"red_spores"` | +| Blue spores | `"blue_spores"` | + +These decorations will be a constant presence within a biome. If a player is within the bounds of a biome, these particles will be visible, even if underground or within water or lava. If undeclared, no particles will be used in a biome. + +As they are represented as float properties in the `"minecraft:climate"` component, their intensities are adjustable. The float value works for any number greater than `0`. The larger the value, the more particles will be used simultaneously; negative values or `0` will disable the effect. + +> It is not recommended to set this value too large, as the particle count may cause crashes to occur. By a value of `16`, the screen will be inundated with particles, but the biome will still be barely visible through the storm. + +## Gameplay + +Biomes are the starting point of much of the configurable gameplay in Minecraft. Features, such as trees and villages, can only generate as part of biomes. Automatic mob spawning can then be configured for biomes and structures. Feature attachments and mob spawning are outside the scope of this document, but there are a few configurations for biome definitions that power how biomes interact with other gameplay systems. + +### Features + + + +```json +"minecraft:forced_features": { + "surface_pass": { + "identifier": "pioneercraft:grasslands_caravan_feature", + "places_feature": "pioneercraft:caravan_feature", + + "scatter_chance": "100 * math.pow(2, -4)", + + "x": { + "distribution": "uniform", + "extent": [0, 16] + }, + "z": { + "distribution": "uniform", + "extent": [0, 16] + }, + "y": "q.heightmap(v.worldx, v.worldz)" + } +}, +"minecraft:ignore_automatic_features": {} +``` + +If a collection of blocks generating in a world aren’t created by a surface builder, they are created from a feature. Features are fundamental to gameplay in Minecraft: vanilla features range from trees to villages to boulders. The features in a biome may handily determine that biome’s worth to a player. + +Features are mostly outside the scope of biomes, but the two components within a biome’s schema affecting feature generation should be noted. + +#### Forced Features + + + +```json +"minecraft:forced_features": { + "surface_pass": [ + { + "identifier": "wiki:redwood_tree_feature", + "places_feature": "wiki:redwood_tree", + + "iterations": "math.random_integer(2, 4)", + + "x": { + "distribution": "uniform", + "extent": [0, 16] + }, + "z": { + "distribution": "uniform", + "extent": [0, 16] + }, + "y": "q.heightmap(v.worldx, v.worldz)" + } + ] +} +``` + +The `"minecraft:forced_features"` component can be used to force a feature to generate within a biome without using [feature rules](#/concepts/features/). + +Forced features are placed in array order for each pass. When overriding a previously provided array of feature attachments for a placement pass, the previous feature attachments will be completely ignored by the override; only the new attachments will be used. To use the old attachments with the new ones, they must be redeclared within the override. + +By default, no forced features are implied in a definition; if they are never declared down the inheritance chain, no additional features will exist. Note that [some features](#immutable-features) are hard-coded and cannot be removed easily. + +#### External Features + +The empty `"minecraft:ignore_automatic_features"` component is intended to indicate that a declaring biome will ignore all external feature rules attached to it, but this component currently does not work, whether for overrides or initial definitions. + +##### Immutable Features + +A few features may even generate in a custom biome with no attached tags. These features current cannot be removed conveniently: + +- Springs (water and lava “lakes”) +- Ruined Portals +- Mineshafts +- Dungeons\* +- Nether Fortresses + +> The Dungeon structure may generate infrequently due to the air created from the other Overworld immutable features; its generation is typically dependent on cave systems, [which may be disabled](#caves). + +These features occur before even the first placement pass of data-driven features and can even cut through the Bedrock layer. The immutable features can be overridden by data-driven features, but this is typically too challenging or expensive to consider. + +One typically ubiquitous Overworld structure, Strongholds, cannot be configured to generate in custom biomes no matter what. + +### Caves + +Carvers generate cave-like features in the world. Unlike the Java Edition of Minecraft, the Bedrock Edition currently provides no way to customize carvers. However, cave generation can be influenced by the types of blocks used in a [biome’s surface](#surface-builders). A whitelist of blocks allow carvers to cut through them to generate caves. At minimum, these blocks include: + +- Stone +- Dirt +- Sandstone +- Grass +- Podzol +- Mycelium +- Sand + +All of the variants of these blocks, such as Polished Andesite (a variant of Stone) can be culled by carvers. Custom blocks cannot currently be configured to be culled, often leaving heavily customized biomes without caves. Culling is not stopped by blocks not on the whitelist, so if only the top layer of a surface builder isn’t whitelisted, cave generation may resume underneath it, assuming those blocks below _are_ whitelisted. + +Caves are created only after the heightmap of a surface (including its adjustments) has been constructed; decorations created from surface builders, such as icebergs, are not interrupted by cave generation. Caves are always generated in full before even the first placement pass of features occurs. + +### Tagging + + + +```json +"components": { + … + + "urban": {}, + "city": {}, + "metro": {}, + + "rare": {} +} +``` + +Tags power much of what brings a biome to life in Minecraft, including entity spawns, external feature attachment, and data-driven gameplay. [Because some tags are additionally used (by poor design) to determine where a biome may generate](#regions), issues may arise when attempting to separate placement from form and function. See [Tags](#tags) for the implementation details of tags. + +No tags are implied based on the nature of a biome. For example, if a biome is set to generate in the Overworld, the `"overworld"` tag used on such biomes will need to be manually added to opt-in to the consequences of that tag. Another notable implication is that designated sub-biomes of a custom biome will need to redeclare the tags relevant to that biome cluster. As an example, imagine a base biome and its wooded mutated sub-biome. Regardless of the mutation, both biomes should have tall grass, which will be placed in these biomes using the `"highlands"` tag. For the base biome: + +biomes/highlands.json + +```json +{ + "format_version": "1.13.0", + + "minecraft:biome": { + "description": { + "identifier": "highlands" + }, + + "components": { + … + + "minecraft:overworld_generation_rules": { + "generate_for_climates": [ + ["cold", 2] + ], + + "mutate_transformation": "highlands_forest" + }, + + "overworld": {}, + "highlands": {}, + + "animal": {}, + "monster": {} + } + } +} +``` + +The sub-biome _must_ redeclare the `"highlands"` tag to opt in to its functionality — in this case, the addition of scattered tall grass across the surface: + +biomes/highlands_forest.json + +```json +{ + "format_version": "1.13.0", + + "minecraft:biome": { + "description": { + "identifier": "highlands_forest" + }, + + "components": { + … + + "overworld": {}, + "highlands": {}, + "forest": {}, + + "animal": {}, + "monster": {} + } + } +} +``` + +Without that tag, the sub-biome would appear barren. Transitions between the base biome and its mutation would appear strange and inconsistent. + +#### Tagging Strategies + +Due to the inheritance system for biome definitions, strategies should be used with tagging to separate concerns. + +##### Biome Taxonomy + +A taxonomical system can be created to bind biomes to other systems by putting the focus on the biome itself. Adding tags that help single out a biome by its generation rules can be useful for features that need to generate under conditions shared by a set of biomes due to their inherent nature. Some examples of a basic taxonomy would include using tags to specify: + +- A name for the basic type of biome +- The dimension where a biome would generate +- The [type of climate](#climates) or [strength of a defining characteristic](#separation-of-concerns) for the biome +- [Variants](#hierarchy) of a biome + +Example taxonomical tags for a theoretical Pumpkin Pastures Spooky Hills biome could include: + +- `"overworld"` +- `"cold"` +- `"pumpkin_pastures"` +- `"hills"` +- `"mutation"` (the “spooky” aspect) +- `"spooky"`, but only if this mutated aspect were shared with other biomes + +Vanilla biomes have historically relied exclusively on taxonomical systems for biome selection, often leading to verbose success conditions for spawning or generation. Here’s a snippet from the `wolf.json` spawn rules: + + + +```json +"minecraft:biome_filter": { + "all_of": [ + {"test": "has_biome_tag", "operator":"==", "value": "forest"}, + {"test": "has_biome_tag", "operator":"!=", "value": "mutated"}, + {"test": "has_biome_tag", "operator":"!=", "value": "birch"}, + {"test": "has_biome_tag", "operator":"!=", "value": "roofed"}, + {"test": "has_biome_tag", "operator":"!=", "value": "mountain"} + ] +} +``` + +In cases such as this, another perspective can be used for tagging that eases authoring pains. + +##### Spawning & Generating Perspective + +Authoring spawning and generating conditions can be made much easier by shifting the tagging perspective onto feature and spawn rules. [Minecraft 1.16 began using such a system for mob spawning in the Nether.](#other-mobs) In this system, tags are attached to a biome with actual gameplay in mind. If a custom mob were to be created that wasn’t meant to neatly spawn in a convenient classification of biome taxonomy, alluding to spawn rules via tagging can keep condition checks simple. + +Imagining bird mobs that could spawn in any area with trees, a tagging system could be developed dependent on how wooded a biome is. From another perspective, these biomes could also be tagged as `"forested"` and even go so far as to provide tags relating the density of trees: + +| Forest cover | Feature-focused tag | Biome taxonomy-focused tag | +| :----------- | :------------------ | :------------------------- | +| Light | `"few_birds"` | `"lightly_forested"` | +| Medium | `"default_birds"` | `"moderately_forested"` | +| Heavy | `"many_birds"` | `"heavily_forested"` | + +The problem with the latter system is what can happen during development if some other gameplay aspect relies on trees existing in a biome. Continuing the scenario, pretend only the biome taxonomy system were to be used: + +An abandoned forest shack structure feature meant to hide under the cover of trees is created; its feature rule will check for any of the 3 forested tags for generation. Later in behavior pack development, a new, heavily forested, toxic waste biome, Toxic Woods, is constructed with the `"heavily_forested"` tag. Abandoned shacks could make sense here to match the environment, but nature should be scarce or even missing; few or no birds should spawn. Unfortunately, the `"heavily_forested"` tag here would cause many birds to spawn, which is undesirable. The spawn rules for the birds would have to be updated to blacklist Toxic Woods. + +With dozens or hundreds of biomes, features, and mobs across the game all relying on the same tagging system, such exceptions as this can add up. Consider using feature-focused tagging systems. These systems don’t have to compete with taxonomy; both types can be included and used as needed. + +#### Vanilla Tags + +The tags used on vanilla biomes should be noted for biome-altering behavior packs that only mildly change or add to vanilla generation. These tags could be used to emulate vanilla gameplay aspects in a custom biome. + +##### Location & Variation + +Most tags used in vanilla biomes are used to help organize biomes by location and variant, forming a sort of [taxonomy](#biome-taxonomy) for targeting biomes. + +> A `"no_legacy_worldgen"` tag exists in the biome definition of Roofed Forests, but its behavior is unknown. + +###### Dimensions + + + +```json +"components": { + … + + "overworld": {} +} +``` + +4 tags exists supporting the game’s dimensions: + +| Dimension | Tag | +| :------------------- | :----------------------- | +| Overworld | `"overworld"` | +| Overworld generation | `"overworld_generation"` | +| The Nether | `"nether"` | +| The End | `"the_end"` | + +> The Overworld generation tag is required by Minecraft to support legacy features and behaviors. Features, entity spawning, and gameplay that needs to target all the Overworld should filter for both `"overworld"` _and_ `"overworld_generation"`, but the construction of this targeting is outside the scope of this document. + +These tags have mixed effects on biomes but are predominantly used to further organize or filter biomes in combination with other tags. The most direct effect of any tag here is that the `"overworld"` tag is what enables ores and some other underground features to generate. + +###### Biomes + + + +```json +"components": { + … + + "taiga": {}, + "mega": {}, + "hills": {} +} +``` + +A number of vanilla biome tags exist to support the specific nature of those biomes. + +For the Overworld: + +| Biome | Tag | +| :-------------- | :------------------- | +| Plains | `"plains"` | +| Forest | `"forest"` | +| Mountains | `"extreme_hills"` | +| Taiga | `"taiga"` | +| Swamp | `"swamp"` | +| Flower Forest | `"flower_forest"` | +| Jungle | `"jungle"` | +| Desert | `"desert"` | +| Savanna | `"savanna"` | +| Badlands | `"mesa"` | +| Snowy Tundra | `"ice_plains"` | +| Mushroom Fields | `"mooshroom_island"` | +| Beach | `"beach"` | + +For the Nether: + +| Biome | Tag | +| :-------------- | :------------------ | +| Nether Wastes | `"nether_wastes"` | +| Soulsand Valley | `"soulsand_valley"` | +| Basalt Deltas | `"basalt_deltas"` | +| Crimson Forest | `"crimson_forest"` | +| Warped Forest | `"warped_forest"` | + +Two tags exists strictly to group related biomes: + +| Group | Tag | +| :----------------------------- | :-------------------- | +| Snowy Tundra & Snowy Mountains | `"ice"` | +| Crimson Forest & Warped Forest | `"netherwart_forest"` | + +A few tags are used to single out unique variants: + +| Variant | Tag | +| :---------------------------------- | :---------- | +| Giant Tree Taiga variant | `"mega"` | +| Stone Shore variant | `"stone"` | +| Birch Forest variant | `"birch"` | +| Dark Forest variant | `"roofed"` | +| Bamboo Jungle variant | `"bamboo"` | +| Savanna & Badlands Plateaus variant | `"plateau"` | +| Jungle Edge variant | `"edge"` | + +###### Overworld Generation Aspects + + + +```json +"components": { + … + + "ocean": {}, + "deep": {}, + "warm": {} +} +``` + +Groups of tags exist for slotting and matching climates and transformations in the Overworld. + +Three tags are used for the slotting of biomes in the Overworld. These slotting tags are: + +| Slot | Tag | +| :----------------------------------------------------------- | :-------- | +| Ocean | `"ocean"` | +| Deep ocean (when used in combination with the `"ocean"` tag) | `"deep"` | +| Rare land | `"rare"` | + +> As described in [Regions](#regions), these tags have an actual effect on world generation. Only use these tags for biome placement. + +4 tags exist for [Overworld temperature variations](#climates): + +| Climate | Tag | +| :------- | :----------- | +| Frozen | `"frozen"` | +| Cold | `"cold"` | +| Lukewarm | `"lukewarm"` | +| Warm | `"warm"` | + +A tag exists for [each type of Overworld sub-biome](#hierarchy): + +| Sub-Biome type | Tag | +| :------------- | :---------- | +| Hills | `"hills"` | +| Mutated | `"mutated"` | +| River | `"river"` | +| Shore | `"shore"` | + +##### Mob Spawning + +Mob spawning is predominantly controlled by two tags: `"animal"` and `"monster"`. Finer control over the spawning of vanilla mob is provided in some special cases but often necessitates an intervention that involves both adding tags to biome definitions and overriding spawn rules to work with these new tags. + +> Overriding spawn rules is outside the scope of this document. + +Vanilla mobs not listed in this section are spawned via selection of vanilla biome-specific tags. As an example, Wolves only spawn in biomes tagged with `"forest"` or `"taiga"`. It is possible to tag a custom biome using one of these vanilla tags to spawn Wolves, but doing so may have unintended consequences. In this example, likely unwanted ground decorations from Forests and Taigas could generate in the custom biome. Instead, use custom tag additions, and adapt spawn rules to these new tags. + +###### Animals + + + +```json +"components": { + … + + "animal": {} +} +``` + +Using the `"animal"` tag will allow Cows, Chickens, Sheep, Pigs, and Bats to spawn in a biome. + +A `"bee_habitat"` tag exists, presumably to generate beehives, but it is unused. + +###### Other Mobs + + + +```json +"components": { + … + + "monster": {} +} +``` + +The `"monster"` tag allows Zombies, Skeletons, Spiders, Creepers, Slime, Endermen, Witches, and Phantoms to spawn in a biome. + +Beginning with Minecraft 1.16, a [new tagging strategy](#spawning-generating-perspective) was employed by Mojang in the new Nether biomes to separate biome type and location from functionality. A number of tags now exist for mob spawning in the Nether. + +| Mob spawning rule | Tag | +| :--------------------------------------------------------------- | :------------------------------ | +| Piglins | `"spawn_piglin"` | +| Few Piglins | `"spawn_few_piglins"` | +| Zombified Piglins | `"spawn_zombified_piglin"` | +| Few Zombified Piglins | `"spawn_few_zombified_piglins"` | +| Ghasts | `"spawn_ghast"` | +| Magma Cubes | `"spawn_magma_cubes"` | +| Many Magma Cubes | `"spawn_many_magma_cubes"` | +| Endermen (only considered in biomes also tagged with `"nether"`) | `"spawn_endermen"` | + +##### Decorations + +Currently, features and decorations are applied only through the [targeting of a a particular kind of biome](#location-variation); no dedicated tags exist for decorations. diff --git a/docs/wiki/world-generation/custom-ores.md b/docs/wiki/world-generation/custom-ores.md new file mode 100644 index 00000000..1edfe1b9 --- /dev/null +++ b/docs/wiki/world-generation/custom-ores.md @@ -0,0 +1,116 @@ +--- +title: Generating Custom Ores +category: Tutorials +tags: + - experimental +mentions: + - DerpMcaddon + - SirLich + - 7dev7urandom + - Chikorita-Lover +--- + +`ore_feature`'s are basic but important features! They can form clusters of blocks by replacing blocks where they are generated. This tutorial will show you how to make mineral ores that naturally generate. + +The use of features and feature rules requires Creation of Custom Biomes to be enabled in your world settings. If your block doesn't generate, make sure it's enabled! + +:::tip +For this tutorial, I'll be using 2 custom blocks, Titanite Ore and Deepslate Titanite Ore. For how to make custom blocks, visit the [Blocks Intro](/blocks/blocks-intro) page. +::: + +## The Feature File + +BP/features/titanite_ore_feature.json + +```json +{ + "format_version": "1.17.0", + "minecraft:ore_feature": { + "description": { + "identifier": "wiki:titanite_ore_feature" + }, + "count": 8, // Placement attempts + "replace_rules": [ + { + // Replace all stone variants (andesite, granite, and diorite) with titanite ore + "places_block": "wiki:titanite_ore", + "may_replace": ["minecraft:stone"] + }, + { + // Replace deepslate with deepslate titanite ore + "places_block": "wiki:deepslate_titanite_ore", + "may_replace": ["minecraft:deepslate"] + } + ] + } +} +``` + +## The Feature Rule + +BP/feature_rules/overworld_underground_titanite_ore_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:feature_rules": { + "description": { + "identifier": "wiki:overworld_underground_titanite_ore_feature", + "places_feature": "wiki:titanite_ore_feature" // Identifier from the feature file + }, + "conditions": { + "placement_pass": "underground_pass", + "minecraft:biome_filter": [ + // Scatter the ore throughout the Overworld + { + "any_of": [ + { + "test": "has_biome_tag", + "operator": "==", + "value": "overworld" + }, + { + "test": "has_biome_tag", + "operator": "==", + "value": "overworld_generation" + } + ] + } + ] + }, + "distribution": { + "iterations": 10, // Placement attempts of the cluster, not the ore blocks + "coordinate_eval_order": "zyx", + "x": { + "distribution": "uniform", + "extent": [0, 16] + }, + "y": { + "distribution": "uniform", // You can use "triangle" to make ores more common in the middle of the extent + "extent": [ + 0, // Minimum y level for the ore to generate + 62 // Maximum y level for the ore to generate + ] + }, + "z": { + "distribution": "uniform", + "extent": [0, 16] + } + } + } +} +``` + +## Testing + +You can look for the ore by exploring caves, but if your ores are rare, you can use commands instead to check if they're generating. Simply place this command into a repeating command block, then fly around: + +- `execute @a ~ ~ ~ fill ~8 ~8 ~8 ~-8 ~-8 ~-8 air 0 replace wiki:titanite_ore` + +Stone ores: + +![](/assets/images/world-generation/generating-custom-ores/stone_ore.png) + +Deepslate ores: + +![](/assets/images/world-generation/generating-custom-ores/deepslate_ore.png) diff --git a/docs/wiki/world-generation/feature-block-conditions.md b/docs/wiki/world-generation/feature-block-conditions.md new file mode 100644 index 00000000..2136aa91 --- /dev/null +++ b/docs/wiki/world-generation/feature-block-conditions.md @@ -0,0 +1,182 @@ +--- +title: Block Conditions for Features +category: Tutorials +tags: + - experimental +mentions: + - PavelDobCZ23 + - SmokeyStack + - ThomasOrs +--- + +Sometimes you might need to place any feature conditionally depending on what blocks are below or above it for example. Not many features have the option to conditionally place them like so, but with a simple trick we can use it on anything we want. + +:::tip +This technique utilizes `aggregate_feature` and `single_block_feature` features. If you want to learn more about those, visit [Feature Types](/world-generation/feature-types) article. +::: + +## Files + +### Features + +This feature places a `single_block_feature` which can be specified with the conditions we need for some other feature. The block can be kept there if it doesn't interrupt your desired features, but we will replace it with air in the next feature so that it doesn't cause any issues later on. This feature acts as a "dummy" feature because we only want its condition part but we don't need it to actually place anything. + +BP/features/block_condition_feature.json + +```json +{ + "format_version": "1.18.0", + "minecraft:single_block_feature": { + "description": { + "identifier": "wiki:block_condition_feature" + }, + "places_block": "minecraft:cobblestone", //Any block that isn't in "may_replace" list. + "enforce_placement_rules": false, + "enforce_survivability_rules": false, + "may_replace": ["minecraft:air"], //Only blocks the feature is allowed to be placed in. + "may_attach_to": { //Attachment conditions - what blocks can surround the feature when its being placed + "bottom": ["minecraft:grass"] //Only blocks the feature can be placed on top of. + } + } +} +//This "dummy" feature will only allow the feature to generate in the air, right above a grass block. +``` + +This next feature is the one that is going to replace the cobblestone with the original air block that was there, however it can be omitted if you choose a block you actually want there or if it won't cause you any issues later. + +BP/features/block_replacement_feature.json + +```json +{ + "format_version": "1.18.0", + "minecraft:single_block_feature": { + "description": { + "identifier": "wiki:block_replacement_feature" + }, + "places_block": "minecraft:air", //Replaces the block with another one which doesn't cause us any issue. + "enforce_placement_rules": false, + "enforce_survivability_rules": false, + "may_replace": ["minecraft:cobblestone"] //The block that we specified in the previous feature. + } +} +//This feature will replace the block with air that originally was there so it won't cause us any issue. +``` + +This is a feature that places the condition "dummy" feature, the feature that gets rid of the "dummy" block placed by the condition and after that the actual features we want to conditionally place. It uses `early_out` with value `first_failure` to make the aggregate stop if the conditional placement fails. It is the feature placed by a feature rule. + +BP/features/aggregate_placement_rock_feature.json + +```json +{ + "format_version": "1.18.0", + "minecraft:aggregate_feature": { + "description": { + "identifier": "wiki:aggregate_placement_rock_feature" + }, + "features": [ + "wiki:block_condition_feature", //Single block feature that is used as "dummy" feature to act as our condition. + "wiki:block_replacement_feature", //This feature replaces the "dummy" block we used in the feature above to not cause us any issues later. + //Any feature from this point on is what we actually want to place. + "wiki:rock_ore_feature" + ], + "early_out": "first_failure" //This makes sure that if the first(or any) feature fails, it will not continue to place anything else in the list. + } +} +//This is a feature that places all the features one by one in order and is placed by the feature rule. +``` + +This is the actual feature we want to be conditionally placed. It is `ore_feature` which doesn't have actual condition for us to allow it to only be placed in air and on a grass block, so this technique has helped us achieve that. + +BP/features/rock_ore_feature.json + +```json +{ + "format_version": "1.18.0", + "minecraft:ore_feature": { + "description": { + "identifier": "wiki:rock_ore_feature" + }, + "count": 12, + "replace_rules": [ + { + "places_block": "minecraft:stone", + "may_replace": ["minecraft:air","minecraft:grass"] + }, + { + "places_block": { + "name": "minecraft:dirt", + "states": { + "dirt_type": "coarse" + } + }, + "may_replace": ["minecraft:dirt"] + } + ] + } +} +``` +:::tip +If you want to learn more about ore features, you can visit [Generating Custom Ores](/world-generation/custom-ores) tutorial. +::: + +### Feature Rule + +BP/feature_rules/overworld_after_surface_rock_feature.json + +```json +{ + "format_version": "1.18.0", + "minecraft:feature_rules": { + "description": { + "identifier": "wiki:overworld_after_surface_rock_feature", + "places_feature": "wiki:aggregate_placement_rock_feature" + }, + "conditions": { + //Places the feature in any overworld biome along with features in the after_surface_pass + "placement_pass": "after_surface_pass", + "minecraft:biome_filter": [ + { + "any_of": [ + { + "test": "has_biome_tag", + "operator": "==", + "value": "overworld" + }, + { + "test": "has_biome_tag", + "operator": "==", + "value": "overworld_generation" + } + ] + } + ] + }, + "distribution": { + //1 in 3 chance to attempt 1 placement in chunk + "scatter_chance": 33, + "iterations": 1, + "coordinate_eval_order": "xzy", + "x": { + "distribution": "uniform", + "extent": [0, 15] + }, + //Places the feature along the heightmap + "y": "q.heightmap(v.worldx,v.worldz)", + "z": { + "distribution": "uniform", + "extent": [0, 15] + } + } + } +} +``` + +## Summary + +After reading this tutorial you should be able to use block conditions on any feature you want. This was a very basic example as this can be used for far more complex creations and can be used with any feature. + +Like that we have made a rock feature that can only be placed in air blocks and above grass blocks. + +Generation screenshot: + +![](/assets/images/world-generation/rock_feature.png) diff --git a/docs/wiki/world-generation/feature-types.md b/docs/wiki/world-generation/feature-types.md new file mode 100644 index 00000000..b14e1dce --- /dev/null +++ b/docs/wiki/world-generation/feature-types.md @@ -0,0 +1,1724 @@ +--- +title: Feature Types +category: General +tags: + - experimental +mentions: + - SirLich + - MedicalJewel105 + - Luthorius + - TheItsNameless +--- + +_Last updated for 1.17.10_ + +::: warning +Some links designed to reference external documents do not function, and will be updated at a later time to point to the correct resource. + +Screenshots and other resources may be provided for many feature types given here at a later time. +::: + +## Content Features + +Content features are the fundamental feature type responsible for defining block placements in a feature system. They offer nothing in terms of arrangement or composition. Instead, they define basic arrangements of blocks and are often combined or positioned using [proxy features](#proxy-features). + +### Single Block Features + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:single_block_feature": { + "description": { + "identifier": "beachside:pier_planks" + }, + + "places_block": "minecraft:planks", + + "enforce_placement_rules": true, + "enforce_survivability_rules": true, + "may_replace": ["minecraft:water"], + "may_attach_to": { + "top": "minecraft:air", + "sides": ["minecraft:planks", "minecraft:water"] + } + } +} +``` + +**Single block features** place a single block in the world. Single block features are typically useless on their own; their real power comes in conjunction with [proxy features](#proxy-features) to construct builds. + +The **target block**, the block to be placed, is specified by the `"places_block"` property. No variation capabilities are currently possible in the definition; [weighted random features](#weighted-random-features) over additional single block features must be used instead. + +#### Conditions + +**Conditions** can be specified to limit placement success. If any of the conditions would fail, the block will not be placed. + +::: warning +For the sake of placement success, single block features are considered to fail if replacing themselves. This is an important distinction for [aggregate features](#aggregate-features), [conditional lists](#conditional-lists), and others. Proxy single block features with a [search feature](#search-feature) when only considering placement restriction success. +::: + +##### Innate Block Conditions + +Single block features can allow block placement that wouldn’t be allowed in-game due to a block’s innate conditions. + +When true, the required `"enforce_placement_rules"` boolean ensures a block’s innate placement check must succeed for the block to be placed; setting to false ignores this check. As an example, seeds can usually only be placed on farmland, but disabling this check can allow them to generate anywhere. + +Additionally, the required "enforce_survivability_rules" boolean property will toggle whether the survivability checks of a block will succeed. If false, the block’s survivability conditions are ignored. One vanilla survivability example is living coral blocks requiring adjacent water. + +::: tip NOTE +Just because the block’s survivability check was ignored for world generation does not mean it will maintain its invalid state during gameplay. Block updates will correct invalid block survivability. +::: + +##### Replacement Conditions + + + +```json +"may_replace": [ + "minecraft:air", + "minecraft:leaves", + "minecraft:leaves2" +] +``` + +Single block features may optionally specify a **replacement list** via the `"may_replace"` array to restrict the set of blocks the target block may replace. If the block at the [input position](#) of the single block feature is _not_ in this list, the placement will fail. + +::: warning +Unlike [attachment properties](#attachment-conditions), `"may_replace"` must be an array. It cannot be declared as a direct block reference. +::: + +##### Attachment Conditions + + + +```json +"may_attach_to": { + "top": "minecraft:air", + "sides": [ + "minecraft:planks", + "minecraft:water" + ] +} +``` + +**Attachment specifications**, given via the optional `"may_attach_to"` property, restrict block adjacency. A property exists for each attachable side: + +- `"top"` +- `"bottom"` +- `"north"` +- `"south"` +- `"east"` +- `"west"` + +Each property accepts either a single direct block reference or an array of such references: + + + +```json +"bottom": { + "name": "minecraft:stone", + + "states": { + "stone_type": "andesite" + } +} +``` + + + +```json +"top": [ + "minecraft:netherrack", + "minecraft:soul_sand" +] +``` + +A `"sides"` property is available as a catch-all to match `"north"`, `"west"`, `"east"`, and `"south"`. Finally, the `"all"` property matches all 6 faces. All 8 properties are optional, but at least one should be specified. + +For attachment along the sides (`"north"`, `"south"`, `"east"`, `"west"`), 2 more optional properties are available for fine control. + +`"min_sides_must_attach"` sets the minimum number of successes yielded by provided side properties that will result in side attachment being flagged as successful. Therefore, if this property is set to `4`, all four sides must match. If set to `2` and only 1 side matched, block placement would fail. + +`"auto_rotate"` causes side definitions to be interpreted as relative associations instead of strict directions. As an example, if a block should be squeezed laterally in one dimension between two other blocks but the orientation doesn’t matter, enabling auto rotate and specifying opposing sides would allow either orientation to work. + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:single_block_feature": { + "description": { + "identifier": "aura_heights:force_conduit_block" + }, + + "places_block": "aura_heights:force_conduit", + + "enforce_placement_rules": true, + "enforce_survivability_rules": true, + "may_replace": ["minecraft:air"], + "may_attach_to": { + "north": "minecraft:glass", + "south": "minecraft:glass", + + "auto_rotate": true + } + } +} +``` + +Specifically, with the preceding code, the force conduit block would be sandwiched between adjacent glass along opposing lateral sides — regardless of the orientation. + +### Ore Features + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:ore_feature": { + "description": { + "identifier": "deepest_depths:starlite_ore_cluster" + }, + + "count": 4, + "replace_rules": [ + { + "places_block": "deepest_depths:starlite_ore", + "may_replace": ["minecraft:stone"] + } + ] + } +} +``` + +**Ore features** place clusters of blocks around a target position. The blocks placed by ore features vary via [replacement rules](#replacement-rules). Only the **block count** in ore features is global, controlled by the `"count"` property. + +::: tip NOTE +The shape of the cluster cannot be controlled; to achieve this, use [scatter features](#scatter-features) with a [custom distribution system](#). +::: + +#### Replacement Rules + + + +```json +"replace_rules": [ + { + "places_block": "infinitum:exposed_pylon", + "may_replace": [ + "minecraft:air" + ] + }, + { + "places_block": "infinitum:submerged_pylon", + "may_replace": [ + "minecraft:water" + ] + } +] +``` + +In ore features, **replacement rules** bind target blocks to replacement lists that restrict the target’s placement; these rules are given with `"replace_rules"`. **Target blocks** are the blocks placed by a replacement rule, provided with the required `"places_block"` property; **replacement lists** (via `"may_replace"`) are optional arrays that only allow replacement of specific blocks. The block selected for a given position in the cluster will be the target block of the first matching rule. If a replacement list is not provided, that rule will always succeed in its position amongst the other rules, and all future rules will be ignored. + +### Structure Template Features + + + +```json +{ + "format_version": "1.13.0", + "minecraft:structure_template_feature": { + "description": { + "identifier": "forgotten_worlds:blackmoor_castle_feature" + }, + + "structure_name": "forgotten_worlds:blackmoor_castle", + + "facing_direction": "random", + "constraints": { + "block_intersection": { + "block_allowlist": [ + "minecraft:air", + "minecraft:stone", + "minecraft:dirt", + "minecraft:grass" + ] + }, + "unburied": {} + }, + "adjustment_radius": 4 + } +} +``` + +**Structure template features** generate structures by referencing saved structure files. These features trade power and flexibility for convenience. + +::: warning +Unlike with data-driven features, blocks in structure features are _not_ automatically waterlogged if placed in water. +::: + +The **target structure** is placed with the `"structure_name"` string property. This string follows a unique naming system to select a `.mcstructure` file from the behavior pack; it follows the form `namespace:path`. Structure files must be placed in the top-level `structures` directory; any hierarchy of folders from here is allowed but not required. If the structure file is placed directly in the `structures` directory, the default namespace `mystructure` is used. Otherwise, if placed in a directory inside `structures`, that directory name is used as the namespace. If any nesting is present within this directory, it is reflected in the path. Finally, the file extension (`.mcstructure`) is omitted. + +For some examples: + +| Structure file location | Associated `"structure_name"` | +| :---------------------------------------------------------- | :------------------------------------ | +| `/structures/well.mcstructure` | `"mystructure:well"` | +| `/structures/farmstead/silo.mcstructure` | `"farmstead:silo"` | +| `/structures/campsites/taiga/rustic/tents/wool.mcstructure` | `"campsites:taiga/rustic/tents/wool"` | + +::: warning +[Due to constraints in the feature system](#), large structures may need to be pre-sliced into smaller structures and positioned together. +::: + +#### Rotation + + + +```json +"facing_direction": "south" +``` + +**Structure rotation** is performed using the `"facing_direction"` property, which accepts the four lateral directions: `"north"`, `"south"`, `"east"`, and `"west"`, and an additional `"random"` property to shuffle amongst them each instance. South is the “default” direction; structures extend into the positive _x_ and _z_ directions using this orientation. + +::: warning +For non-South-oriented structures, not all block states are updated to accommodate the rotation, causing some rotatable blocks, such as vines, to hang in invalid positions. +::: + +Rotations are performed clockwise from a top-down perspective. Unfortunately, rotations occur around the [structure origin](#), not the center, so large structures may be cut off in random rotation due to [feature limitations](#). Using a set rotation, however, will orient in reliable (albeit inconvenient) ways. All rotations begin inclusively from the [feature origin](#) and are generated with the following orientations: + +| Rotation | _x_ Projection | _z_ Projection | Clockwise Rotation from Above | +| :-------- | :------------- | :------------- | :---------------------------- | +| `"east"` | Positive | Negative | 270° | +| `"south"` | Positive | Positive | 0° | +| `"west"` | Negative | Positive | 90° | +| `"north"` | Negative | Negative | 180° | + +Therefore, if a 7 × 6 feature is generated from an origin of (64, 64), an east rotation would occupy the lateral area from (64, 58) to (70, 65). + +::: warning +Because of how rotation is handled, structure features typically need to be proxied by [weighted random features](#weighted-random-features) and [scatter proxies](#scatter-features) that offset position. +::: + +#### Constraints + + + +```json +"constraints": { + "block_intersection": { + "block_whitelist": [ + "minecraft:sand", + "minecraft:sandstone", + "minecraft:stone" + ] + }, + "unburied": {}, + "grounded": {} +} +``` + +Structure features can enforce **constraints** using the required `"constraints"` property to restrict block intersection, adjust the placement position, and clear the space above the features using air. Although the property and its object (`{}`) are required, all sub-properties are optional. + +##### Block Intersection + + + +```json +"block_intersection": { + "block_whitelist": [ + "minecraft:end_stone" + ] +}, +``` + +The set of blocks the structure may replace are given by the **block whitelist**, given with `"block_whitelist"`. If even one block within the structure’s attempted volume is not in the whitelist, the structure will not be placed at that position. If no block intersection is provided, the structure may replace all blocks. + +::: tip NOTE +Bizarrely, the `"block_whitelist"` property can also be given with `"block_allowlist"`. Both function the same. +::: + +##### Ground Attachment + + + +```json +"grounded": {} +``` + +The optional `"grounded"` component ensures the base of a structure is not overhanging into open space — air, water, or lava. All non-structure void, non-air blocks along the bottom layer of the structure are considered; if air, water, or lava is beneath even one such block, generation will fail. + +##### Top Clearance + + + +```json +"unburied": {} +``` + +The `"unburied"` component ensures a structure’s top is exposed to air for generation to succeed. Only non-structure void, non-air blocks on the top layer of the structure are considered, and all must be exposed to air above for the structure to successfully generate. + +::: tip NOTE +Unlike [ground attachment](#ground-attachment), exposure to water is _not_ considered. +::: + +#### Placement Adjustment + + + +```json +"adjustment_radius": 4 +``` + +To accommodate possibly stringent [constraints](#constraints), the optional `"adjustment_radius"` property is available; it accepts values from `0` (the default) to `16`. During placement, Minecraft will begin at the input position and radially search laterally outward up to the number of blocks specified by this property; vertical adjustment is not attempted. Each corresponding volume will be checked for validity; [block intersection](#block-intersection), [ground attachment](#ground-attachment), and [top clearance](#top-clearance) are all considered. The first success, if one exists, is used. + +::: tip +If vertical adjustment should be used, proxy the structure feature with a [search feature](#search-feature). +::: + +### Growing Plant Features + + + +```json +{ + "format_version": "1.13.0", + "minecraft:growing_plant_feature": { + "description": { + "identifier": "echelon:bulbous_cerulon" + }, + + "body_blocks": [ + ["echelon:bulbous_cerulon_stem", 1], + ["echelon:bulbous_cerulon_spiked_stem", 1] + ], + "head_blocks": [ + ["echelon:bulbous_cerulon_bulb", 1], + ["echelon:bulbous_cerulon_bulb_exposed", 1] + ], + "age": { "range_min": 1, "range_max": 15 }, + + "growth_direction": "up", + "height_distribution": [[{ "range_min": 4, "range_max": 12 }, 1]] + } +} +``` + +**Growing plant features** place columns of body blocks with a head block at the end. Both can be randomized per-block for fine-tuned customization. + +::: tip +For advanced column generation, use [scatter features](#scatter-features) with [fixed grid distribution](#grid-distributions). +::: + +#### Column Blocks + + + +```json +"body_blocks" : [ + ["arctica:ice", 4], + ["arctica:ice_crystallized", 1] +], +"head_blocks" : [ + ["arctica:growing_ice", 1] +], +"age": 3 +``` + +The growing plant is divided into **body blocks**, which make up most of the feature, and **head blocks**, which are only the last block generated as part of the plant. Both are given as arrays of **block entries**. Each block entry is an array that binds a block reference to an integer [weight](#): + + + +```json +["crestfallen:fungi_stem", 2] +``` + +Each block is independently selected for the body or head. There is no way using growing plant features to make all of the body blocks the same. + +An optional `"age"` property exists to set the age block state of the head block. It accepts two forms, an integer and a range object. When using the range object, the age is uniformly randomly selected each instance of the feature between the two provided integer bounds. + +Integer: + + + +```json +"age": 12 +``` + +Range object: + + + +```json +"age": {"range_min": 4, "range_max": 8} +``` + +::: warning +Age configuration is currently only applicable to cave vines. +::: + +#### Column Generation + + + +```json +"growth_direction": "down", +"height_distribution": [ + [{"range_min": 8, "range_max": 12}, 4], + [{"range_min": 4, "range_max": 8}, 2], + [2, 1] +], +"allow_water": true +``` + +Columns are generated from the feature origin in the vertical direction specified by the required `"growth_direction"` property, which accepts either `"up"` or `"down"`. + +The _maximum_ possible length of the growing plant feature is given with the `"height_distribution"` array. Like the [block declarations previously](#column-blocks), each entry in the height distribution is a **height entry** that binds a height to a weight. Heights may be given as fixed integers or as [range objects](#column-blocks). + +As an integer: + + + +```json +[6, 3] +``` + +As a range object: + + + +```json +[{ "range_min": 2, "range_max": 8 }, 1] +``` + +One entry from the height distribution is selected according to [weight](#), and if a range is provided, a random value is uniformly selected inclusively between the given limits. + +Growing plant features begin from the [input position](#) and proceed up or down (depending on the `"growth_direction"`). By default, only air is replaced along the generated column. If not beginning in air, column generation begins at the first available air block along the correct direction. Block opportunities that were missed because of non-air blocks in the way are not re-attempted. This means that if the feature origin had to search through two non-air blocks before reaching air, the height will be stunted by 2. + +After reaching (or beginning in) air, the column generates body blocks until reaching a non-air block, at which point column generation is permanently stopped. Column generation is — of course — also stopped when traversing the determined height, as counted from the feature origin. Regardless, the final block in the column will be a head block, even if the column ends up being only one block in height. + +When true, the optional `"allow_water"` boolean allows the _first available replacement_ to be water instead of air. If this property is `true` and the first water block is not attached to air above, only the single head block is generated for the entire column; otherwise, column generation resumes as usual. + +### Tree Features + + + +```json +{ + "format_version": "1.13.0", + "minecraft:tree_feature": { + "description": { + "identifier": "forgotten_forests:grand_oak" + }, + + "base_block": ["minecraft:dirt", "minecraft:coarse_dirt"], + "base_cluster": { + "num_clusters": 4, + "cluster_radius": 3, + "may_replace": ["minecraft:air"] + }, + + "may_replace": ["minecraft:air"], + + "fancy_trunk": { + "trunk_block": "minecraft:log", + + "trunk_height": { + "base": 24, + "variance": 9, + "scale": 1 + }, + "trunk_width": 3, + "width_scale": 2, + + "foliage_altitude_factor": 0.5, + "branches": { + "slope": 0.33, + "density": 0.25, + "min_altitude_factor": 0 + } + }, + + "fancy_canopy": { + "height": 3, + "radius": 4, + "leaf_block": "minecraft:leaves" + } + } +} +``` + +**Tree features** generate tree-like shapes. Tree features allow for more customization than any other feature type, including: + +- Setting wood and leaf blocks +- Adding tree face decorations +- Restricting foundation and intersection blocks +- Customizing branch frequency and angle + +Tree features are composed of _many_ sub-properties to reflect the many variations of tree shapes found in vanilla gameplay. In general, these properties are divided into [setup](#setup-properties), [trunk](#trunk-properties), and [canopy](#canopy-properties) properties. + +#### Setup Properties + + + +```json +"base_block": [ + "minecraft:dirt", + "minecraft:grass" +], +"base_cluster": { + "may_replace": [ + + ], + "num_clusers": 2, + "cluster_radius": 3 +}, + +"may_grow_on": [ + +], +"may_replace": [ + +], +"may_grow_through": [ + +] +``` + +Foundation and intersection blocks for the tree are specified using **setup properties**. + +#### Trunk Properties + +**Trunk properties** establish the trunk and branches. + +##### Trunks + + + +```json + +``` + +##### Acacia Trunks + + + +```json + +``` + +##### Fancy Trunk + + + +```json + +``` + +##### Mega Trunk + + + +```json + +``` + +##### Fallen Trunk + + + +```json + +``` + +#### Canopy Properties + +Tree canopies are constructed using **canopy properties**. + +##### Canopies + + + +```json + +``` + +##### Fancy Canopies + + + +```json + +``` + +##### Mega Canopies + + + +```json + +``` + +##### Spruce Canopies + + + +```json + +``` + +##### Pine Canopies + + + +```json + +``` + +##### Mega Pine Canopies + + + +```json + +``` + +##### Acacia Canopies + + + +```json + +``` + +##### Roofed Canopies + + + +```json + +``` + +##### Random Spread Canopies + + + +```json + +``` + +### Multiface Features + +::: warning +Multiface features are currently bugged and should not be used. At most 2 iterations are being placed — regardless of the spread chance. [Scatter features](#scatter-features) are a viable substitute in the meantime. +::: + + + +```json +{ + "format_version": "1.13.0", + "minecraft:multiface_feature": { + "description": { + "identifier": "underworld:decay_spread" + }, + + "places_block": "underworld:decay", + + "search_range": 8, + "chance_of_spreading": 0.5, + + "can_place_on_ceiling": false, + "can_place_on_floor": false, + "can_place_on_wall": true, + "can_place_on": [ + "minecraft:stone", + "minecraft:deepslate", + "minecraft:tuff" + ] + } +} +``` + +Multiface features randomly place sequences of blocks on surfaces based on the success of the previous element of the sequence. **Surfaces** are defined as between either air or water and any other block. + +#### Spread Mechanics + + + +```json +"search_range": 4, +"chance_of_spreading": 0.75 +``` + +Multiface features begin by attempting to place the **target block** (via the `"places_block"` property) at the [input position](#) of the multiface feature. For each subsequent attempt, a roll is made against the **spread chance**. The spread chance is given with the `"chance_of_spreading"` float property; it ranges from `0` (never successful) to `1` (always successful). If it succeeds, the next block in the sequence will be placed randomly within a cube centered on the input position that has a half side length equal to the value given by `"search_range"`. The sequence continues until a block fails to be placed. The search range may be between `1` and `64`. + +#### Placement Restrictions + + + +```json +"can_place_on_ceiling": true, +"can_place_on_floor": false, +"can_place_on_wall": true, +"can_place_on": [ + "minecraft:log", + "minecraft:log2", + "minecraft:leaves" +] +``` + +Multiface features use **placement restrictions** to limit block attachment. With any iteration (including the first), if the placement check fails, the sequence is terminated. 3 required boolean properties control where the target can be placed: + +- "can_place_on_floor" +- "can_place_on_ceiling" +- "can_place_on_wall" + +When these properties are true, their corresponding surfaces are eligible for attachment. Of course, at least one property must be true, or the sequence will never begin. + +::: tip NOTE +These properties _do not_ dictate block state, only attachment. Multiface blocks, such as torches, will not automatically orient to the appropriate face. Furthermore, if the target block supports simultaneous attachment to multiple faces and would be attached to a face whitelisted by these properties, it may also automatically attach to a face that is _not_ whitelisted. +::: + +An optional whitelist of blocks to which the target may attach is available via the `"can_place_on"` array property. Omitting this property defaults to allowing all blocks to attach. + +## Proxy Features + +Proxy features group, arrange, or gate features, including other proxy features. Proxy features themselves are incapable of having a direct effect on world generation. + +All proxy features must therefore point to one or multiple **target features**: the features that are placed, rearranged, or selected by proxy features. Target features are represented as string references to the identifier of the intended feature. + +### Scatter Features + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:scatter_feature": { + "description": { + "identifier": "arboreal:flower_patch" + }, + + "places_feature": "arboreal:flowers", + + "scatter_chance": { + "numerator": 2, + "denominator": 3 + }, + "iterations": "v.flower_patch.size = math.random_integer(6, 14); return math.random_integer(math.pow(v.flower_patch.size, 2) / 4, math.pow(v.flower_patch.size, 2) / 3);", + + "project_input_to_floor": true, + "x": { + "distribution": "gaussian", + "extent": [0, "v.flower_patch.size"] + }, + "z": { + "distribution": "gaussian", + "extent": [0, "v.flower_patch.size"] + }, + "y": 0 + } +} +``` + +**Scatter features** are the most flexible and useful feature type available. Scatter features can: + +- Distribute or reposition a feature any number of times within a [chunk’s feature domain](#) +- Act as a gate to conditionally enable a feature to be placed +- Execute Molang within the current [feature context](#) + +Scatter features attempt to place a [target feature](#proxy-features) with each iteration: + + + +```json +"places_feature": "lostlands:shimmerfields_spire" +``` + +If, where, and how an instance of the target is placed depend on the [generation potential](#generation-potential), [distribution](#distribution), and the [evaluation order](#evaluation-order) + +#### Generation Potential + + + +```json +"scatter_chance": 25, +"iterations": 12 +``` + +A scatter feature will determine placement attempts of its target using the `"scatter_chance"` and `"iterations"` properties. + +**Scatter chance** represents the potential for the scatter feature to succeed. It can be represented as… + +A numeric literal: + + + +```json +"scatter_chance": 12.5 +``` + +::: warning +The numeric literal form is considered against 100, not 1. A scatter chance of `50`, therefore, has half a chance of success. +::: + +A Molang expression: + + + +```json +"scatter_chance": "1 / 8" +``` + +A fraction object: + + + +```json +"scatter_chance": { + "numerator": 1, + "denominator": 8 +} +``` + +All 3 examples have a 12.5% chance for success. Use whichever form feels most appropriate for your case. If scatter chance is omitted, it defaults to a 100% chance for the scatter feature to attempt to place its target. + +**Iterations** are the number of attempts a scatter feature will try to place its target. If an instance of a scatter feature would succeed (in other words, if its scatter chance check were successful), _all_ of the iterations given by `"iterations"` will be attempted. Iterations may be represented as integer literals or Molang expressions. Unlike scatter chance, iterations are required. + +#### Distribution + + + +```json +"x": { + "distribution": "fixed_grid", + "extent": [0, 15] +}, +"z": { + "distribution": "fixed_grid", + "extent": [0, 15] +}, +"y": 0 +``` + +Distribution is predominantly handled using **coordinate properties**: `"x"`, `"z"`, and `"y"`. All these properties may be represented using… + +An integer literal: + + + +```json +"x": 0 +``` + +A Molang Expression: + + + +```json +"x": "math.random_integer(0, v.surface_grass.spread - 1)" +``` + +Or a number of object forms for conveniently distributing a coordinate: + + + +```json +"x": { + "distribution": "uniform", + "extent": [0, 16] +} +``` + +Literals and Molang expressions are relative to the [feature origin](#). See [Distribution Types](#distribution-types) for the available pre-constructed distribution systems. + +Because placement of features is so often relative to the heightmap, the incoming _y_-origin for the scatter feature may be **projected into the heightmap**: + + + +```json +"project_input_to_floor": true +``` + +This means that the specified _y_-origin from the scatter feature’s parent is ignored in favor of the _y_-coordinate of the heightmap at an iteration’s _x_-_z_ location ([assuming the _y_-coordinate would be evaluated after the lateral coordinates](#evaluation-order)). The `"y"` property may still be given a value that will represent the offset from the heightmap. + +::: tip NOTE +Functionally, this is the same as using the Molang expression `"q.heightmap(v.worldx, v.worldz) + *offset*"`. +::: + +##### Distribution Types + +Custom distribution systems can be constructed using Molang expressions, but scatter features come pre-equipped with a few common **distribution types** for convenient authoring: + +- Uniform +- Gaussian +- Inverse Gaussian +- Fixed grid +- Jittered grid + +Each distribution type requires an **extent**, which represents the range of values on which that distribution operates, from minimum to maximum. Extents, like the basic forms of coordinate declarations, are relative to the [feature origin](#). + +###### Uniform Distribution + + + +```json +"z": { + "distribution": "uniform", + "extent": ["v.boulder_spread.start", "v.boulder_spread.end"] +} +``` + +**Uniform distribution** is uniformly random distribution on a half-open interval between two values. It is known as “uniform” because every value within the range has an equal chance of being selected and “half-open” because the extent minimum is a member of the range, while the extent maximum is not: + +_minimum extent_ <= _x_ < _maximum extent_ + +Therefore, if an extent of `[0, 16]` were given for a uniform distribution, blocks may be placed in a range of size 16: from 0 to 15. The 1st possible position starts at 0 while the 15th possible position ends at 16, matching the extent. + +###### Gaussian Distributions + + + +```json +"y": { + "distribution": "gaussian", + "extent": [0, "2 * v.vine_cluster.radius"] +} +``` + +**Gaussian distribution** (`"gaussian"`) and its **inverse** (`"inverse_gaussian"`) are useful for grouping features together: toward or away from the center of the extent respectively. Gaussian distribution is so extreme that values will almost never be selected away from the center with normal Gaussian distribution or toward the center with inverse Gaussian distribution. The extents for Gaussian distribution behave the as with [uniform distribution](#uniform-distribution). + +###### Grid Distributions + + + +```json +"x": { + "distribution": "jittered_grid", + "extent": [0, 15], + "step_size": 2, + "grid_offset": 4 +} +``` + +**Grid distributions** are powerful systems for placing blocks either directly on (`"fixed_grid"`) or randomly within (`"jittered_grid"`) evenly spaced intervals along a coordinate. Unlike the other distribution types, the extent of grids forms an interval that includes the maximum extent: + +_minimum extent_ <= _x_ <= _maximum extent_ + +Two grid distribution-only properties are available for finer control over the grids used by these systems. The interval size, which defaults to 1, can be customized with the `"step_size"` property. An initial offset, defaulting to 0, can also be provided via the `"grid_offset"` property. + +If the iteration count in conjunction with the step size and offset would push a coordinate beyond the maximum extent, the coordinate will be wrapped back to the minimum extent and continue from there. + +While grids are useful on a coordinate independently, their true power shows when in combination with grid distributions on other coordinates. Placements prioritize incrementing the earliest evaluated grid system before later systems; the later layouts are only considered when wrapping occurs in the previous grid system. When a placement in an earlier evaluated coordinate would wrap, the next evaluated grid-powered coordinate will be offset by the number of wraps that occurred. + +As a simple example: + + + +```json +"iterations": 21, + +"x": { + "distribution": "fixed_grid", + "extent": [0, 15] +}, +"z": { + "distribution": "fixed_grid", + "extent": [0, 15] +} +``` + +Placements will first begin along _x_: (0, 0), (1, 0), etc., until reaching the end of the extent at (15, 0). However, only 16 of the 21 iterations have occurred; 5 remain. Now, the _x_-coordinate wraps back around to 0, while the _z_-coordinate increments to 1: (0, 1). + +This wrapping occurs in three-dimensions, too, so when a plane along the earliest evaluated coordinates would wrap (assuming a high enough iteration count), another plane will begin formation based on the final coordinate’s step size. + +::: warning +Grid extents behave in unexpected ways when 0 is not within the extent range. In particular, the extent will be projected into 0 by the closest bound. For example, the given extent `[-7, -2]` will be remapped as though it were `[-5, 0]`. `[13, 21]` would get remapped to `[0, 8]`. For this reason, it's recommended to just specify the extent as a length, such as using `[0, 8]` in the latter example, and proxying that scatter feature with another scatter feature that would position that coordinate using a literal `13`. + +When using multiple grid distributions to form a surface or volume, extents for any coordinate that would extend below `0` will only work on the first pass of that coordinate. Later passes will be restricted to non-negative values. +::: + +#### Evaluation Order + +When a scatter chance is included, it is evaluated before any other properties. If the check against scatter chance fails for that instance of the scatter feature, nothing downstream within that instance is evaluated. No further Molang is interpreted; no variables within the [feature context](#) are updated. The target feature is entirely disregarded. + +Next, the iteration count is evaluated. Similarly to scatter chance, if the iteration count were not to resolve to a positive number of placement attempts, nothing further is evaluated. + +Next, every iteration is attempted regardless of whether an early iteration would for some reason fail. For each iteration, each coordinate is evaluated using the same ordering across all iterations. + +::: warning +The order of coordinate evaluation is _not_ dependent upon the order the coordinate properties are declared in JSON. +::: + +By default, the coordinate ordering is _x_ then _z_ then _y_. This covers the majority of use-cases: if the coordinates aren’t independent, more than likely the vertical position depends on the lateral coordinates. However, scatter features may declare an atypical **coordinate evaluation order** for full control over coordinate dependence: + + + +```json +"coordinate_eval_order": "zyx" +``` + +After the coordinates for an iteration have been determined, world generation moves its focus within the target: acknowledging its restrictions, attempting its placement, evaluating its Molang, and (if possible and relevant) continuing by placing its children and their children and so forth. + +When finished with the target’s feature tree, if more iterations have yet to be run from the scatter feature, focus returns to the scatter feature beginning with the first-evaluated coordinate and execution is resumed. + +### Conditional Lists + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:conditional_list": { + "description": { + "identifier": "olympus:columns_selection" + }, + + "conditional_features": [ + { + "places_feature": "olympus:columns_unweathered", + "condition": "q.noise(v.originx, v.originz) < 0" + }, + { + "places_feature": "olympus:columns_weathered", + "condition": 1 + } + ], + + "early_out_scheme": "placement_success" + } +} +``` + +**Conditional lists** pick a single feature from a collection based on conditions; they are akin to “if-else if” blocks in programming languages. Once a condition has been evaluated as successful (as determined via [success determination](#success-determination), the conditional list will select _only that one feature_ for placement. + +::: tip NOTE +Instead, if _every_ success should place a feature in the same location, use an [aggregate feature](#aggregate-features) pointing to [scatter features](#scatter-features) that proxy the target features. +::: + +#### Conditions List + + + +```json +"conditional_features": [ + { + "places_feature": "summer_fun:beachadjustment_water", + "condition": "q.heightmap(v.originx, v.originz) < 63 && q.noise(v.originx, v.originz) < 0" + }, + { + "places_feature": "summer_fun:beachadjustment_coral", + "condition": "q.heightmap(v.originx, v.originz) < 63 && q.noise(v.originx, v.originz) >= 0" + }, + { + "places_feature": "summer_fun:beachadjustment_air", + "condition": 1 + } +] +``` + +The **conditions list**, `"conditional_features"`, is an ordered array comprised of **feature entries** objects. Feature entries bind [**target features**](#proxy-features) to their **conditions**: + + + +```json +{ + "places_feature": "verona:evergreen_trees_stumps", + "condition": "v.evergreen_forest.type == v.evergreen_forest.types.lumberjack_ruined" +} +``` + +Conditions are given with the required `"condition"` property. Conditions are traditionally represented via Molang strings, but numbers may be used as well. `0` will always result in that feature entry being disabled. Non-zero values will always cause that entry to succeed. Generally, using `1` can be considered as a catch-all “else” or “default” clause — it should only be used at the very end of the conditions list. + +The condition of each feature entry is evaluated by entry order in the conditions list. Once a feature entry [would succeed](#success-determination), no later-listed conditions will be evaluated. + +#### Success Determination + + + +```json +"early_out_scheme": "placement_success" +``` + +Feature entry success is considered in light of the optional **early out scheme**. Two mechanisms are provided for controlling if a feature entry would succeed. `"condition_success"` — the default if no `"early_out_scheme"` is provided — considers a success to occur when a condition evaluates to true. `"placement_success"` goes further: a condition must evaluate to true, and its target feature’s placement must succeed. + +### Aggregate Features + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:aggregate_feature": { + "description": { + "identifier": "better_villages:village_center" + }, + + "features": [ + "better_villages:village_center_well", + "better_villages:village_center_grass_path" + ], + "early_out": "first_failure" + } +} +``` + +**Aggregate features** successively place features from a given list at the input location. Aggregate features are typically used to build custom scenes comprised of many disparate features. + +The features to be placed by the aggregate are given by the required **features list**. Each feature in this list — [if placed](#placement-escape) — will be positioned _in order of declaration_ at the same spot. Aggregate features will often need to point to [scatter features](#scatter-features) to position elements of a scene. + +#### Placement Escape + + + +```json +"early_out": "first_success" +``` + +By default, every entry in the features list will attempt to be placed. A **placement escape** is provided via the `"early_out"` property, which accepts 3 values: + +| Value | Description | +| :---------------- | :--------------------------------------------------------------- | +| `"none"` | Attempt to place each feature (default) | +| `"first_success"` | Stop placing features once the first successful placement occurs | +| `"first_failure"` | Stop placing features once the first failed placement occurs | + +### Sequence Features + +::: warning +Sequence features are currently bugged and should not be used. Currently, all features in the features list generate at the same input location, like [aggregate features](#aggregate-features). +::: + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:sequence_feature": { + "description": { + "identifier": "first_nations:totem_pole" + }, + + "features": [ + "first_nations:totem_pole_base", + "first_nations:totem_pole_body", + "first_nations:totem_pole_head" + ] + } +} +``` + +**Sequence features** place a collection of features in spatial sequence. + +Features are ordered via the **features list**, given by the `"features"` property. The output location from the previous feature becomes the input location of the subsequent feature. As an example, if the origin of the sequence feature were at (0, 67, 0), and the first listed feature were a column that extended 10 blocks vertically, the input position for the next listed feature would be (0, 77, 0). + +### Snap-to-Surface Features + + + +```json +{ + "format_version": "1.16.0", + + "minecraft:snap_to_surface_feature": { + "description": { + "identifier": "herbs_and_spices:underground_silas_plant_snap" + }, + + "feature_to_snap": "herbs_and_spices:underground_silas_plant", + + "surface": "floor", + "vertical_search_range": 12 + } +} +``` + +Features can be pinned to a floor or ceiling when proxied by **snap-to-surface features**. Currently, the **target feature**, given with `"feature_to_snap"`, can only be projected through air onto solid surfaces. + +#### Surface Search + + + +```json +"surface": "ceiling", +"vertical_search_range": 16 +``` + +Snap-to-surface features effectively remap the input _y_ coordinate to a usable surface for a proxied feature. This **target surface** is given with the optional `"surface"` property, which accepts either `"floor"` or `"ceiling"`, defaulting to `"floor"`. The remapping occurs by beginning at the [feature origin](#) and searching vertically down (if targeting floors) or up (if targeting ceilings) for a surface, which seemingly must be a solid block. + +::: warning +The feature origin must begin in air (even if just one block of it), or the surface search will immediately fail. +::: + +The distance that should be searched is given with the required `"vertical_search_range"` property, which has no reasonable limit. Unfortunately, the actual range isn’t particularly intuitive. The range acts as though it were 2 less than this value. As an example, starting from a _y_ of 70 and using a search range of `5` can position features from 67 to 70. If targeting a ceiling from 48 with a range of `6`, features may be placed from 48 to 52. + +### Search Features + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:search_feature": { + "description": { + "identifier": "search_features:search_feature" + }, + + "places_feature": "search_features:search_feature_obsidian", + + "search_volume": { + "min": [0, 0, 0], + "max": [7, 7, 7] + }, + + "search_axis": "y", + "required_successes": 512 + } +} +``` + +**Search features** search a volume for valid placement locations for a target feature. These features are a great option when positioning features with challenging placement conditions. + +The **target feature** is placed with the `"places_feature"` property. The success of its placement depends on whether a [successes threshold](#search-specifications) is met within a [search volume](#search-volume). The placement conditions of the target feature are successively checked at each location within the volume before any placement occurs. + +#### Search Volume + + + +```json +"search_volume": { + "min": [-12, 0, -12], + "max": [11, 11, 11] +}, +``` + +The **search volume** declares the space in which the search will occur. Two vectors define the bounds of this volume: `"min"`, which points to the corner with the lowest coordinates and `"max"`, which points to the _origin of the block_ in the opposite corner of the prism. The coordinates of the maximum corner therefore extend 1 block in each dimension beyond what is given by the `"max"` vector. As an example, the following search volume actually covers 8 blocks (2 in each dimension), not 1: + + + +```json +"search_volume": { + "min": [0, 0, 0], + "max": [1, 1, 1] +}, +``` + +These vectors only accept numbers and are relative to the [feature origin](#) + +#### Search Specifications + + + +```json +"search_axis": "z", +"required_successes": 16 +``` + +Within the given search volume, positions are checked layer by layer according to the `"search_axis"` property, which accepts `"+x"`, `"-x"`, `"+y"`,`"-y"`, `"+z"`, or `"-z"`. The other dimensions within a layer of the specified search axis are checked in a grid until reaching their respective boundaries before the next search axis layer is checked. In particular, the order of coordinates checked is: + +- The earliest of _x_ or _y_ that _isn’t_ a search axis +- The earliest remaining of _y_ or _z_ that _isn’t_ a search axis +- The specified search axis + +The feature is only placed if the number given by the optional `"required_successes"` property is met while scanning the search volume. If the property is omitted, only one success in the entire volume must be found for feature placement to succeed. + +#### Search Procedure + +The search begins at the position given by the [minimum vector](#search-volume) relative to the [feature origin](#). This position is updated one coordinate at a time, as determined by the [search axis](#search-axis). When the maximum for a coordinate is reached, the position is wrapped to the start of the next coordinate; if iterating over the search axis, the specified direction (`+` or `-`) is considered. At each position, the search conditions innate to the [target feature](#search-features) are checked. Once the number of successes found reaches the [required successes threshold](#search-specifications) (or once one such success is found if no threshold is provided), the target feature is placed at _every_ such success. No features are placed prior to the threshold being reached. + +### Rect Layouts + +::: warning +Rect layouts are currently bugged and should not be used. No information has been provided about how they will work. Presumably, rect layouts divide the surface area of a chunk into the provided rectangles given by `"area_dimensions"` and place their associated features based on the declared ratio of empty space. +::: + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:rect_layout": { + "description": { + "identifier": "gardenpalooza:garden_maze" + }, + + "ratio_of_empty_space": 0.5, + "feature_areas": [ + { + "feature": "gardenpalooza:flower_patch", + "area_dimensions": [2, 4] + }, + { + "feature": "gardenpalooza:garden_hedge", + "area_dimensions": [1, 3] + } + ] + } +} +``` + +### Scan Surface Features + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:scan_surface": { + "description": { + "identifier": "yosemite:fallen_leaves_cover" + }, + + "scan_surface_feature": "yosemite:fallen_leaves" + } +} +``` + +Every block across the surface of a chunk can be covered by a feature using **scan surface features**. For this reason, it is strongly recommended to choose a feature that only occupies a column’s space. + +The **target feature** to be placed is given with the `"scan_surface_feature"` property. Placement position is the same as [the Molang query `heightmap`](#), which means that water surfaces are used instead of their floors. It is therefore typically recommended to use [scatter features](#scatter-features) with a _y_ expression utilizing the [`above_top_solid` query](#). + +### Weighted Random Features + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:weighted_random_feature": { + "description": { + "identifier": "sweet_tooth:gelatin" + }, + + "features": [ + ["sweet_tooth:gelatin_green", 3], + ["sweet_tooth:gelatin_red", 3], + ["sweet_tooth:gelatin_blue", 2], + ["sweet_tooth:gelatin_purple", 1] + ] + } +} +``` + +**Weighted random features** randomly select a feature from a list. They are typically used to provide variation across a set of related features. + +Weighted random features select from their **weighted feature list**. Each entry in the list is an array made of a feature reference and an integer weight. A weighted random feature can select a different feature each instance it is run. + +::: tip NOTE +To understand how weights work, see [the associated section in Probabilities](#). +::: + +## Scene Features + +Scene features are a sort of combination of content features and proxy features. They are opinionated feature types designed around an aesthetic necessary for vanilla generation. + +Scene features only allow minimal customizations of their shapes to achieve their intended aesthetic. Like content features, though, their blocks are conveniently modifiable, and like proxy features, they can place their own sub-features. + +### Geode Features + + + +```json +{ + "format_version": "1.13.0", + "minecraft:geode_feature": { + "description": { + "identifier": "insectorium:wasp_hive" + }, + + "max_radius": 12, + + "filler": "minecraft:air", + + "inner_layer": "insectorium:wasp_hive_inside", + "alternate_inner_layer": "insectorium:wasp_hive_spawner_base", + "use_alternate_layer0_chance": 0.125, + + "middle_layer": "insectorium:wasp_hive_inside", + + "outer_layer": "insectorium:wasp_hive_shell", + + "inner_placements": ["insectorium:wasp_hive_spawner"], + "placements_require_layer0_alternate": true, + "use_potential_placements_chance": 1, + + "min_distribution_points": 2, + "max_distribution_points": 4, + "min_outer_wall_distance": 2, + "max_outer_wall_distance": 4, + "min_point_offset": 0, + "max_point_offset": 2, + "noise_multiplier": 0.125, + "invalid_blocks_threshold": 64, + + "crack_point_offset": 0, + "generate_crack_chance": 1, + "base_crack_size": 1 + } +} +``` + +**Geode features** construct spherical structures comprised of multiple block layers; they allow placement of sub-features along walls of the interior. + +### Beards and Shavers + +::: warning +Beards and shavers are currently bugged and should be avoided. In particular, the platform is poorly constructed, with the surface block usually generating on the incorrect layer and the shape being cut off awkwardly. +::: + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:beards_and_shavers": { + "description": { + "identifier": "broadmoor_wars:highland_tower_foundation" + }, + + "places_feature": "broadmoor_wars:highland_tower", + "y_delta": 0, + + "bounding_box_min": [-4, 0, -4], + "bounding_box_max": [5, 12, 5], + "beard_raggedness_min": 0.25, + "beard_raggedness_max": 0.5, + + "surface_block_type": "minecraft:grass", + "subsurface_block_type": "minecraft:dirt" + } +} +``` + +**Beards and shavers** simultaneously provide a platform (beard) and a clearance (shaver) for a feature to generate. + +### Vegetation Patch Features + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:vegetation_patch_feature": { + "description": { + "identifier": "tension:shiitake_patch" + }, + + "horizontal_radius": 4, + "extra_edge_column_chance": 0.5, + + "surface": "floor", + "vertical_range": 5, + + "ground_block": "minecraft:mycelium", + "replaceable_blocks": ["minecraft:dirt", "minecraft:grass"], + "depth": 4, + "extra_deep_block_chance": 0.5, + + "vegetation_feature": "tension:shiitake_mushroom", + "vegetation_chance": 0.125 + } +} +``` + +**Vegetation patches** place sub-features (often vegetation) within a square-like boundary (the patch). + +Vegetation patches fundamentally perform 4 operations: + +- Determine a lateral patch shape from a given radius +- Search vertically from the [input position](#) of every block in the shape for a surface (ceiling or floor) +- Place columns of blocks into the surface +- Generate sub-features randomly within the created patch + +#### Patch Shape + + + +```json +"horizontal_radius": 3, +"extra_edge_column_chance": 0.25 +``` + +Vegetation patches commence by constructing the patch’s lateral shape. This shape is centered on the _x_ and _z_ of the [input position](#). From here, the required `"horizontal_radius"` specifies how far away in all lateral directions the initial shape should extend. This shape doesn’t use [taxicab distance](#); instead, the corners are filled in, constructing a simple square. The size of this square is given by: + +_horizontal radius_ \* 2 + 1 + +Therefore, a horizontal radius of 4 will generate a square of side length 9, centered on the input _x_ and _z_. + +Patch shape can be mildly randomized using the optional `"extra_edge_column_chance"` property. This property accepts values between `0`, the default, and `1` inclusively, indicating the odds for any of the blocks along the outside of the perimeter to be included in the patch shape. These perimeter blocks do not include the outer perimeter corners. If the corners are ignored, setting this property to `1` is equivalent to increasing the horizontal radius by 1. + +#### Patch Search + + + +```json +"surface": "ceiling", +"vertical_range": 8 +``` + +The vegetation patch then searches each column within the determined patch shape from the _y_-component of the [input position](#) vertically to find the appropriate surface, given with the optional `"surface"` property. Either `"floor"` (the default if unspecified) or `"ceiling"` may be provided. The surface search only functions against air; no other contrast of blocks may be used. The search itself, however, may begin from within any block. + +The distance searched is given with `"vertical_range"`, which is required and has no tangible limit. The search occurs bidirectionally. As an example, if starting from a _y_ of 70 and using a vertical range of `5`, surfaces between 65 and 75 inclusively will succeed. + +Only the first matched surface within range in a column will be used. When targeting floor surfaces, the first match is the highest surface. If targeting ceilings, the first match is the lowest surface. + +#### Patch Column Placement + + + +```json +"ground_block": "arabia:lush_sand", +"waterlogged": true, +"replaceable_blocks": [ + "minecraft:sand", + "minecraft:sandstone" +], +"depth": 2, +"extra_deep_block_chance": 0.75 +``` + +Patch column generation is then attempted in each column whose surface search succeeds. Columns are generated procedurally, starting at the input position and continuing away into the surface. + +The block that forms the solid foundation of the patch is given with the `"ground_block"`. Its length into the surface is given with `"depth"`. As expected, a depth of `0` will generate no blocks as part of the patch column, but negative values will generate a column that continues indefinitely until reaching a non-whitelisted block. + +The optional `"extra_deep_block_chance"` property provides a chance for each column to attempt generation of an additional block, increasing the depth of that column by 1. It takes a value between `0` and `1` inclusively, defaulting to 0. Setting the property to `1` has the same effect as increasing the depth by 1. + +::: tip NOTE +The [vertical range](#patch-search) takes no further affect in generation after the search phase. If a column were to barely be within search range, its entire depth would still be attempted. Furthermore, if a surface would be out of the vertical range but blocks in that column would fall within the range, those blocks will still be ignored. Placement begins from the surface and continues downward when targeting [floor surfaces](#patch-search), and vice versa. +::: + +A whitelist of blocks must be provided via the `"replaceable_blocks"` property. When generating a patch column, each block is checked and placed in order. If a non-whitelisted block is detected, generation of that column ceases. It is therefore possible for columns not to reach their target depth. Failure of a single column’s generation has no effect on other columns. + +Lastly, the optional boolean `"waterlogged"` property attempts to replace the topmost block in a patch column with water when set to true and `"surface"` is `"floor"`. Water will therefore be exposed to air along the surface. Water will not be substituted if one of its lateral faces is attached to air; this prevents water from spilling out. If `"waterlogged"` is omitted, water generation is disabled by default. When `"depth"` is `0` and waterlogging is enabled, blocks not whitelisted may be replaced with water anyway. For all other depth values, only whitelisted blocks will be replaced with water. + +#### Vegetation Placement + + + +```json +"vegetation_feature": "tension:shiitake_mushroom", +"vegetation_chance": 0.125 +``` + +Finally, vegetation patches take a vegetation feature and corresponding generation chance to place sub-features at random locations on the surface of the patch. The sub-feature is given with the required `"vegetation_feature"` property. Every surface block generated has a chance to support this vegetation feature. + +::: warning +Vegetation features multiple blocks in height that are attached to the surface of ceilings will still generate _upward_ naturally. They must be constructed or proxied in such a way to generate downward from the ceiling. +::: + +The chance that any block surface is selected as an input position for the sub-feature is given with the optional `"vegetation_chance"` float property, which defaults to `0`. Like the other chances in vegetation patch features, it ranges from 0 to 1 inclusively, where `0` will generate no sub-features and `1` will attempt to generate one for each block surface. Be wary of vegetation features that span more than a single column; collisions may occur, clumping individual features into a single mass. + +For [floor-bound](#patch-search) patches, if [`"waterlogged"`](#patch-column-placement) is `false`, vegetation features generate directly on the surface and have the potential to generate on surface edges. If waterlogging is enabled, however, vegetation features can’t generate on surface edges but may generate in water, waterlogging the block if supported. When the [`"depth"`](#patch-column-placement) is `0`, sub-features may be placed even though no patch blocks support them. + +::: warning +If waterlogging is enabled on a ceiling-targeting vegetation patch feature, no vegetation features will be placed. +::: + +## Carver Features + +Carver features are special feature types for modifying vanilla cave generation. Little can currently be customized using carvers. Carvers only include the classic spaghetti caves and not ravines or structures. + +All carver features require being placed in the [pregeneration pass](#). Carver features can therefore not be combined with any other features by any means, even by proxies. + +Carvers work by culling blocks around predetermined paths; these paths are unchangeable. Instead, carver features allow for customization of the **width modifier**, which is added to the base width variance provided by the game. This property is available across all carver features as `"width_modifier"`. Width modifiers only affect the lateral distance around the carver path, not the height. Negative values behave as normal subtraction: shrinking the carver instead of dilating it; low enough values, around `-16`, can be used on the vanilla carvers to remove caves. + +::: warning +Although listed in the features schema as optional, `"width_modifier"` should always be provided; errors will be thrown relentlessly, and entire chunks will appear corrupted. Furthermore, large values for the width modifier (greater than approximately `16`) shouldn’t be used: world loading slows to a crawl, and chunks may get culled in entirety. +::: + +Carvers don’t truly _cull_ blocks per se; instead they replace existing blocks (such as from biome surface builders or earlier-placed carvers) with a **fill block**. The fill block can be provided with the optional `"fill_with"` property, whose default depends on the carver type; this property, too, is usable in all carver feature types. + +::: warning +The block intersection set for carvers currently cannot be customized. Only vanilla blocks specific to each carver type will be replaced; custom blocks cannot be stripped to form caves. +::: + +### Cave Carver Features + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:cave_carver_feature": { + "description": { + "identifier": "spelunkers_dreams:massive_cave" + }, + + "width_modifier": 4 + } +} +``` + +The classic Overworld caving system is controlled using **cave carver features**. These carvers only work when used in the Overworld. + +Overworld caves naturally extend from just above the bedrock layer at _y_-3 to *y*s of indeterminate values over 100. The fill block for cave carver features defaults to air if omitted. Cave carver features strip typical Overworld surface and foundation blocks, such as stone variants, dirt variants, sand variants, and sandstone. However, water is not culled, and water in oceans and rivers is aggressively avoided. + +### Underwater Cave Carver Features + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:underwater_cave_carver_feature": { + "description": { + "identifier": "aquamarine:underwater_thick_caves" + }, + + "width_modifier": 8 + } +} +``` + +**Underwater cave carver features** generate caves at lower heights in the Overworld — below the sea level of 63. These carvers, too, only work in the Overworld. Underwater carver features accept an additional optional property, `"replace_air_with"`, which is intended to substitute intersections of pre-existing air with a given block. + +::: warning +This property currently seems non-functional. Whether acting on a biome whose foundation was air or intersecting an earlier-placed [cave carver feature](#cave-carver-feature) that used air, the intersecting air was never successfully replaced during testing. +::: + +Underwater carvers replace the same natural vanilla blocks as [cave carver features](#cave-carver-features) with one addition: water. This means spiraling masses can be constructed from the fill block in underwater settings. Underwater carvers can begin at a height of 3; they won’t ever operate above _y_-63 (the Overworld sea level) even if they have the opportunity to do so. + +::: warning +Underwater cave carvers won’t function in custom biomes — even if that biome uses vanilla blocks. +::: + +### Hell Cave Carver Features + + + +```json +{ + "format_version": "1.13.0", + + "minecraft:hell_cave_carver_feature": { + "description": { + "identifier": "hellscape:nether_caves" + }, + + "fill_with": "minecraft:magma", + "width_modifier": 1 + } +} +``` + +Nether-based caves are formed via **Hell cave carver features**. Surprisingly, these carvers may be used in the Overworld in addition to the Nether; [biome filters]() must be applied to the feature rule to limit this occurrence. + +Nether carvers extend from *y*s of 5 to 121, and their fill block defaults to air. Hell carvers strip the same set of blocks as [cave carver features](#cave-carver-features) with a few exceptions: hell carvers won’t strip sand variants or sandstone but will remove Netherrack and water. diff --git a/docs/wiki/world-generation/heightmap-noise.md b/docs/wiki/world-generation/heightmap-noise.md new file mode 100644 index 00000000..0a78a53d --- /dev/null +++ b/docs/wiki/world-generation/heightmap-noise.md @@ -0,0 +1,116 @@ +--- +title: Heightmap Noise +category: Tutorials +tags: + - experimental + - tutorial +mentions: + - Apex360 + - SirLich +--- + +:::tip +This tutorial assumes you have a basic understanding of molang, features and feature rules. +::: + +In this tutorial we're gonna see how we can make noise based terrain using the `q.noise` molang query. + +## Single Block Feature + +First we will define the single block feature. It will define the block that is going to be generated. For this tutorial I'll use stone. + +BP/features/stone_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:single_block_feature": { + "description": { + "identifier": "wiki:stone_feature" + }, + "places_block": "minecraft:stone", + "enforce_survivability_rules": false, + "enforce_placement_rules": false + } +} +``` + +## Scatter Feature + +The scatter feature is the main feature which we'll be using to generate the terrain. + +BP/features/column.json + +```json +{ + "format_version": "1.13.0", + "minecraft:scatter_feature": { + "description": { + "identifier": "wiki:column" + }, + "iterations": "t.height=64+(q.noise(v.originz/64,v.originx/64))*16; return t.height;", + "places_feature": "wiki:stone_feature", + "x": 0, + "z": 0, + "y": { + "extent": [-64, "t.height"], + "distribution": "fixed_grid" + } + } +} +``` + +Let me explain whats happening in the `iterations`: +In the iterations we've defined a temp `t.height` in which we've defined our main noise function. +In `t.height` the value that we're adding first is the base height, basically the height at which the function starts. +After that we're querying perlin using the `q.noise` query which returns values ranging from -1 to 1 and dividing that by a value which smooths out the function. +Then we're multiplying the whole function by a value which in simple words is basically the variation in the terrain. + +So what's happening here is that we are getting values from the `t.height` temp and assigning them to the y extent ranging from -64 to the value thus generating a column. Now this value is going to vary column by column but not in a random way as `q.noise` queryies Perlin noise, meaning the values are relative to each other. So instead of getting values like 64,69,45,100,7,56 we are getting values like 64,65,66,68,69,68,66,65 and so on. + +## Feature Rule + +BP/feature_rules/column_grid_placement.json + +```json +{ + "format_version": "1.13.0", + "minecraft:feature_rules": { + "description": { + "identifier": "wiki:column_grid_placement", + "places_feature": "wiki:column" + }, + "conditions": { + "placement_pass": "first_pass", + "minecraft:biome_filter": { + "any_of": [ + { + "test": "has_biome_tag", + "value": "overworld" + }, + { + "test": "has_biome_tag", + "value": "overworld_generation" + } + ] + } + }, + "distribution": { + "iterations": 256, + "x": { + "extent": [0, 15], + "distribution": "fixed_grid" + }, + "y": 0, + "z": { + "extent": [0, 15], + "distribution": "fixed_grid" + } + } + } +} +``` + +In this we have set the `iteration` to 256 as the area of a whole chunk is 256 (16x16) to make the columns generate in the whole chunk. + +And our custom noise based terrain is finished! Feel free to mess with the values. diff --git a/docs/wiki/world-generation/index.md b/docs/wiki/world-generation/index.md new file mode 100644 index 00000000..cc5cae1b --- /dev/null +++ b/docs/wiki/world-generation/index.md @@ -0,0 +1,10 @@ +--- +title: World Generation +categories: + - title: General + color: blue + - title: Tutorials + color: green + - title: Documentation + color: red +--- diff --git a/docs/wiki/world-generation/structure-features.md b/docs/wiki/world-generation/structure-features.md new file mode 100644 index 00000000..0b875f7e --- /dev/null +++ b/docs/wiki/world-generation/structure-features.md @@ -0,0 +1,393 @@ +--- +title: Generating Custom Structures +category: Tutorials +mentions: + - DerpMcaddon + - SirLich +tags: + - experimental +--- + +Structure feature is one of the most basic feature. It places exported `.mcstructure` file in the world. +This tutorial will show you how to make: + +- Surface structure, + +- Underground structure, + +- Floating structure, + +- Underwater structure, and + +- Water surface structure + +:::tip +For exporting structure on android devices, use this [resource pack](https://mcpedl.com/export-structure-button-android-addon/) +::: + +Make sure you put the `.mcstructure` file inside of `BP/structures/`! + +## Surface Structure + +### Feature File + +BP/features/house_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:structure_template_feature": { + "description": { + "identifier": "wiki:house_feature" + }, + "structure_name": "mystructure:house", + "adjustment_radius": 4, + "facing_direction": "random", + "constraints": { + "grounded": {}, + "unburied": {}, + "block_intersection": { + "block_allowlist": [ + "minecraft:air" //The structure can only replace air + ] + } + } + } +} +``` + +### Feature Rule + +BP/feature_rules/plains_house_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:feature_rules": { + "description": { + "identifier": "wiki:plains_house_feature", + "places_feature": "wiki:house_feature" + }, + "conditions": { + "placement_pass": "first_pass", + "minecraft:biome_filter": { + "test": "has_biome_tag", + "operator": "==", + "value": "plains" + } + }, + "distribution": { + "iterations": 1, + "x": { + "extent": [0, 16], + "distribution": "uniform" + }, + "y": "q.heightmap(v.worldx, v.worldz)", //Generates the feature on the highest block on the column + "z": { + "extent": [0, 16], + "distribution": "uniform" + }, + "scatter_chance": { + "numerator": 1, + "denominator": 25 + } + } + } +} +``` + +![](/assets/images/world-generation/structure-features/house.png) + +## Underground Structure + +### Feature File + +BP/features/bunker_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:structure_template_feature": { + "description": { + "identifier": "wiki:bunker_feature" + }, + "structure_name": "mystructure:bunker", + "adjustment_radius": 4, + "facing_direction": "random", + "constraints": { + "block_intersection": { + "block_allowlist": [ + "minecraft:air", //Makes the feature only replace air and stone + "minecraft:stone" + ] + } + } + } +} +``` + +### Feature Rule + +BP/feature_rules/overworld_bunker_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:feature_rules": { + "description": { + "identifier": "wiki:overworld_bunker_feature", + "places_feature": "wiki:bunker_feature" + }, + "conditions": { + "placement_pass": "first_pass", + "minecraft:biome_filter": { + "test": "has_biome_tag", + "operator": "==", + "value": "overworld" + } + }, + "distribution": { + "iterations": 1, + "x": { + "extent": [0, 16], + "distribution": "uniform" + }, + "y": { + "extent": [ + 11, + 50 //Makes the structure generate between y11 and y50 + ], + "distribution": "uniform" + }, + "z": { + "extent": [0, 16], + "distribution": "uniform" + }, + "scatter_chance": { + "numerator": 1, + "denominator": 15 + } + } + } +} +``` + +![](/assets/images/world-generation/structure-features/bunker.png) + +## Floating Feature + +### Feature File + +BP/features/balloon_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:structure_template_feature": { + "description": { + "identifier": "wiki:balloon_feature" + }, + "structure_name": "mystructure:balloon", + "adjustment_radius": 4, + "facing_direction": "random", + "constraints": { + "block_intersection": { + "block_allowlist": [ + "minecraft:air" //Makes the structure only replace air + ] + } + } + } +} +``` + +### Feature Rule + +BP/feature_rules/overworld_balloon_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:feature_rules": { + "description": { + "identifier": "wiki:overworld_baloon_feature", + "places_feature": "wiki:balloon_feature" + }, + "conditions": { + "placement_pass": "first_pass", + "minecraft:biome_filter": { + "test": "has_biome_tag", + "operator": "==", + "value": "overworld" + } + }, + "distribution": { + "iterations": 1, + "x": { + "extent": [0, 16], + "distribution": "uniform" + }, + "y": { + "extent": [ + 100, //Makes the structure generate from y100 to y200 + 200 + ], + "distribution": "uniform" + }, + "z": { + "extent": [0, 16], + "distribution": "uniform" + }, + "scatter_chance": { + "numerator": 1, + "denominator": 25 + } + } + } +} +``` + +![](/assets/images/world-generation/structure-features/balloon.png) + +## Underwater Structure + +::: tip +For underwater structures, make sure you waterlogged the structure, because Minecraft won't waterlog them automatically! +::: + +### Feature File + +BP/features/aqua_temple_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:structure_template_feature": { + "description": { + "identifier": "wiki:aqua_temple_feature" + }, + "structure_name": "mystructure:aqua_temple", + "adjustment_radius": 4, + "facing_direction": "random", + "constraints": { + "block_intersection": { + "block_allowlist": [ + "minecraft:water" //Makes the structure only replace water + ] + } + } + } +} +``` + +### Feature Rule + +BP/feature_rules/ocean_aqua_temple_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:feature_rules": { + "description": { + "identifier": "wiki:ocean_aqua_temple_feature", + "places_feature": "wiki:aqua_temple_feature" + }, + "conditions": { + "placement_pass": "first_pass", + "minecraft:biome_filter": { + "test": "has_biome_tag", + "operator": "==", + "value": "ocean" + } + }, + "distribution": { + "iterations": 1, + "x": { + "extent": [0, 16], + "distribution": "uniform" + }, + "y": "q.above_top_solid(v.worldx, v.worldz)", //Places the feature on top of the highest solid block on the column, so it won't place it on the surface of the water + "z": { + "extent": [0, 16], + "distribution": "uniform" + }, + "scatter_chance": { + "numerator": 1, + "denominator": 25 + } + } + } +} +``` + +![](/assets/images/world-generation/structure-features/aqua_temple.png) + +## Water Surface Structure + +### Feature File + +BP/features/raft_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:structure_template_feature": { + "description": { + "identifier": "wiki:raft_feature" + }, + "structure_name": "mystructure:raft", + "adjustment_radius": 4, + "facing_direction": "random", + "constraints": { + "block_intersection": { + "block_allowlist": [ + "minecraft:water", //Makes the structure only replace air and water + "minecraft:air" + ] + } + } + } +} +``` + +### Feature Rule + +BP/feature_rules/ocean_raft_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:feature_rules": { + "description": { + "identifier": "wiki:ocean_raft_feature", + "places_feature": "wiki:raft_feature" + }, + "conditions": { + "placement_pass": "first_pass", + "minecraft:biome_filter": { + "test": "has_biome_tag", + "operator": "==", + "value": "ocean" + } + }, + "distribution": { + "iterations": 1, + "x": { + "extent": [0, 16], + "distribution": "uniform" + }, + "y": 62, //Makes the feature generate only on y62, which is Minecraft water level + "z": { + "extent": [0, 16], + "distribution": "uniform" + }, + "scatter_chance": { + "numerator": 1, + "denominator": 25 + } + } + } +} +``` + +![](/assets/images/world-generation/structure-features/raft.png) diff --git a/docs/wiki/world-generation/surface-builder.md b/docs/wiki/world-generation/surface-builder.md new file mode 100644 index 00000000..21e2e63f --- /dev/null +++ b/docs/wiki/world-generation/surface-builder.md @@ -0,0 +1,202 @@ +--- +title: Generating Patches +category: Tutorials +mentions: + - DerpMcaddon + - SirLich +tags: + - experimental +--- + +Feature based surface builder is a feature that puts together a collection of blocks that serve to add variety and decoration to the Overworld surface. This tutorial will explain what is needed to create this feature, including size, frequency, generation location, and more! + +## Single Block Features + +Single block features are going to be the base of our surface builder. They will define which blocks we are going to use. For this tutorial I'll be using Coarse Dirt, Podzol and Cobblestone. + +Learn more about single block features [here](/world-generation/feature-types#single-block-features) + +Coarse Dirt File + +BP/features/coarse_dirt_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:single_block_feature": { + "description": { + "identifier": "wiki:coarse_dirt_feature" + }, + "places_block": { + //Coarse dirt shares same identifier as dirt, set it using name and states + "name": "minecraft:dirt", + "states": { + "dirt_type": "coarse" + } + }, + "enforce_survivability_rules": false, + "enforce_placement_rules": false, + "may_replace": [ + "minecraft:grass" //The block can only replace grass + ] + } +} +``` + +Podzol File + +BP/features/podzol_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:single_block_feature": { + "description": { + "identifier": "wiki:podzol_feature" + }, + "places_block": "minecraft:podzol", //Podzol can be defined using direct identifier + "enforce_survivability_rules": false, + "enforce_placement_rules": false, + "may_replace": [ + "minecraft:grass" //The block can only replace grass + ] + } +} +``` + +Cobblestone File + +BP/features/cobblestone_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:single_block_feature": { + "description": { + "identifier": "wiki:cobblestone_feature" + }, + "places_block": "minecraft:cobblestone", //Cobblestone can be defined using direct identifier + "enforce_survivability_rules": false, + "enforce_placement_rules": false, + "may_replace": [ + "minecraft:grass" //The block can only replace grass + ] + } +} +``` + +## Weighted Random Features + +Weighted random features are going to be our _randomizer_ to select between each type of blocks. + +Learn more about weighted random features [here](/world-generation/feature-types#weighted-random-features) + +BP/features/select_surface_block_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:weighted_random_feature": { + "description": { + "identifier": "wiki:select_surface_block_feature" + }, + "features": [ + [ + "wiki:coarse_dirt_feature", //Coarse dirt weighs 5 + 5 + ], + [ + "wiki:podzol_feature", //Podzol dirt weighs 3 + 3 + ], + [ + "wiki:cobblestone_feature", //Cobblestone weighs 2 + 2 + ] + ] + } +} +``` + +## Scatter Features + +Scatter features are an important part of our surface builder. It will determine the size, shape and number of blocks in one blob. + +Learn more about scatter features [here](/world-generation/feature-types#scatter-features) + +BP/features/scatter_surface_block_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:scatter_feature": { + "description": { + "identifier": "wiki:scatter_surface_block_feature" + }, + "iterations": "math.random_integer(20,25)", + "x": { + "extent": [0, 8], + "distribution": "gaussian" + }, + "z": { + "extent": [0, 8], + "distribution": "gaussian" + }, + "y": "q.heightmap(v.worldx, v.worldz) -1", + "places_feature": "wiki:select_surface_block_feature" //Weighted random feature identifier + } +} +``` + +- `iterations` determine how many blocks will be placed. I'm going to use the Molang `math.random_integer` function to randomize the number of blocks. In this case, it'll be 20 to 25 blocks. + +- `extent` use an array to determine the size of the blob. `[0, 8]` means the size is extended from 0 to 8 blocks. So, our blob would be 8 blocks long both on X and Z axis. **Only use this for X and Z distribution**. + +- `"y": "q.heightmap(v.worldx, v.worldz) -1` means it will put the block on the highest block on the y coordinate -1. So it'll always put the feature on the surface. + +- `distribution` specifies the type of distribution to use. Available include `Gaussian`, `Inverse Gaussian`, `Uniform`,`Fixed Grid` and `Jittered Grid` + +## Feature Rule + +This is the final step for our surface builder. The feature rules for our surface builders are slightly different. + +BP/feature_rules/overworld_surface_blocks_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:feature_rules": { + "description": { + "identifier": "wiki:overworld_surface_blocks_feature", + "places_feature": "wiki:scatter_surface_block_feature" + }, + "conditions": { + "placement_pass": "surface_pass", + "minecraft:biome_filter": { + "test": "has_biome_tag", + "operator": "==", + "value": "overworld" //You can change this to whatever biometag you want + } + }, + "distribution": { + "iterations": 1, + "x": { + "extent": [0, 16], + "distribution": "uniform" + }, + "y": 0, + "z": { + "extent": [0, 16], + "distribution": "uniform" + }, + "scatter_chance": { + //Chance of the blob generating each chunk + "numerator": 1, + "denominator": 5 + } + } + } +} +``` + +And our surface builder is done! Feel free to modify and mess around with it! diff --git a/docs/wiki/world-generation/world-generation-intro.md b/docs/wiki/world-generation/world-generation-intro.md new file mode 100644 index 00000000..f8688f92 --- /dev/null +++ b/docs/wiki/world-generation/world-generation-intro.md @@ -0,0 +1,340 @@ +--- +title: Intro to World Generation +category: General +nav_order: 1 +tags: + - guide + - experimental +mentions: + - SirLich + - solvedDev + - Dreamedc2015 + - destruc7ion + - MedicalJewel105 + - aexer0e + - retr0cube + - SmokeyStack +--- + +:::warning +This page is somewhat out-dated, and contains limited information. For the most up-to-date and comprehensive information, view the other pages in this section. +::: + +You can change the world's generation via Add-ons. The needed folders in the Behavior pack for these are: + +`structures`, `features`, `feature_rules` and `biomes`. It's quite self-explanatory: you can store your .mcstructure files from (or for) structure blocks in `structures`, biome files in `biomes`, terrain features, like ores, in `features` and the rules for their generation in `feature_rules`. Let's go over adding a custom biome first. + +_Note: it might be easier to create biomes using bridge., a Visual software for Add-on creation (also linked in Links and Contact), since the official Documentation is rather incomplete. You can also generate all example files of vanilla biomes, features and feature rules for reference, like shown here:_ + +![](/assets/images/guide/gen_coal_ore.png) +_Generating a coal_ore feature using bridge._ + +However, bridge. is not required. + +--- + +## Custom Biomes + +BP/biomes/cold_biome.json + +```json +{ + "format_version": "1.13.0", + "minecraft:biome": { + "description": { + "identifier": "cold_biome" + }, + "components": { + "minecraft:climate": { + "downfall": 0.7, + "snow_accumulation": [0.6, 0.9], + "temperature": 15.0 + }, + "minecraft:overworld_height": { + "noise_params": [0.6, 0.9] + }, + "minecraft:surface_parameters": { + "sea_floor_depth": 7, + "sea_floor_material": "minecraft:blue_ice", + "foundation_material": "minecraft:cobblestone", + "mid_material": "minecraft:minecraft:concrete", + "top_material": "minecraft:glass", + "sea_material": "minecraft:water" + }, + "minecraft:overworld_generation_rules": { + "generate_for_climates": [ + ["medium", 100], + ["warm", 100], + ["cold", 100] + ] + }, + "cold_biome": {} + } + } +} +``` + +- Set `format_version` to 1.13.0: it's the latest biome file version as of the current release. +- `description` takes only one value: `identifier`. This requires **NO namespace** and **MUST** be the same as the **file's name**. + (If you do use a namespace, for example `wiki:cold_biome`, the file name needs to only match the id, so it has to remain as `cold_biome.json`. +- `components` is just what you'd expect: something applied to the biome at default. let's look through them: +- `minecraft:climate` controls everything climate-wise. +- `downfall` is how often it'll be raining or snowing. 0.0 is for absolutely no rain (like a desert) and 1.0 should mean constant rain. +- `temperature` is used to define things like water freezing and rain turning into snow. + +**You can generate default biome files for reference using bridge.** + +- `overworld_surface` controls blocks generated. +- `floor_depth` is how deep down lakes and rivers go in blocks. +- `sea_floor_material` defines the material to be used when generating the river and lake's floor. +- `foundation_material` is the material to be used approximately between y=5 and y=50. For a desert, for example, it's stone. +- `sea_material` is the material used as show liquid in lakes, rivers, oceans, etc. For example, in all Overworld biomes, this is set to "minecraft:water". +- `top_material` defines the material for the highest level. E.g for Plains it's grass. +- `mid_material` is the layer between 'top' and 'foundation'. For Plains it's dirt. +- `overworld_height` defines how the Biome will look terrain-wise. + +DO NOT use both `noise_type` and `noise_params` at the same time. `noise_params` is an array of the top level of noise and the lowest level of noise allowed in the biome. + +![](/assets/images/guide/non_smooth_noise_transition.jpg) +_A non-smooth transition between the same biome, generated with noise_params as [0.1, 0,1] and then [1.0, 1.0]._ + +- If you want to use `noise_type`, however, you will be presented with a few pre-generated types of noise. You will probably know how some of them look from the Vanilla game. Here's the list: + +`beach, default, extreme, taiga, ocean, mountains, default_mutated, deep_ocean, lowlands, less_extreme, stone_beach, swamp, river, mushroom`. + +- `minecraft_world_generation_rules` is the most important component of all, especially the `generate_for_climates` array. Basically, there are three climates in the game: "warm", "medium" and "cold". They are randomly thrown around every world when it's created [hard-coded]. Now, you can choose how often your custom biome will generate in every specific climate. If you do not provide anything in here, the default value is 0 for every climate, and the biome won't generate. In the example, the **weight** (the smaller the number, the smaller the chance of this biome generating instead of a vanilla one in the climate) for every climate is set to 100 for testing purposes: that makes the biome generate almost everywhere in the Overworld. Once I'm done with testing, however, I'll balance the weight how it's supposed to be. For example, the Vanilla _desert_ has the weight of 3 for warm. + +- This component also takes Objects such as: `hills_transformation`, `mutate_transformation`, `shore_transformation`, `river_transformation`, but their meaning is unclear to me. Contributions are always appreciated. Same goes for the `surface_meaterial_adjustments` component. + +- And, last but not least, BIOME TAGS! They're very simple, but useful. You can set however many of the vanilla or custom tags you want, by adding them in this format in `components`: + +``` +"tagName": {} +``` + +Then, you can test for your tag in _environment_sensors_, _filters_, _has_biome_ tests, _spawn rules_, and more. + +Your custom biome is now complete! + +--- + +## Features and Feature Rules + +Note: in v.1.15Beta, it is possible to use `.mcstructures` from the `structures` folder instead of `features` to generate custom structures with `feature_rules`. More on that after the update arrives. + +Features and Feature Rules are used to generate everything from ores to grass and flowers, vegetation to granite or clay patches. +It is even possible to create custom structures using those, but as it is very grindy and will be much easier after the mentioned update, we won't talk about it just yet. + +Now, it's worthwhile to mention that the easiest way to generate Custom Structures is this [auto generator](https://machine-builder.itch.io/frg-v2) by [MACHINE_BUILDER](https://www.youtube.com/channel/UC8FBQgo4AWwKFX97h60NKOQ), you should note that this tool has a free version with limited functionality and to enjoy the full functionality use the payware version. However, we'll still learn some other manual feature generation here, because some things like Ores are much more efficient to generate as `ore_feature`s and not `structure_template_feature`s. + +Let's make our `wiki:blocky` custom block generate as an ore for the tutorial's sake. I'll do it the easy way, like this: + +1. Open _bridge._, choose your Add-on. +1. _Add new file>features>diamond_ore and Add new file>feature_rules>diamond_ore_. +1. Now I'll save the files and open them in my Code Editor and make the necessary modifications. + +_You could've easily just written the files from scratch or copied them from somewhere without using bridge. in case you are having trouble installing it. **One place to find the Vanilla Files are the [Example Packs](https://www.minecraft.net/en-us/addons), another, a more complete one is [bridge.'s repository](https://github.com/bridge.-core/bridge../tree/master/static/vanilla)**._ + +## Features + +Features are located in `BP/features` and are basically a group of blocks stored in the game's files, which can be placed with a _feature_rule_. The **file name** of a _feature_ **must match** the **identifier** as well. + +You can find their Documentation on [bedrock.dev/r/Features](https://bedrock.dev/r/Features) + +BP/features/blocky_ore_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:ore_feature": { + "description": { + "identifier": "blocky_ore_feature" + }, + "count": 8, + "places_block": "wiki:blocky", + "may_replace": [ + { + "name": "minecraft:stone", + "states": { + "stone_type": "andesite" + } + }, + { + "name": "minecraft:stone", + "states": { + "stone_type": "andesite_smooth" + } + }, + { + "name": "minecraft:stone", + "states": { + "stone_type": "diorite" + } + }, + { + "name": "minecraft:stone", + "states": { + "stone_type": "diorite_smooth" + } + }, + { + "name": "minecraft:stone", + "states": { + "stone_type": "granite" + } + }, + { + "name": "minecraft:stone", + "states": { + "stone_type": "granite_smooth" + } + }, + { + "name": "minecraft:stone", + "states": { + "stone_type": "stone" + } + } + ] + } +} +``` + +- `minecraft_ore_feature` is type of the specific feature that places ores automatically. Each feature type has it's own specific syntax. (There's also `single_block_feature` that places a single block instead of an ore group, etc) +- `identifier` doesn't require a namespace in this scenario. The namespace is optional, and is not to be added in the filename. +- `count` is how big the ore "cluster" will be at maximum, or how many actual ore blocks will generate together. +- `places_block` takes the identifier of the block to be placed as the value. +- `may_replace` takes all the blocks that the feature can replace as arguments. If it generates over one of the blocks not included in here, the block will remain where it was without being replaced. + +## Feature Rules + +**Feature Rules** control where and how _features_ (and, in the future, _structures_) are placed. + +BP/feature_rules/overworld_underground_blocky_ore_feature.json + +```json +{ + "format_version": "1.13.0", + "minecraft:feature_rules": { + "description": { + "identifier": "overworld_underground_blocky_ore_feature", + "places_feature": "blocky_ore_feature" + }, + "conditions": { + "placement_pass": "underground_pass", + "minecraft:biome_filter": [ + { + "any_of": [ + { + "test": "has_biome_tag", + "operator": "==", + "value": "overworld" + }, + { + "test": "has_biome_tag", + "operator": "==", + "value": "overworld_generation" + } + ] + } + ] + }, + "distribution": { + "iterations": 100, + "coordinate_eval_order": "zyx", + "x": { + "distribution": "uniform", + "extent": [0, 16] + }, + "y": { + "distribution": "uniform", + "extent": [0, 16] + }, + "z": { + "distribution": "uniform", + "extent": [0, 16] + } + } + } +} +``` + +- `description` + - `identifier` needs no namespace, but the filename needs to match. + - `places_feature` takes the identifier of the feature that is controlled by this rule as the value. +- `conditions` + - `placement_pass` HOW the feature will be passed. + - `biome_filter` tests for biome tags where the feature will generate, exactly as a spawn rule. +- `distribution` + - `iterations` basically chance. I set mine to 100 to make it generate everywhere, but for a diamond_ore, this is set to 1. + - The next four components show in which directions the ore will be 'dragged' towards. + _Needs more clarification_ + +The easiest way to test wether your ores generated is /fill ~15 ~5 ~15 ~-15 ~-15 ~-15 air 0 replace stone using this command at a low y level. it'll keep everything BUT stone in the selected area, like this: + +![](/assets/images/guide/ore_gen_sans_stone.jpg) + +And yes, 100 as "iterations" is definitely waaay too much ;) + +It's a good idea to proceed checking out other feature and feature_rule vanilla files to learn further techniques. However, the ones you were just walked through are enough to create most of what needs to be generated. + +--- + +## Custom Structures + +As of MCBE v1.16.20, **Custom Generated structures are possible**. +A simple way to generate Structures is [this](https://machine-builder.itch.io/frg-v2) auto generator by MACHINE_BUILDER, mentioned earlier. It generates all three of the required files for your structure: `feature_rules/mystructure.feature_rule.json`, `feature_rules/mystructure.feature.json` and `structures/mystructure.mcstructure.` You can learn more about defining `.mcstructures` with Structure Blocks in Minecraft itself [here](/nbt/mcstructure). + +--- + +Now that you have your `.mcstructure`, time to write your `feature` and `feature rule`. The last is the same as with ores (see the beginning of this article). Let's continue to the **Feature**. + +- Remember that the namespace is not required and that the filename must match the identifier, excluding the namespace. So if you have a feature rule with the identifier `wiki:myfeaturerule` or simply `myfeaturerule`, the file name can be be `myfeaturerule.json` in both cases. + +Here's an code example from the [Features Documentation](https://bedrock.dev/r/Features#minecraft:structure_template_feature): + + + +```json +{ + "format_version": "1.13.0", + "minecraft:structure_template_feature": { + "description": { + "identifier": "wiki:hot_air_balloon_feature" + }, + "structure_name": "wiki:hot_air_balloon", + "adjustment_radius": 8, + "facing_direction": "random", + "constraints": { + "unburied": {}, + "block_intersection": { + "block_whitelist": [ + "minecraft:air" + ] + } + } + } +} +``` + +- `structure_name` is the structure's identifier, the one you saved via a Structure Block. + +That's pretty much it! Now you're able to generate your own custom Structures in the world. + +--- + +--- + +## Your progress so far + +**What you've done:** + + + +- [x] Created you very first biome. +- [x] Made your very first ore generate naturally. +- [x] Learned to use bridge. for vanilla files generation and referencing. +- [x] Learned about other Custom Generation methods. +- [x] Created custom Structures + +