From 5bf8f59daaf1757b6cb0cb42fe6fc009c00ca8ce Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sat, 25 Jul 2026 08:25:44 +0200 Subject: [PATCH 1/7] chore: remove unused addon template files and configurations --- templates/addon/.gitignore | 2 - templates/addon/.mcignore | 2 - templates/addon/.vscode/extensions.json | 13 - templates/addon/.vscode/launch.json | 16 - templates/addon/.vscode/settings.json | 41 - templates/addon/config.json | 48 - templates/addon/eslint.config.mjs | 397 ----- templates/addon/filters/.gitkeep | 3 - templates/addon/package.json | 31 - templates/addon/packs/BP/manifest.json | 60 - .../packs/BP/scripts/Actions/Uninstall.ts | 6 - .../addon/packs/BP/scripts/Actions/index.ts | 10 - .../packs/BP/scripts/Events/EntityDie.ts | 13 - .../addon/packs/BP/scripts/Events/index.ts | 7 - .../packs/BP/scripts/Models/EntityTypes.ts | 3 - .../addon/packs/BP/scripts/Models/index.ts | 10 - .../addon/packs/BP/scripts/UI/Example.ts | 14 - templates/addon/packs/BP/scripts/UI/index.ts | 7 - .../BP/scripts/Util/DynamicProperties.ts | 45 - .../addon/packs/BP/scripts/Util/Scoreboard.ts | 39 - .../addon/packs/BP/scripts/Util/index.ts | 9 - templates/addon/packs/BP/scripts/main.ts | 14 - templates/addon/packs/BP/texts/en_GB.lang | 2 - templates/addon/packs/BP/texts/en_US.lang | 2 - templates/addon/packs/BP/texts/languages.json | 4 - templates/addon/packs/RP/manifest.json | 48 - templates/addon/packs/RP/texts/en_GB.lang | 14 - templates/addon/packs/RP/texts/en_US.lang | 14 - templates/addon/packs/RP/texts/languages.json | 4 - templates/addon/packs/data/.gitkeep | 3 - templates/addon/tsconfig.json | 35 - templates/addon/yarn.lock | 1458 ----------------- 32 files changed, 2374 deletions(-) delete mode 100644 templates/addon/.gitignore delete mode 100644 templates/addon/.mcignore delete mode 100644 templates/addon/.vscode/extensions.json delete mode 100644 templates/addon/.vscode/launch.json delete mode 100644 templates/addon/.vscode/settings.json delete mode 100644 templates/addon/config.json delete mode 100644 templates/addon/eslint.config.mjs delete mode 100644 templates/addon/filters/.gitkeep delete mode 100644 templates/addon/package.json delete mode 100644 templates/addon/packs/BP/manifest.json delete mode 100644 templates/addon/packs/BP/scripts/Actions/Uninstall.ts delete mode 100644 templates/addon/packs/BP/scripts/Actions/index.ts delete mode 100644 templates/addon/packs/BP/scripts/Events/EntityDie.ts delete mode 100644 templates/addon/packs/BP/scripts/Events/index.ts delete mode 100644 templates/addon/packs/BP/scripts/Models/EntityTypes.ts delete mode 100644 templates/addon/packs/BP/scripts/Models/index.ts delete mode 100644 templates/addon/packs/BP/scripts/UI/Example.ts delete mode 100644 templates/addon/packs/BP/scripts/UI/index.ts delete mode 100644 templates/addon/packs/BP/scripts/Util/DynamicProperties.ts delete mode 100644 templates/addon/packs/BP/scripts/Util/Scoreboard.ts delete mode 100644 templates/addon/packs/BP/scripts/Util/index.ts delete mode 100644 templates/addon/packs/BP/scripts/main.ts delete mode 100644 templates/addon/packs/BP/texts/en_GB.lang delete mode 100644 templates/addon/packs/BP/texts/en_US.lang delete mode 100644 templates/addon/packs/BP/texts/languages.json delete mode 100644 templates/addon/packs/RP/manifest.json delete mode 100644 templates/addon/packs/RP/texts/en_GB.lang delete mode 100644 templates/addon/packs/RP/texts/en_US.lang delete mode 100644 templates/addon/packs/RP/texts/languages.json delete mode 100644 templates/addon/packs/data/.gitkeep delete mode 100644 templates/addon/tsconfig.json delete mode 100644 templates/addon/yarn.lock diff --git a/templates/addon/.gitignore b/templates/addon/.gitignore deleted file mode 100644 index 3f195ca9a..000000000 --- a/templates/addon/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/build -/.regolith \ No newline at end of file diff --git a/templates/addon/.mcignore b/templates/addon/.mcignore deleted file mode 100644 index 704c8aa46..000000000 --- a/templates/addon/.mcignore +++ /dev/null @@ -1,2 +0,0 @@ -/build -/.regolith diff --git a/templates/addon/.vscode/extensions.json b/templates/addon/.vscode/extensions.json deleted file mode 100644 index 25477bef4..000000000 --- a/templates/addon/.vscode/extensions.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "recommendations": [ - "aaron-bond.better-comments", - "blockceptionltd.blockceptionvscodeminecraftbedrockdevelopmentextension", - "dbaeumer.vscode-eslint", - "mojang-studios.minecraft-debugger", - "misodee.vscode-nbt", - "bedrockoss.regolith", - "jannisx11.snowstorm", - "netcorext.uuid-generator", - "christian-kohler.npm-intellisense" - ] -} \ No newline at end of file diff --git a/templates/addon/.vscode/launch.json b/templates/addon/.vscode/launch.json deleted file mode 100644 index 3fbbe8bd7..000000000 --- a/templates/addon/.vscode/launch.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "version": "0.3.0", - "configurations": [ - { - "type": "minecraft-js", - "request": "attach", - "sourceMapRoot": "${env:LOCALAPPDATA}/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/development_behavior_packs/ - - Bedrock Tweaks/scripts/", - "generatedSourceRoot": "${env:LOCALAPPDATA}/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/development_behavior_packs/ - - Bedrock Tweaks/scripts/", - "localRoot": "${workspaceFolder}/packs/BP/scripts/", - "name": "Debug with Minecraft", - "mode": "listen", - "port": 19144, - "targetModuleUuid": "" - } - ] -} \ No newline at end of file diff --git a/templates/addon/.vscode/settings.json b/templates/addon/.vscode/settings.json deleted file mode 100644 index 03f36e123..000000000 --- a/templates/addon/.vscode/settings.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "editor.formatOnSave": false, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - }, - "editor.detectIndentation": false, - "editor.insertSpaces": false, - "editor.tabSize": 2, - "[typescript]": { - "editor.defaultFormatter": "dbaeumer.vscode-eslint", - "editor.insertSpaces": false, - "editor.tabSize": 4 - }, - "[javascript]": { - "editor.defaultFormatter": "dbaeumer.vscode-eslint", - "editor.insertSpaces": false, - "editor.tabSize": 4 - }, - "[json]": { - "editor.defaultFormatter": "vscode.json-language-features", - "editor.insertSpaces": false, - "editor.tabSize": 4 - }, - "[jsonc]": { - "editor.defaultFormatter": "vscode.json-language-features", - "editor.insertSpaces": false, - "editor.tabSize": 4 - }, - "typescript.tsdk": "node_modules/typescript/lib", - "typescript.enablePromptUseWorkspaceTsdk": true, - "eslint.validate": [ - "typescript", - "json", - "jsonc" - ], - "files.associations": { - "*.json": "jsonc" - }, - "eslint.enable": true, - "eslint.format.enable": true -} \ No newline at end of file diff --git a/templates/addon/config.json b/templates/addon/config.json deleted file mode 100644 index da80d1913..000000000 --- a/templates/addon/config.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/Bedrock-OSS/regolith-schemas/main/config/v1.4.json", - "name": "bedrock-tweaks/", - "author": "", - "packs": { - "behaviorPack": "./packs/BP", - "resourcePack": "./packs/RP" - }, - "regolith": { - "dataPath": "./packs/data", - "formatVersion": "1.4.0", - "filterDefinitions": { - "bundler": { - "url": "github.com/bedrock-core/regolith-filters", - "version": "1.0.1" - } - }, - "profiles": { - "build": { - "export": { - "build": "standard", - "readOnly": false, - "target": "local" - }, - "filters": [ - { - "filter": "bundler" - } - ] - }, - "default": { - "export": { - "build": "standard", - "readOnly": false, - "target": "development" - }, - "filters": [ - { - "filter": "bundler", - "settings": { - "debug": true - } - } - ] - } - } - } -} \ No newline at end of file diff --git a/templates/addon/eslint.config.mjs b/templates/addon/eslint.config.mjs deleted file mode 100644 index c772a561f..000000000 --- a/templates/addon/eslint.config.mjs +++ /dev/null @@ -1,397 +0,0 @@ -import minecraftLinting from "eslint-plugin-minecraft-linting"; -import stylistic from "@stylistic/eslint-plugin"; -import { defineConfig } from "eslint/config"; -import tseslint from "typescript-eslint"; -import json from "@eslint/json"; -import { fileURLToPath } from "url"; -import { dirname } from "path"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); - -export default defineConfig([ - { - ignores: [ - ".*/**", // Any directory starting with dot (.yarn, .vscode, .regolith, etc.) - ".*", // Any file starting with dot - "node_modules/**", - "**/*.*js", // Generated JS files - "filters/**", // The filters directory - "build/**", // Build output - "*.json", // Root level JSON files (config.json, package.json, tsconfig.json) - "*.md", // Root level markdown files - "*.mjs", // Root level mjs files (like this config) - "*.js", // Root level js files - ], - }, - - { - plugins: { - json, - }, - }, - - // lint JSON files - { - files: ["**/*.json"], - language: "json/jsonc", - rules: { - "json/no-duplicate-keys": "error", - "json/no-empty-keys": "off", - "json/no-unnormalized-keys": "error", - "json/no-unsafe-values": "error", - "json/sort-keys": "off", - "json/top-level-interop": "off", - } - }, - - { - files: ["packs/BP/scripts/**/*.ts"], - plugins: { - "@stylistic": stylistic, - "@typescript-eslint": tseslint.plugin, - "@minecraft": minecraftLinting - }, - - languageOptions: { - parser: tseslint.parser, - ecmaVersion: "latest", - sourceType: "module", - parserOptions: { - project: ["tsconfig.json"], - tsconfigRootDir: __dirname, - }, - }, - - rules: { - "no-unused-expressions": "off", - "@typescript-eslint/no-unused-expressions": "off", - "@typescript-eslint/explicit-member-accessibility": ["error", - { - accessibility: "no-public", - } - ], - - "@typescript-eslint/no-restricted-types": [ - "error", - { - "types": { - "Object": { - "message": "Avoid using the `Object` type. Did you mean `object`?" - }, - "Function": { - "message": "Avoid using the `Function` type. Prefer a specific function type, like `() => void`." - }, - "Boolean": { - "message": "Avoid using the `Boolean` type. Did you mean `boolean`?" - }, - "Number": { - "message": "Avoid using the `Number` type. Did you mean `number`?" - }, - "String": { - "message": "Avoid using the `String` type. Did you mean `string`?" - }, - "Symbol": { - "message": "Avoid using the `Symbol` type. Did you mean `symbol`?" - } - } - } - ], - "@typescript-eslint/no-wrapper-object-types": "error", - "@typescript-eslint/no-unsafe-function-type": "error", - "@typescript-eslint/no-empty-object-type": ["error", - { - allowInterfaces: 'always' - } - ], - "@typescript-eslint/ban-ts-comment": ["error", - { - 'ts-expect-error': 'allow-with-description' - } - ], - - "@typescript-eslint/consistent-type-assertions": "error", - "@typescript-eslint/dot-notation": "error", - - "@typescript-eslint/member-ordering": ["error", - { - default: [ - "private-field", - "protected-field", - "public-field", - "constructor", - "public-method", - "protected-method", - "private-method", - ], - } - ], - - "@typescript-eslint/naming-convention": ["error", - { - selector: "default", - format: ["camelCase"], - }, - { - selector: "default", - modifiers: ["unused"], - - filter: { - regex: "^(_|_.*_?)$", - match: true, - }, - - format: null, - }, - { - selector: "variable", - format: ["camelCase"], - }, - { - selector: ["parameter"], - format: ["camelCase", "snake_case"], - }, - { - selector: "variable", - modifiers: ["const"], - format: ["camelCase", "UPPER_CASE", "PascalCase"], - }, - { - selector: ["enum", "enumMember", "function"], - format: ["camelCase", "UPPER_CASE", "PascalCase"], - }, - { - selector: ["property", "parameterProperty", "accessor"], - modifiers: ["private"], - format: ["camelCase", "snake_case"], - leadingUnderscore: "require", - }, - { - selector: ["property", "parameterProperty", "accessor"], - modifiers: ["private", "readonly"], - format: ["UPPER_CASE", "camelCase"], - leadingUnderscore: "allow", - }, - { - selector: ["property"], - modifiers: ["readonly"], - format: ["camelCase", "UPPER_CASE"], - }, - { - selector: ["objectLiteralProperty", "typeProperty"], - format: ["camelCase", "snake_case", "UPPER_CASE"], - }, - { - selector: "typeLike", - format: ["PascalCase"], - } - ], - - "@typescript-eslint/explicit-function-return-type": ["error", - { - allowExpressions: true, - } - ], - - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "@typescript-eslint/default-param-last": "warn", - "@typescript-eslint/no-explicit-any": "warn", - "@typescript-eslint/no-unnecessary-boolean-literal-compare": "warn", - "@typescript-eslint/prefer-enum-initializers": "warn", - - "@typescript-eslint/unbound-method": ["error", - { - ignoreStatic: true, - } - ], - - eqeqeq: ["error", "always", - { - null: "ignore", - } - ], - - "object-shorthand": "error", - - "@typescript-eslint/no-unused-vars": ["error", - { - argsIgnorePattern: "^(_|_.*_?)$", - } - ], - - "arrow-body-style": "warn", - curly: ["warn", "multi-line", "consistent"], - "@typescript-eslint/array-type": "warn", - "@typescript-eslint/prefer-optional-chain": "warn", - "@typescript-eslint/prefer-reduce-type-parameter": "warn", - "@stylistic/array-bracket-newline": "off", - "@stylistic/array-bracket-spacing": ["warn"], - "@stylistic/array-element-newline": "off", - "@stylistic/arrow-parens": ["warn", "as-needed"], - "@stylistic/arrow-spacing": ["warn"], - "@stylistic/block-spacing": ["warn", "always"], - - "@stylistic/brace-style": ["warn", "1tbs", - { - allowSingleLine: true, - } - ], - - "@stylistic/comma-dangle": ["warn", - { - arrays: "always-multiline", - objects: "always-multiline", - imports: "never", - exports: "never", - functions: "always-multiline", - enums: "never", - generics: "never", - tuples: "always-multiline", - } - ], - - "@stylistic/comma-spacing": ["warn", - { - before: false, - after: true, - } - ], - - "@stylistic/computed-property-spacing": ["warn"], - "@stylistic/dot-location": ["warn", "property"], - "@stylistic/eol-last": ["warn"], - "@stylistic/function-call-argument-newline": ["warn", "consistent"], - "@stylistic/function-paren-newline": ["warn", "consistent"], - "@stylistic/generator-star-spacing": "off", - "@stylistic/implicit-arrow-linebreak": ["warn", "beside"], - "@stylistic/indent": ["warn", "tab"], - "@stylistic/jsx-quotes": "off", - - "@stylistic/key-spacing": ["warn", - { - beforeColon: false, - afterColon: true, - mode: "strict", - } - ], - - "@stylistic/keyword-spacing": ["warn"], - "@stylistic/linebreak-style": ["warn", "windows"], - - "@stylistic/lines-around-comment": ["warn", - { - afterBlockComment: false, - beforeLineComment: false, - afterLineComment: false, - allowBlockStart: true, - allowClassStart: true, - allowObjectStart: true, - allowArrayStart: true, - } - ], - - "@stylistic/lines-between-class-members": ["warn", "always", - { - exceptAfterSingleLine: true, - exceptAfterOverload: false, - } - ], - - "@stylistic/max-len": "off", - "@stylistic/max-statements-per-line": "off", - "@stylistic/multiline-ternary": "off", - "@stylistic/new-parens": ["warn"], - "@stylistic/newline-per-chained-call": "off", - "@stylistic/no-confusing-arrow": "off", - "@stylistic/no-extra-parens": ["warn"], - "@stylistic/no-extra-semi": ["warn"], - "@stylistic/no-floating-decimal": ["warn"], - "@stylistic/no-mixed-operators": "off", - "@stylistic/no-mixed-spaces-and-tabs": ["warn"], - "@stylistic/no-multi-spaces": ["warn"], - - "@stylistic/no-multiple-empty-lines": ["warn", - { - max: 1, - } - ], - - "@stylistic/no-tabs": ["off"], - "@stylistic/no-trailing-spaces": ["warn"], - "@stylistic/no-whitespace-before-property": ["warn"], - "@stylistic/nonblock-statement-body-position": "off", - - "@stylistic/object-curly-newline": ["warn", - { - multiline: true, - } - ], - - "@stylistic/object-curly-spacing": ["warn", "always"], - "@stylistic/object-property-newline": "off", - "@stylistic/one-var-declaration-per-line": "off", - "@stylistic/operator-linebreak": "off", - "@stylistic/padded-blocks": ["warn", "never"], - - "@stylistic/padding-line-between-statements": ["warn", - { - blankLine: "always", - prev: "*", - next: "return", - } - ], - - "@stylistic/quote-props": ["warn", "as-needed"], - - "@stylistic/quotes": ["warn", "single", - { - avoidEscape: true, - allowTemplateLiterals: 'always', - } - ], - - "@stylistic/rest-spread-spacing": ["warn", "never"], - "@stylistic/semi": ["warn", "always"], - "@stylistic/semi-spacing": ["warn"], - "@stylistic/semi-style": ["warn", "last"], - "@stylistic/space-before-blocks": ["warn"], - "@stylistic/space-before-function-paren": ["warn", { - "anonymous": "never", - "named": "never", - "asyncArrow": "never", - "catch": "always" - }], - "@stylistic/space-in-parens": ["warn", "never"], - "@stylistic/space-infix-ops": "warn", - "@stylistic/space-unary-ops": "off", - "@stylistic/spaced-comment": ["warn", "always"], - "@stylistic/switch-colon-spacing": ["warn"], - "@stylistic/template-curly-spacing": ["warn"], - "@stylistic/template-tag-spacing": "off", - "@stylistic/wrap-iife": "off", - "@stylistic/wrap-regex": "off", - "@stylistic/yield-star-spacing": "off", - "@stylistic/member-delimiter-style": ["warn"], - "@stylistic/type-annotation-spacing": "warn", - "@stylistic/jsx-child-element-spacing": "off", - "@stylistic/jsx-closing-bracket-location": "off", - "@stylistic/jsx-closing-tag-location": "off", - "@stylistic/jsx-curly-brace-presence": "off", - "@stylistic/jsx-curly-newline": "off", - "@stylistic/jsx-curly-spacing": "off", - "@stylistic/jsx-equals-spacing": "off", - "@stylistic/jsx-first-prop-new-line": "off", - "@stylistic/jsx-indent": "off", - "@stylistic/jsx-indent-props": "off", - "@stylistic/jsx-max-props-per-line": "off", - "@stylistic/jsx-newline": "off", - "@stylistic/jsx-one-expression-per-line": "off", - "@stylistic/jsx-props-no-multi-spaces": "off", - "@stylistic/jsx-self-closing-comp": "off", - "@stylistic/jsx-sort-props": "off", - "@stylistic/jsx-tag-spacing": "off", - "@stylistic/jsx-wrap-multilines": "off", - "@minecraft/avoid-unnecessary-command": "error", - }, - } -]); diff --git a/templates/addon/filters/.gitkeep b/templates/addon/filters/.gitkeep deleted file mode 100644 index 9d375552f..000000000 --- a/templates/addon/filters/.gitkeep +++ /dev/null @@ -1,3 +0,0 @@ -# Info - -Add any custom filters to automate part of the regolith build diff --git a/templates/addon/package.json b/templates/addon/package.json deleted file mode 100644 index eee8de63b..000000000 --- a/templates/addon/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "@bedrock-tweaks/", - "version": "", - "description": "", - "private": true, - "scripts": { - "regolith-install": "regolith install-all", - "build": "regolith run build", - "dev": "regolith watch", - "lint": "npx eslint ." - }, - "dependencies": { - "@minecraft/common": "^1.2.0", - "@minecraft/math": "^2.4.0", - "@minecraft/server": "^2.6.0", - "@minecraft/server-ui": "^2.0.0", - "@minecraft/vanilla-data": "^1.26.13", - "@stylistic/eslint-config": "^1.1.0" - }, - "devDependencies": { - "@eslint/js": "^9.38.0", - "@eslint/json": "^0.13.2", - "@stylistic/eslint-plugin": "^5.4.0", - "@typescript-eslint/eslint-plugin": "^8.46.1", - "@typescript-eslint/parser": "^8.46.1", - "eslint": "^9.38.0", - "eslint-plugin-minecraft-linting": "^2.0.10", - "typescript": "^5.9.3", - "typescript-eslint": "^8.46.1" - } -} \ No newline at end of file diff --git a/templates/addon/packs/BP/manifest.json b/templates/addon/packs/BP/manifest.json deleted file mode 100644 index fd6e81ce4..000000000 --- a/templates/addon/packs/BP/manifest.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "format_version": 2, - "header": { - "name": "pack.name", - "description": "pack.description", - "uuid": "", - "pack_scope": "world", - "version": [ - 1, - 0, - 0 - ], - // Update to latest minecraft release - "min_engine_version": [ - 1, - 26, - 1 - ] - }, - "modules": [ - { - "type": "data", - "uuid": "", - "version": [ - 1, - 0, - 0 - ] - }, - { - "type": "script", - "language": "javascript", - "uuid": "", - "entry": "scripts/main.js", - "version": [ - 1, - 0, - 0 - ] - } - ], - "dependencies": [ - { - "uuid": "", - "version": [ - 1, - 0, - 0 - ] - } - ], - "metadata": { - "product_type": "addon", - "authors": [ - "Vanilla Tweaks", - "Bedrock Tweaks", - "" - ] - } -} \ No newline at end of file diff --git a/templates/addon/packs/BP/scripts/Actions/Uninstall.ts b/templates/addon/packs/BP/scripts/Actions/Uninstall.ts deleted file mode 100644 index a02638fce..000000000 --- a/templates/addon/packs/BP/scripts/Actions/Uninstall.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { world } from '@minecraft/server'; - -export const uninstall = (): void => { - world.clearDynamicProperties(); - world.sendMessage({ translate: 'bt.example.misc.uninstall', with: ['\n'] }); -}; diff --git a/templates/addon/packs/BP/scripts/Actions/index.ts b/templates/addon/packs/BP/scripts/Actions/index.ts deleted file mode 100644 index 53c0d2c1d..000000000 --- a/templates/addon/packs/BP/scripts/Actions/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Actions Module - * - * This module exports the functions which interact between the game and the addon - * - * For more examples, refer to - * @see addons/files/gameplay_changes/graves/packs/BP/scripts/Models - */ -export { uninstall } from './Uninstall'; - diff --git a/templates/addon/packs/BP/scripts/Events/EntityDie.ts b/templates/addon/packs/BP/scripts/Events/EntityDie.ts deleted file mode 100644 index 223b4767b..000000000 --- a/templates/addon/packs/BP/scripts/Events/EntityDie.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { EntityDieAfterEvent, world } from '@minecraft/server'; -import { MinecraftEntityTypes } from '@minecraft/vanilla-data'; - -/** - * We check for conditions in the Event Handlers and run the Actions related to them if the conditions are met - * Prefer casting here after the type was checked rather than in Actions - */ -world.afterEvents.entityDie.subscribe(({ deadEntity }: EntityDieAfterEvent): void => { - if (deadEntity.matches({ type: MinecraftEntityTypes.Player })) { - // Action to run when a player dies - // exampleAction(deadEntity as Player); - } -}); diff --git a/templates/addon/packs/BP/scripts/Events/index.ts b/templates/addon/packs/BP/scripts/Events/index.ts deleted file mode 100644 index 55c14fcfb..000000000 --- a/templates/addon/packs/BP/scripts/Events/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Events Module - * - * This module imports and registers all event handlers. - * Events that have both "before" and "after" versions are organized within the same file. - */ -import './EntityDie'; diff --git a/templates/addon/packs/BP/scripts/Models/EntityTypes.ts b/templates/addon/packs/BP/scripts/Models/EntityTypes.ts deleted file mode 100644 index c48cafe10..000000000 --- a/templates/addon/packs/BP/scripts/Models/EntityTypes.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum ExampleEntityTypes { - Example = 'bt:ex.example' -} diff --git a/templates/addon/packs/BP/scripts/Models/index.ts b/templates/addon/packs/BP/scripts/Models/index.ts deleted file mode 100644 index efa32a781..000000000 --- a/templates/addon/packs/BP/scripts/Models/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Models Module - * - * This module exports the definitions of the types, interfaces and enums of the addon - * It centralizes all model-related exports for easier import and management across different parts of the application. - * - * For more examples, refer to - * @see addons/files/gameplay_changes/graves/packs/BP/scripts/Models - */ -export { ExampleEntityTypes } from './EntityTypes'; diff --git a/templates/addon/packs/BP/scripts/UI/Example.ts b/templates/addon/packs/BP/scripts/UI/Example.ts deleted file mode 100644 index 2857b6828..000000000 --- a/templates/addon/packs/BP/scripts/UI/Example.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Player } from '@minecraft/server'; -import { ActionFormData, ActionFormResponse } from '@minecraft/server-ui'; - -export const openExampleInterface = (player: Player): void => { - const form: ActionFormData = new ActionFormData() - .title({ translate: 'bt.example.config.title' }) - .button({ translate: 'bt.example.config.button' }); - - form.show(player).then((response: ActionFormResponse): void => { - if (response.selection !== undefined && response.selection === 0) { - // Action to run on button press - } - }); -}; diff --git a/templates/addon/packs/BP/scripts/UI/index.ts b/templates/addon/packs/BP/scripts/UI/index.ts deleted file mode 100644 index 5e26d2a21..000000000 --- a/templates/addon/packs/BP/scripts/UI/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * UI Module - * - * This module contains the @minecraft/server-ui forms used in the addon - */ - -export { openExampleInterface } from './Example'; diff --git a/templates/addon/packs/BP/scripts/Util/DynamicProperties.ts b/templates/addon/packs/BP/scripts/Util/DynamicProperties.ts deleted file mode 100644 index 3f734dac2..000000000 --- a/templates/addon/packs/BP/scripts/Util/DynamicProperties.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Entity, Vector3, World } from '@minecraft/server'; - -type PropertiesTypes = boolean | number | string | Vector3 | undefined; - -/** - * Converts the properties of the world or an entity from the enumType to a JS Object of type T - * Enum keys and object properties should match for proper conversion. - * - * @template T - The type of the resulting object. - * @param {World | Entity} from - The world or entity from which the properties are retrieved. - * @param {{ [key: string]: string }} enumType - An object mapping property keys to dynamic property identifiers. - * - * @returns {T} - An object containing the properties extracted based on the enumType. - */ -export function getProperties(from: World | Entity, enumType: { [key: string]: string }): T { - const propertiesObject: Record = {}; - - Object.entries(enumType).forEach(([key, value]: [string, string]): void => { - propertiesObject[key] = from.getDynamicProperty(value); - }); - - return propertiesObject as T; -} - -/** - * Converts a JavaScript object into dynamic properties based on the `enumType` - * and saves them in the provided world or entity. - * Enum keys and object properties should match for proper conversion. - * - * @param {World | Entity} to - The world or entity where the properties will be set. - * @param {{ [key: string]: string }} enumType - An object mapping property keys to dynamic property identifiers. - * @param {object} propertyObject - A JavaScript object containing the properties to be set. - */ -export function setProperties< - T extends Record, - K extends Record ->(to: World | Entity, enumType: K, propertyObject: T): void { - Object.entries(propertyObject).forEach(([key, value]: [string, PropertiesTypes]): void => { - const identifier: string = enumType[key]; - - if (identifier) { - to.setDynamicProperty(identifier, value); - } - }); -} diff --git a/templates/addon/packs/BP/scripts/Util/Scoreboard.ts b/templates/addon/packs/BP/scripts/Util/Scoreboard.ts deleted file mode 100644 index 10da408e4..000000000 --- a/templates/addon/packs/BP/scripts/Util/Scoreboard.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ScoreboardIdentity, ScoreboardObjective, ScoreboardScoreInfo, world } from '@minecraft/server'; - -/** - * Converts the in-game Scoreboard Objective participants to a JS Object - * - * @template T - The type of the resulting object. - * @param {string} objectiveName - The name of the scoreboard objective to retrieve. - * - * @returns {T} - An object where the keys are participant display names (Player, Entity, or FakePlayer) and the values are their respective scores. - */ -export function getObjective(objectiveName: string): T { - // Any object with keys as string and values as number - const scoreboardObject: Record = {}; - const scoreboardObjective: ScoreboardObjective | undefined = world.scoreboard.getObjective(objectiveName); - - scoreboardObjective?.getScores().forEach((score: ScoreboardScoreInfo): void => { - scoreboardObject[score.participant.displayName] = score.score; - }); - - return scoreboardObject as T; -} - -/** - * Converts a JS Object with key, value pairs of to an in-game Scoreboard Objective participants - * - * @param {string} objectiveName - The name of the scoreboard objective to update. - * @param {object} scoreboardObject - An object where the keys are participant display names (Player, Entity, or FakePlayer) and the values are their respective scores. - */ -export function setObjective(objectiveName: string, scoreboardObject: object): void { - const scoreboardObjective: ScoreboardObjective | undefined = world.scoreboard.getObjective(objectiveName); - const participants: ScoreboardIdentity[] | undefined = scoreboardObjective?.getParticipants(); - - Object.entries(scoreboardObject).forEach(([key, value]: [string, number]): void => { - const player: ScoreboardIdentity | undefined = participants?.find( - (participant: ScoreboardIdentity): boolean => participant.displayName === key, - ); - player && scoreboardObjective?.setScore(player, value); - }); -} diff --git a/templates/addon/packs/BP/scripts/Util/index.ts b/templates/addon/packs/BP/scripts/Util/index.ts deleted file mode 100644 index 4224b8232..000000000 --- a/templates/addon/packs/BP/scripts/Util/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Util Module - * - * This module provides utility functions for the addons - * If you think something might be of use could discuss in the Discord to add it to the template - */ - -export { getObjective, setObjective } from './Scoreboard'; -export { getProperties, setProperties } from './DynamicProperties'; diff --git a/templates/addon/packs/BP/scripts/main.ts b/templates/addon/packs/BP/scripts/main.ts deleted file mode 100644 index d901975f5..000000000 --- a/templates/addon/packs/BP/scripts/main.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { system, TicksPerSecond } from '@minecraft/server'; -import './Events'; - -/** - * Entry point of the addon - * - * We do 2 things here - * Import the Events module - * Execute any system functions which need to be constantly running - */ - -system.runInterval((): void => { - // Action to run on an interval -}, TicksPerSecond); diff --git a/templates/addon/packs/BP/texts/en_GB.lang b/templates/addon/packs/BP/texts/en_GB.lang deleted file mode 100644 index b3a287682..000000000 --- a/templates/addon/packs/BP/texts/en_GB.lang +++ /dev/null @@ -1,2 +0,0 @@ -pack.name= - - Bedrock Tweaks -pack.description= \ No newline at end of file diff --git a/templates/addon/packs/BP/texts/en_US.lang b/templates/addon/packs/BP/texts/en_US.lang deleted file mode 100644 index b3a287682..000000000 --- a/templates/addon/packs/BP/texts/en_US.lang +++ /dev/null @@ -1,2 +0,0 @@ -pack.name= - - Bedrock Tweaks -pack.description= \ No newline at end of file diff --git a/templates/addon/packs/BP/texts/languages.json b/templates/addon/packs/BP/texts/languages.json deleted file mode 100644 index 5f61e6961..000000000 --- a/templates/addon/packs/BP/texts/languages.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - "en_GB", - "en_US" -] \ No newline at end of file diff --git a/templates/addon/packs/RP/manifest.json b/templates/addon/packs/RP/manifest.json deleted file mode 100644 index eff630138..000000000 --- a/templates/addon/packs/RP/manifest.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "format_version": 2, - "header": { - "name": "pack.name", - "description": "pack.description", - "uuid": "", - "pack_scope": "world", - "version": [ - 1, - 0, - 0 - ], - // Update to latest minecraft release - "min_engine_version": [ - 1, - 26, - 1 - ] - }, - "modules": [ - { - "type": "resources", - "uuid": "", - "version": [ - 1, - 0, - 0 - ] - } - ], - "dependencies": [ - { - "uuid": "", - "version": [ - 1, - 0, - 0 - ] - } - ], - "metadata": { - "authors": [ - "Vanilla Tweaks", - "Bedrock Tweaks", - "" - ] - } -} \ No newline at end of file diff --git a/templates/addon/packs/RP/texts/en_GB.lang b/templates/addon/packs/RP/texts/en_GB.lang deleted file mode 100644 index 4b401483a..000000000 --- a/templates/addon/packs/RP/texts/en_GB.lang +++ /dev/null @@ -1,14 +0,0 @@ -## In here, we add all the texts that are send to the chat, use in a UI like ModalFormData, etc -## The main idea of adding texts here is to keep them all organized and make them easily translatable to other languages - -## The format of all the keys with their text is as follows -## bt.addon_name.category.action=Text -## addon_name - The name of the addon -## category - The category describes all the related actions associated with it, like "settings" -## action - The action is the specific operation performed related to the category - -## Replace the word "example" with your addon name, using an underscore for spaces if needed, like "anti_creeper_grief" -## Replace the word "Example" with your addon name, like "Anti Creeper Grief" -pack.name= - - Bedrock Tweaks -pack.description= -bt.example.misc.uninstall=§eUninstalled Correctly§r%1Remove the Example pack from Behaviour Packs to complete the uninstall. \ No newline at end of file diff --git a/templates/addon/packs/RP/texts/en_US.lang b/templates/addon/packs/RP/texts/en_US.lang deleted file mode 100644 index 152f8aa7c..000000000 --- a/templates/addon/packs/RP/texts/en_US.lang +++ /dev/null @@ -1,14 +0,0 @@ -## In here, we add all the texts that are send to the chat, use in a UI like ModalFormData, etc -## The main idea of adding texts here is to keep them all organized and make them easily translatable to other languages - -## The format of all the keys with their text is as follows -## bt.addon_name.category.action=Text -## addon_name - The name of the addon -## category - The category describes all the related actions associated with it, like "settings" -## action - The action is the specific operation performed related to the category - -## Replace the word "example" with your addon name, using an underscore for spaces if needed, like "anti_creeper_grief" -## Replace the word "Example" with your addon name, like "Anti Creeper Grief" -pack.name= - - Bedrock Tweaks -pack.description= -bt.example.misc.uninstall=§eUninstalled Correctly§r%1Remove the Example pack from Behavior Packs to complete the uninstall. \ No newline at end of file diff --git a/templates/addon/packs/RP/texts/languages.json b/templates/addon/packs/RP/texts/languages.json deleted file mode 100644 index 5f61e6961..000000000 --- a/templates/addon/packs/RP/texts/languages.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - "en_GB", - "en_US" -] \ No newline at end of file diff --git a/templates/addon/packs/data/.gitkeep b/templates/addon/packs/data/.gitkeep deleted file mode 100644 index 49ae7b096..000000000 --- a/templates/addon/packs/data/.gitkeep +++ /dev/null @@ -1,3 +0,0 @@ -# Info - -Custom data folder used by some filters, regolith requires the existence of this directory. diff --git a/templates/addon/tsconfig.json b/templates/addon/tsconfig.json deleted file mode 100644 index 381cd5c03..000000000 --- a/templates/addon/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2023", - "module": "esnext", - "declaration": true, - "declarationMap": false, - "sourceMap": true, - "inlineSources": true, - "rootDir": "packs/BP/scripts", - "stripInternal": true, - "strict": true, - "moduleResolution": "bundler", - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "skipLibCheck": true, - "allowSyntheticDefaultImports": true, - "noImplicitAny": true, - "removeComments": true, - "preserveConstEnums": true, - "noImplicitReturns": true, - "allowJs": false, - "resolveJsonModule": true - }, - "files": [ - "packs/BP/scripts/main.ts" - ], - "include": [ - "packs/BP/scripts/**/*" - ], - "exclude": [ - "node_modules", - "**/__tests__/*", - "eslint.config.mjs" - ] -} \ No newline at end of file diff --git a/templates/addon/yarn.lock b/templates/addon/yarn.lock deleted file mode 100644 index f326349f1..000000000 --- a/templates/addon/yarn.lock +++ /dev/null @@ -1,1458 +0,0 @@ -# This file is generated by running "yarn install" inside your project. -# Manual changes might be lost - proceed with caution! - -__metadata: - version: 8 - cacheKey: 10c0 - -"@bedrock-tweaks/@workspace:.": - version: 0.0.0-use.local - resolution: "@bedrock-tweaks/@workspace:." - dependencies: - "@eslint/js": "npm:^9.38.0" - "@eslint/json": "npm:^0.13.2" - "@minecraft/common": "npm:1.2.0" - "@minecraft/math": "npm:2.2.11" - "@minecraft/server": "npm:2.2.0" - "@minecraft/server-ui": "npm:^2.0.0" - "@minecraft/vanilla-data": "npm:1.21.114" - "@stylistic/eslint-config": "npm:^1.1.0" - "@stylistic/eslint-plugin": "npm:^5.4.0" - "@typescript-eslint/eslint-plugin": "npm:^8.46.1" - "@typescript-eslint/parser": "npm:^8.46.1" - eslint: "npm:^9.38.0" - eslint-plugin-minecraft-linting: "npm:^2.0.10" - typescript: "npm:^5.9.3" - typescript-eslint: "npm:^8.46.1" - languageName: unknown - linkType: soft - -"@eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.7.0, @eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.0": - version: 4.9.0 - resolution: "@eslint-community/eslint-utils@npm:4.9.0" - dependencies: - eslint-visitor-keys: "npm:^3.4.3" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10c0/8881e22d519326e7dba85ea915ac7a143367c805e6ba1374c987aa2fbdd09195cc51183d2da72c0e2ff388f84363e1b220fd0d19bef10c272c63455162176817 - languageName: node - linkType: hard - -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1": - version: 4.12.1 - resolution: "@eslint-community/regexpp@npm:4.12.1" - checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 - languageName: node - linkType: hard - -"@eslint/config-array@npm:^0.21.1": - version: 0.21.1 - resolution: "@eslint/config-array@npm:0.21.1" - dependencies: - "@eslint/object-schema": "npm:^2.1.7" - debug: "npm:^4.3.1" - minimatch: "npm:^3.1.2" - checksum: 10c0/2f657d4edd6ddcb920579b72e7a5b127865d4c3fb4dda24f11d5c4f445a93ca481aebdbd6bf3291c536f5d034458dbcbb298ee3b698bc6c9dd02900fe87eec3c - languageName: node - linkType: hard - -"@eslint/config-helpers@npm:^0.4.1": - version: 0.4.1 - resolution: "@eslint/config-helpers@npm:0.4.1" - dependencies: - "@eslint/core": "npm:^0.16.0" - checksum: 10c0/bb7dd534019a975320ac0f8e0699b37433cee9a3731354c1ee941648e6651032386e7848792060fb53a0fd603ea6cf7a101ed3bd5b82ee2f641598986d1e080a - languageName: node - linkType: hard - -"@eslint/core@npm:^0.15.2": - version: 0.15.2 - resolution: "@eslint/core@npm:0.15.2" - dependencies: - "@types/json-schema": "npm:^7.0.15" - checksum: 10c0/c17a6dc4f5a6006ecb60165cc38bcd21fefb4a10c7a2578a0cfe5813bbd442531a87ed741da5adab5eb678e8e693fda2e2b14555b035355537e32bcec367ea17 - languageName: node - linkType: hard - -"@eslint/core@npm:^0.16.0": - version: 0.16.0 - resolution: "@eslint/core@npm:0.16.0" - dependencies: - "@types/json-schema": "npm:^7.0.15" - checksum: 10c0/f27496a244ccfdca3e0fbc3331f9da3f603bdf1aa431af0045a3205826789a54493bc619ad6311a9090eaf7bc25798ff4e265dea1eccd2df9ce3b454f7e7da27 - languageName: node - linkType: hard - -"@eslint/eslintrc@npm:^3.3.1": - version: 3.3.1 - resolution: "@eslint/eslintrc@npm:3.3.1" - dependencies: - ajv: "npm:^6.12.4" - debug: "npm:^4.3.2" - espree: "npm:^10.0.1" - globals: "npm:^14.0.0" - ignore: "npm:^5.2.0" - import-fresh: "npm:^3.2.1" - js-yaml: "npm:^4.1.0" - minimatch: "npm:^3.1.2" - strip-json-comments: "npm:^3.1.1" - checksum: 10c0/b0e63f3bc5cce4555f791a4e487bf999173fcf27c65e1ab6e7d63634d8a43b33c3693e79f192cbff486d7df1be8ebb2bd2edc6e70ddd486cbfa84a359a3e3b41 - languageName: node - linkType: hard - -"@eslint/js@npm:9.38.0, @eslint/js@npm:^9.38.0": - version: 9.38.0 - resolution: "@eslint/js@npm:9.38.0" - checksum: 10c0/b4a0d561ab93f0b1bc6a3f5e3f83764c9cccade59f2c54f1d718c1dcc71ac4d1be97bef7300cca641932d72e7555c79a7bf07e4e4ce1d0a1ddccc84d6440d2a6 - languageName: node - linkType: hard - -"@eslint/json@npm:^0.13.2": - version: 0.13.2 - resolution: "@eslint/json@npm:0.13.2" - dependencies: - "@eslint/core": "npm:^0.15.2" - "@eslint/plugin-kit": "npm:^0.3.5" - "@humanwhocodes/momoa": "npm:^3.3.9" - natural-compare: "npm:^1.4.0" - checksum: 10c0/1e024e33687a2cb26261856f0c5d459d06100b2e09718d6b1e8b63f6595e879fea6a7944f97abd07309b937773fc75c7dc4d61f4fc070422a0c8740c40334774 - languageName: node - linkType: hard - -"@eslint/object-schema@npm:^2.1.7": - version: 2.1.7 - resolution: "@eslint/object-schema@npm:2.1.7" - checksum: 10c0/936b6e499853d1335803f556d526c86f5fe2259ed241bc665000e1d6353828edd913feed43120d150adb75570cae162cf000b5b0dfc9596726761c36b82f4e87 - languageName: node - linkType: hard - -"@eslint/plugin-kit@npm:^0.3.5": - version: 0.3.5 - resolution: "@eslint/plugin-kit@npm:0.3.5" - dependencies: - "@eslint/core": "npm:^0.15.2" - levn: "npm:^0.4.1" - checksum: 10c0/c178c1b58c574200c0fd125af3e4bc775daba7ce434ba6d1eeaf9bcb64b2e9fea75efabffb3ed3ab28858e55a016a5efa95f509994ee4341b341199ca630b89e - languageName: node - linkType: hard - -"@eslint/plugin-kit@npm:^0.4.0": - version: 0.4.0 - resolution: "@eslint/plugin-kit@npm:0.4.0" - dependencies: - "@eslint/core": "npm:^0.16.0" - levn: "npm:^0.4.1" - checksum: 10c0/125614e902bb34c041da859794c47ac2ec4a814f5d9e7c4d37fcd34b38d8ee5cf1f97020d38d168885d9bf4046a9a7decb86b4cee8dac9eedcc6ad08ebafe204 - languageName: node - linkType: hard - -"@humanfs/core@npm:^0.19.1": - version: 0.19.1 - resolution: "@humanfs/core@npm:0.19.1" - checksum: 10c0/aa4e0152171c07879b458d0e8a704b8c3a89a8c0541726c6b65b81e84fd8b7564b5d6c633feadc6598307d34564bd53294b533491424e8e313d7ab6c7bc5dc67 - languageName: node - linkType: hard - -"@humanfs/node@npm:^0.16.6": - version: 0.16.7 - resolution: "@humanfs/node@npm:0.16.7" - dependencies: - "@humanfs/core": "npm:^0.19.1" - "@humanwhocodes/retry": "npm:^0.4.0" - checksum: 10c0/9f83d3cf2cfa37383e01e3cdaead11cd426208e04c44adcdd291aa983aaf72d7d3598844d2fe9ce54896bb1bf8bd4b56883376611c8905a19c44684642823f30 - languageName: node - linkType: hard - -"@humanwhocodes/module-importer@npm:^1.0.1": - version: 1.0.1 - resolution: "@humanwhocodes/module-importer@npm:1.0.1" - checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 - languageName: node - linkType: hard - -"@humanwhocodes/momoa@npm:^3.3.9": - version: 3.3.9 - resolution: "@humanwhocodes/momoa@npm:3.3.9" - checksum: 10c0/591e1ef6b6e299a57006a052199a0b5f854dfbd0016c7862eb21fe7441a1426ef2ea75c006863693eb98fc46d4a60a82319546adb0277df2814b543a8dad7a7b - languageName: node - linkType: hard - -"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2": - version: 0.4.3 - resolution: "@humanwhocodes/retry@npm:0.4.3" - checksum: 10c0/3775bb30087d4440b3f7406d5a057777d90e4b9f435af488a4923ef249e93615fb78565a85f173a186a076c7706a81d0d57d563a2624e4de2c5c9c66c486ce42 - languageName: node - linkType: hard - -"@minecraft/common@npm:1.2.0, @minecraft/common@npm:^1.0.0": - version: 1.2.0 - resolution: "@minecraft/common@npm:1.2.0" - checksum: 10c0/597c3ff8ab275ba5d5fb3037e68970e59ac96e8793b7738178c95b17d22a8f48a4412425314ed494f664466dd9a342e2a9eff52af544e57689f103c2ae965e10 - languageName: node - linkType: hard - -"@minecraft/math@npm:2.2.11": - version: 2.2.11 - resolution: "@minecraft/math@npm:2.2.11" - peerDependencies: - "@minecraft/server": ^1.15.0 || ^2.0.0 - checksum: 10c0/28600e0d9933f9a0e0feb1d5fb338eb2d193e6ca7567eb8573f517cdabfa1609b52e4860f59dab66faece29f92120a5c981a6645efd73a0182d573668d595d7d - languageName: node - linkType: hard - -"@minecraft/server-ui@npm:^2.0.0": - version: 2.0.0 - resolution: "@minecraft/server-ui@npm:2.0.0" - dependencies: - "@minecraft/common": "npm:^1.0.0" - "@minecraft/server": "npm:^2.0.0" - checksum: 10c0/5cf1b82b87b86837530e7d63a879dbca33bc04d3ceaa9398bf504e9f0f2a0e3a352d1635aef82388d453e815716c841c101616cb66fbba6c39d3f610a2c09ab7 - languageName: node - linkType: hard - -"@minecraft/server@npm:2.2.0, @minecraft/server@npm:^2.0.0": - version: 2.2.0 - resolution: "@minecraft/server@npm:2.2.0" - peerDependencies: - "@minecraft/common": ^1.2.0 - "@minecraft/vanilla-data": ">=1.20.70" - checksum: 10c0/16ea1fb69c7e322a1738b22cc3b183170f71da1f1a41e64b13e74f0135b1ec92d4ff991cacd2cc55b71849ad059827e56827b462f23cbe51e40f78e1b79ccdac - languageName: node - linkType: hard - -"@minecraft/vanilla-data@npm:1.21.114": - version: 1.21.114 - resolution: "@minecraft/vanilla-data@npm:1.21.114" - checksum: 10c0/77a66fe4643ec08f0054dc9afe0f021d9250ea245c5ca5b2a0d3fda13df8bf5c40231ec5d759611a392a7dbff5f377945c66ad6594d840128dfa406f70cd95c2 - languageName: node - linkType: hard - -"@nodelib/fs.scandir@npm:2.1.5": - version: 2.1.5 - resolution: "@nodelib/fs.scandir@npm:2.1.5" - dependencies: - "@nodelib/fs.stat": "npm:2.0.5" - run-parallel: "npm:^1.1.9" - checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb - languageName: node - linkType: hard - -"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": - version: 2.0.5 - resolution: "@nodelib/fs.stat@npm:2.0.5" - checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d - languageName: node - linkType: hard - -"@nodelib/fs.walk@npm:^1.2.3": - version: 1.2.8 - resolution: "@nodelib/fs.walk@npm:1.2.8" - dependencies: - "@nodelib/fs.scandir": "npm:2.1.5" - fastq: "npm:^1.6.0" - checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1 - languageName: node - linkType: hard - -"@stylistic/eslint-config@npm:^1.1.0": - version: 1.1.0 - resolution: "@stylistic/eslint-config@npm:1.1.0" - dependencies: - "@stylistic/eslint-plugin-js": "npm:1.1.0" - "@stylistic/eslint-plugin-ts": "npm:1.1.0" - checksum: 10c0/bb19a26f0c329c6454416f5c170ef3ffde1ed924c448c2faa34aabffbe04c65f47b004ef812e7253c2325c49c064726ddfe35c6dab6c66cdce50390f06fec34c - languageName: node - linkType: hard - -"@stylistic/eslint-plugin-js@npm:1.1.0": - version: 1.1.0 - resolution: "@stylistic/eslint-plugin-js@npm:1.1.0" - dependencies: - acorn: "npm:^8.11.2" - escape-string-regexp: "npm:^4.0.0" - eslint-visitor-keys: "npm:^3.4.3" - espree: "npm:^9.6.1" - graphemer: "npm:^1.4.0" - checksum: 10c0/15cb4cf4e47f0f63c06592b2c399c3a3795781f2efe099c55e3a29cb380b3043407e86f090e58e7e55419a3acfd7429195c752c9eb8d94e0358b45758efe64c1 - languageName: node - linkType: hard - -"@stylistic/eslint-plugin-ts@npm:1.1.0": - version: 1.1.0 - resolution: "@stylistic/eslint-plugin-ts@npm:1.1.0" - dependencies: - "@stylistic/eslint-plugin-js": "npm:1.1.0" - "@typescript-eslint/utils": "npm:^6.10.0" - graphemer: "npm:^1.4.0" - peerDependencies: - eslint: "*" - checksum: 10c0/6f89f7b73794e3f346c35008fbfc28a530a5ad66f03d8b94c4571220a720053298f1ab815909170c1df22fdd44353084dd6b6530f9d0f7a7bddda6f5a1e7b336 - languageName: node - linkType: hard - -"@stylistic/eslint-plugin@npm:^5.4.0": - version: 5.4.0 - resolution: "@stylistic/eslint-plugin@npm:5.4.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.9.0" - "@typescript-eslint/types": "npm:^8.44.0" - eslint-visitor-keys: "npm:^4.2.1" - espree: "npm:^10.4.0" - estraverse: "npm:^5.3.0" - picomatch: "npm:^4.0.3" - peerDependencies: - eslint: ">=9.0.0" - checksum: 10c0/02db4ec387c75300f07417641fb26eb41fd2a202608d1d752ed799cb72a8cea270abcc0a36eafa2ab7488e8cbe5a51e778afa56100f69ade572d1ec4051e8883 - languageName: node - linkType: hard - -"@types/estree@npm:^1.0.6": - version: 1.0.8 - resolution: "@types/estree@npm:1.0.8" - checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5 - languageName: node - linkType: hard - -"@types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.15": - version: 7.0.15 - resolution: "@types/json-schema@npm:7.0.15" - checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db - languageName: node - linkType: hard - -"@types/semver@npm:^7.5.0": - version: 7.7.1 - resolution: "@types/semver@npm:7.7.1" - checksum: 10c0/c938aef3bf79a73f0f3f6037c16e2e759ff40c54122ddf0b2583703393d8d3127130823facb880e694caa324eb6845628186aac1997ee8b31dc2d18fafe26268 - languageName: node - linkType: hard - -"@typescript-eslint/eslint-plugin@npm:8.46.1, @typescript-eslint/eslint-plugin@npm:^8.46.1": - version: 8.46.1 - resolution: "@typescript-eslint/eslint-plugin@npm:8.46.1" - dependencies: - "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.46.1" - "@typescript-eslint/type-utils": "npm:8.46.1" - "@typescript-eslint/utils": "npm:8.46.1" - "@typescript-eslint/visitor-keys": "npm:8.46.1" - graphemer: "npm:^1.4.0" - ignore: "npm:^7.0.0" - natural-compare: "npm:^1.4.0" - ts-api-utils: "npm:^2.1.0" - peerDependencies: - "@typescript-eslint/parser": ^8.46.1 - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/7a269f7dc3f6d900b9a7caefc0ab455406aae7fc0c0a198b1f18623c1c47bd54c6769777b0d8a2ef2e674a60124470d85394feb5fae4991c84c6a37875f75410 - languageName: node - linkType: hard - -"@typescript-eslint/parser@npm:8.46.1, @typescript-eslint/parser@npm:^8.46.1": - version: 8.46.1 - resolution: "@typescript-eslint/parser@npm:8.46.1" - dependencies: - "@typescript-eslint/scope-manager": "npm:8.46.1" - "@typescript-eslint/types": "npm:8.46.1" - "@typescript-eslint/typescript-estree": "npm:8.46.1" - "@typescript-eslint/visitor-keys": "npm:8.46.1" - debug: "npm:^4.3.4" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/4d14e9dbd5b4ba6001d35ae8833b1b03588911d44b1e01a7e38b1883148c3b1d22e4d4de50e5c6a698a4697ef067e235524b521023d0f5a830767d54c8c5fff5 - languageName: node - linkType: hard - -"@typescript-eslint/project-service@npm:8.46.1": - version: 8.46.1 - resolution: "@typescript-eslint/project-service@npm:8.46.1" - dependencies: - "@typescript-eslint/tsconfig-utils": "npm:^8.46.1" - "@typescript-eslint/types": "npm:^8.46.1" - debug: "npm:^4.3.4" - peerDependencies: - typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/7218bb343eb371e468596947ef66f0ad5024a76f2787550e093af0fc2b34e1bba3e86840bdec719afd26368e9f75c1ea4ab09bdc84610a746acd89b66910cf8b - languageName: node - linkType: hard - -"@typescript-eslint/rule-tester@npm:^8.18.1": - version: 8.46.1 - resolution: "@typescript-eslint/rule-tester@npm:8.46.1" - dependencies: - "@typescript-eslint/parser": "npm:8.46.1" - "@typescript-eslint/typescript-estree": "npm:8.46.1" - "@typescript-eslint/utils": "npm:8.46.1" - ajv: "npm:^6.12.6" - json-stable-stringify-without-jsonify: "npm:^1.0.1" - lodash.merge: "npm:4.6.2" - semver: "npm:^7.6.0" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - checksum: 10c0/1528fe639881d842424525912811cc21ae970e2d807c8717f9152f3347e656b09f373d3441f5e966cf323a9de5065f9bc0a3770c9abc2d1d8c3fc061ca69d733 - languageName: node - linkType: hard - -"@typescript-eslint/scope-manager@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/scope-manager@npm:6.21.0" - dependencies: - "@typescript-eslint/types": "npm:6.21.0" - "@typescript-eslint/visitor-keys": "npm:6.21.0" - checksum: 10c0/eaf868938d811cbbea33e97e44ba7050d2b6892202cea6a9622c486b85ab1cf801979edf78036179a8ba4ac26f1dfdf7fcc83a68c1ff66be0b3a8e9a9989b526 - languageName: node - linkType: hard - -"@typescript-eslint/scope-manager@npm:8.46.1": - version: 8.46.1 - resolution: "@typescript-eslint/scope-manager@npm:8.46.1" - dependencies: - "@typescript-eslint/types": "npm:8.46.1" - "@typescript-eslint/visitor-keys": "npm:8.46.1" - checksum: 10c0/5cff63677e90f3307fe924b739a3fe9f5239f74ec389fa06d6fa0a3fa51f592d8fb038c0c71088157b5b6fb426145bff1239aa3676c05c7d71d3b9be0f8c2cba - languageName: node - linkType: hard - -"@typescript-eslint/tsconfig-utils@npm:8.46.1, @typescript-eslint/tsconfig-utils@npm:^8.46.1": - version: 8.46.1 - resolution: "@typescript-eslint/tsconfig-utils@npm:8.46.1" - peerDependencies: - typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/c373bd4e2f43e03d8d4dc91cacbc0acdb217809f0e7b23fb4dd349fdab2503489dd79a3adb394491763ec967fa1312c5c9aebdbc5799ad3ed773b036a6eddb9d - languageName: node - linkType: hard - -"@typescript-eslint/type-utils@npm:8.46.1": - version: 8.46.1 - resolution: "@typescript-eslint/type-utils@npm:8.46.1" - dependencies: - "@typescript-eslint/types": "npm:8.46.1" - "@typescript-eslint/typescript-estree": "npm:8.46.1" - "@typescript-eslint/utils": "npm:8.46.1" - debug: "npm:^4.3.4" - ts-api-utils: "npm:^2.1.0" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/bcd87755912ad626b496a78e5f3dd8182dd59e815683d6b82a3e9fffc1b52384abfbe4d3faf2ec9b15be67b88e5082a798f35f96624517f82a5026973c251074 - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/types@npm:6.21.0" - checksum: 10c0/020631d3223bbcff8a0da3efbdf058220a8f48a3de221563996ad1dcc30d6c08dadc3f7608cc08830d21c0d565efd2db19b557b9528921c78aabb605eef2d74d - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:8.46.1, @typescript-eslint/types@npm:^8.44.0, @typescript-eslint/types@npm:^8.46.1": - version: 8.46.1 - resolution: "@typescript-eslint/types@npm:8.46.1" - checksum: 10c0/90887acaa5b33b45af20cf7f87ec4ae098c0daa88484245473e73903fa6e542f613247c22148132167891ca06af6549a60b9d2fd14a65b22871e016901ce3756 - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.21.0" - dependencies: - "@typescript-eslint/types": "npm:6.21.0" - "@typescript-eslint/visitor-keys": "npm:6.21.0" - debug: "npm:^4.3.4" - globby: "npm:^11.1.0" - is-glob: "npm:^4.0.3" - minimatch: "npm:9.0.3" - semver: "npm:^7.5.4" - ts-api-utils: "npm:^1.0.1" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/af1438c60f080045ebb330155a8c9bb90db345d5069cdd5d01b67de502abb7449d6c75500519df829f913a6b3f490ade3e8215279b6bdc63d0fb0ae61034df5f - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:8.46.1": - version: 8.46.1 - resolution: "@typescript-eslint/typescript-estree@npm:8.46.1" - dependencies: - "@typescript-eslint/project-service": "npm:8.46.1" - "@typescript-eslint/tsconfig-utils": "npm:8.46.1" - "@typescript-eslint/types": "npm:8.46.1" - "@typescript-eslint/visitor-keys": "npm:8.46.1" - debug: "npm:^4.3.4" - fast-glob: "npm:^3.3.2" - is-glob: "npm:^4.0.3" - minimatch: "npm:^9.0.4" - semver: "npm:^7.6.0" - ts-api-utils: "npm:^2.1.0" - peerDependencies: - typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/610048f615d4487f3dc57b7440214a14614a9dca8783d142e7dd29e2948d9c8239773839a3bcdf509c266d5f8595ea9f3a20c53c38d7b3bf3cf2305de1491bd8 - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:8.46.1, @typescript-eslint/utils@npm:^8.18.1": - version: 8.46.1 - resolution: "@typescript-eslint/utils@npm:8.46.1" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.7.0" - "@typescript-eslint/scope-manager": "npm:8.46.1" - "@typescript-eslint/types": "npm:8.46.1" - "@typescript-eslint/typescript-estree": "npm:8.46.1" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/9089be6b88a934843fd4eead61739e43dc79ba3db3dbaebcd9908eed819765b6414da983254a7d619e89d28b441bd131f53c9f163c39ca5b2369b76cd6699121 - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:^6.10.0": - version: 6.21.0 - resolution: "@typescript-eslint/utils@npm:6.21.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@types/json-schema": "npm:^7.0.12" - "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:6.21.0" - "@typescript-eslint/types": "npm:6.21.0" - "@typescript-eslint/typescript-estree": "npm:6.21.0" - semver: "npm:^7.5.4" - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - checksum: 10c0/ab2df3833b2582d4e5467a484d08942b4f2f7208f8e09d67de510008eb8001a9b7460f2f9ba11c12086fd3cdcac0c626761c7995c2c6b5657d5fa6b82030a32d - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.21.0" - dependencies: - "@typescript-eslint/types": "npm:6.21.0" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10c0/7395f69739cfa1cb83c1fb2fad30afa2a814756367302fb4facd5893eff66abc807e8d8f63eba94ed3b0fe0c1c996ac9a1680bcbf0f83717acedc3f2bb724fbf - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:8.46.1": - version: 8.46.1 - resolution: "@typescript-eslint/visitor-keys@npm:8.46.1" - dependencies: - "@typescript-eslint/types": "npm:8.46.1" - eslint-visitor-keys: "npm:^4.2.1" - checksum: 10c0/4139a8d78ad95e59fff2285beb623a530b7c2e6af89b994a92e9d8728d0c86eb8d86f64f2372aa874f9f24924253ba9887a2f77bec6bfc6028380b024c24e582 - languageName: node - linkType: hard - -"acorn-jsx@npm:^5.3.2": - version: 5.3.2 - resolution: "acorn-jsx@npm:5.3.2" - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10c0/4c54868fbef3b8d58927d5e33f0a4de35f59012fe7b12cf9dfbb345fb8f46607709e1c4431be869a23fb63c151033d84c4198fa9f79385cec34fcb1dd53974c1 - languageName: node - linkType: hard - -"acorn@npm:^8.11.2, acorn@npm:^8.15.0, acorn@npm:^8.9.0": - version: 8.15.0 - resolution: "acorn@npm:8.15.0" - bin: - acorn: bin/acorn - checksum: 10c0/dec73ff59b7d6628a01eebaece7f2bdb8bb62b9b5926dcad0f8931f2b8b79c2be21f6c68ac095592adb5adb15831a3635d9343e6a91d028bbe85d564875ec3ec - languageName: node - linkType: hard - -"ajv@npm:^6.12.4, ajv@npm:^6.12.6": - version: 6.12.6 - resolution: "ajv@npm:6.12.6" - dependencies: - fast-deep-equal: "npm:^3.1.1" - fast-json-stable-stringify: "npm:^2.0.0" - json-schema-traverse: "npm:^0.4.1" - uri-js: "npm:^4.2.2" - checksum: 10c0/41e23642cbe545889245b9d2a45854ebba51cda6c778ebced9649420d9205f2efb39cb43dbc41e358409223b1ea43303ae4839db682c848b891e4811da1a5a71 - languageName: node - linkType: hard - -"ansi-styles@npm:^4.1.0": - version: 4.3.0 - resolution: "ansi-styles@npm:4.3.0" - dependencies: - color-convert: "npm:^2.0.1" - checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 - languageName: node - linkType: hard - -"argparse@npm:^2.0.1": - version: 2.0.1 - resolution: "argparse@npm:2.0.1" - checksum: 10c0/c5640c2d89045371c7cedd6a70212a04e360fd34d6edeae32f6952c63949e3525ea77dbec0289d8213a99bbaeab5abfa860b5c12cf88a2e6cf8106e90dd27a7e - languageName: node - linkType: hard - -"array-union@npm:^2.1.0": - version: 2.1.0 - resolution: "array-union@npm:2.1.0" - checksum: 10c0/429897e68110374f39b771ec47a7161fc6a8fc33e196857c0a396dc75df0b5f65e4d046674db764330b6bb66b39ef48dd7c53b6a2ee75cfb0681e0c1a7033962 - languageName: node - linkType: hard - -"balanced-match@npm:^1.0.0": - version: 1.0.2 - resolution: "balanced-match@npm:1.0.2" - checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee - languageName: node - linkType: hard - -"brace-expansion@npm:^1.1.7": - version: 1.1.12 - resolution: "brace-expansion@npm:1.1.12" - dependencies: - balanced-match: "npm:^1.0.0" - concat-map: "npm:0.0.1" - checksum: 10c0/975fecac2bb7758c062c20d0b3b6288c7cc895219ee25f0a64a9de662dbac981ff0b6e89909c3897c1f84fa353113a721923afdec5f8b2350255b097f12b1f73 - languageName: node - linkType: hard - -"brace-expansion@npm:^2.0.1": - version: 2.0.2 - resolution: "brace-expansion@npm:2.0.2" - dependencies: - balanced-match: "npm:^1.0.0" - checksum: 10c0/6d117a4c793488af86b83172deb6af143e94c17bc53b0b3cec259733923b4ca84679d506ac261f4ba3c7ed37c46018e2ff442f9ce453af8643ecd64f4a54e6cf - languageName: node - linkType: hard - -"braces@npm:^3.0.3": - version: 3.0.3 - resolution: "braces@npm:3.0.3" - dependencies: - fill-range: "npm:^7.1.1" - checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04 - languageName: node - linkType: hard - -"callsites@npm:^3.0.0": - version: 3.1.0 - resolution: "callsites@npm:3.1.0" - checksum: 10c0/fff92277400eb06c3079f9e74f3af120db9f8ea03bad0e84d9aede54bbe2d44a56cccb5f6cf12211f93f52306df87077ecec5b712794c5a9b5dac6d615a3f301 - languageName: node - linkType: hard - -"chalk@npm:^4.0.0": - version: 4.1.2 - resolution: "chalk@npm:4.1.2" - dependencies: - ansi-styles: "npm:^4.1.0" - supports-color: "npm:^7.1.0" - checksum: 10c0/4a3fef5cc34975c898ffe77141450f679721df9dde00f6c304353fa9c8b571929123b26a0e4617bde5018977eb655b31970c297b91b63ee83bb82aeb04666880 - languageName: node - linkType: hard - -"color-convert@npm:^2.0.1": - version: 2.0.1 - resolution: "color-convert@npm:2.0.1" - dependencies: - color-name: "npm:~1.1.4" - checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 - languageName: node - linkType: hard - -"color-name@npm:~1.1.4": - version: 1.1.4 - resolution: "color-name@npm:1.1.4" - checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 - languageName: node - linkType: hard - -"concat-map@npm:0.0.1": - version: 0.0.1 - resolution: "concat-map@npm:0.0.1" - checksum: 10c0/c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f - languageName: node - linkType: hard - -"cross-spawn@npm:^7.0.6": - version: 7.0.6 - resolution: "cross-spawn@npm:7.0.6" - dependencies: - path-key: "npm:^3.1.0" - shebang-command: "npm:^2.0.0" - which: "npm:^2.0.1" - checksum: 10c0/053ea8b2135caff68a9e81470e845613e374e7309a47731e81639de3eaeb90c3d01af0e0b44d2ab9d50b43467223b88567dfeb3262db942dc063b9976718ffc1 - languageName: node - linkType: hard - -"debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4": - version: 4.4.3 - resolution: "debug@npm:4.4.3" - dependencies: - ms: "npm:^2.1.3" - peerDependenciesMeta: - supports-color: - optional: true - checksum: 10c0/d79136ec6c83ecbefd0f6a5593da6a9c91ec4d7ddc4b54c883d6e71ec9accb5f67a1a5e96d00a328196b5b5c86d365e98d8a3a70856aaf16b4e7b1985e67f5a6 - languageName: node - linkType: hard - -"deep-is@npm:^0.1.3": - version: 0.1.4 - resolution: "deep-is@npm:0.1.4" - checksum: 10c0/7f0ee496e0dff14a573dc6127f14c95061b448b87b995fc96c017ce0a1e66af1675e73f1d6064407975bc4ea6ab679497a29fff7b5b9c4e99cb10797c1ad0b4c - languageName: node - linkType: hard - -"dir-glob@npm:^3.0.1": - version: 3.0.1 - resolution: "dir-glob@npm:3.0.1" - dependencies: - path-type: "npm:^4.0.0" - checksum: 10c0/dcac00920a4d503e38bb64001acb19df4efc14536ada475725e12f52c16777afdee4db827f55f13a908ee7efc0cb282e2e3dbaeeb98c0993dd93d1802d3bf00c - languageName: node - linkType: hard - -"escape-string-regexp@npm:^4.0.0": - version: 4.0.0 - resolution: "escape-string-regexp@npm:4.0.0" - checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9 - languageName: node - linkType: hard - -"eslint-plugin-minecraft-linting@npm:^2.0.10": - version: 2.0.10 - resolution: "eslint-plugin-minecraft-linting@npm:2.0.10" - dependencies: - "@typescript-eslint/rule-tester": "npm:^8.18.1" - "@typescript-eslint/utils": "npm:^8.18.1" - eslint: "npm:^9.17.0" - typescript: "npm:^5.6.0" - checksum: 10c0/5865a85a818bbd224eb3be56e95fe45b07b2674c323e9296753dcbf20b8b15e6049faa2bd31a246e64400db5d570612ade00b1a97dbab7fc2d28a5fef5165a81 - languageName: node - linkType: hard - -"eslint-scope@npm:^8.4.0": - version: 8.4.0 - resolution: "eslint-scope@npm:8.4.0" - dependencies: - esrecurse: "npm:^4.3.0" - estraverse: "npm:^5.2.0" - checksum: 10c0/407f6c600204d0f3705bd557f81bd0189e69cd7996f408f8971ab5779c0af733d1af2f1412066b40ee1588b085874fc37a2333986c6521669cdbdd36ca5058e0 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": - version: 3.4.3 - resolution: "eslint-visitor-keys@npm:3.4.3" - checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^4.2.1": - version: 4.2.1 - resolution: "eslint-visitor-keys@npm:4.2.1" - checksum: 10c0/fcd43999199d6740db26c58dbe0c2594623e31ca307e616ac05153c9272f12f1364f5a0b1917a8e962268fdecc6f3622c1c2908b4fcc2e047a106fe6de69dc43 - languageName: node - linkType: hard - -"eslint@npm:^9.17.0, eslint@npm:^9.38.0": - version: 9.38.0 - resolution: "eslint@npm:9.38.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.8.0" - "@eslint-community/regexpp": "npm:^4.12.1" - "@eslint/config-array": "npm:^0.21.1" - "@eslint/config-helpers": "npm:^0.4.1" - "@eslint/core": "npm:^0.16.0" - "@eslint/eslintrc": "npm:^3.3.1" - "@eslint/js": "npm:9.38.0" - "@eslint/plugin-kit": "npm:^0.4.0" - "@humanfs/node": "npm:^0.16.6" - "@humanwhocodes/module-importer": "npm:^1.0.1" - "@humanwhocodes/retry": "npm:^0.4.2" - "@types/estree": "npm:^1.0.6" - ajv: "npm:^6.12.4" - chalk: "npm:^4.0.0" - cross-spawn: "npm:^7.0.6" - debug: "npm:^4.3.2" - escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^8.4.0" - eslint-visitor-keys: "npm:^4.2.1" - espree: "npm:^10.4.0" - esquery: "npm:^1.5.0" - esutils: "npm:^2.0.2" - fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^8.0.0" - find-up: "npm:^5.0.0" - glob-parent: "npm:^6.0.2" - ignore: "npm:^5.2.0" - imurmurhash: "npm:^0.1.4" - is-glob: "npm:^4.0.0" - json-stable-stringify-without-jsonify: "npm:^1.0.1" - lodash.merge: "npm:^4.6.2" - minimatch: "npm:^3.1.2" - natural-compare: "npm:^1.4.0" - optionator: "npm:^0.9.3" - peerDependencies: - jiti: "*" - peerDependenciesMeta: - jiti: - optional: true - bin: - eslint: bin/eslint.js - checksum: 10c0/51b0978dce04233580263fd4b5c4f128ecffdcde44fbddfedb5bced48a60d4fc619f5ae91800a1461a78a860b14c77a5081b0b2cf628b705580b70126a11e14b - languageName: node - linkType: hard - -"espree@npm:^10.0.1, espree@npm:^10.4.0": - version: 10.4.0 - resolution: "espree@npm:10.4.0" - dependencies: - acorn: "npm:^8.15.0" - acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^4.2.1" - checksum: 10c0/c63fe06131c26c8157b4083313cb02a9a54720a08e21543300e55288c40e06c3fc284bdecf108d3a1372c5934a0a88644c98714f38b6ae8ed272b40d9ea08d6b - languageName: node - linkType: hard - -"espree@npm:^9.6.1": - version: 9.6.1 - resolution: "espree@npm:9.6.1" - dependencies: - acorn: "npm:^8.9.0" - acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10c0/1a2e9b4699b715347f62330bcc76aee224390c28bb02b31a3752e9d07549c473f5f986720483c6469cf3cfb3c9d05df612ffc69eb1ee94b54b739e67de9bb460 - languageName: node - linkType: hard - -"esquery@npm:^1.5.0": - version: 1.6.0 - resolution: "esquery@npm:1.6.0" - dependencies: - estraverse: "npm:^5.1.0" - checksum: 10c0/cb9065ec605f9da7a76ca6dadb0619dfb611e37a81e318732977d90fab50a256b95fee2d925fba7c2f3f0523aa16f91587246693bc09bc34d5a59575fe6e93d2 - languageName: node - linkType: hard - -"esrecurse@npm:^4.3.0": - version: 4.3.0 - resolution: "esrecurse@npm:4.3.0" - dependencies: - estraverse: "npm:^5.2.0" - checksum: 10c0/81a37116d1408ded88ada45b9fb16dbd26fba3aadc369ce50fcaf82a0bac12772ebd7b24cd7b91fc66786bf2c1ac7b5f196bc990a473efff972f5cb338877cf5 - languageName: node - linkType: hard - -"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0": - version: 5.3.0 - resolution: "estraverse@npm:5.3.0" - checksum: 10c0/1ff9447b96263dec95d6d67431c5e0771eb9776427421260a3e2f0fdd5d6bd4f8e37a7338f5ad2880c9f143450c9b1e4fc2069060724570a49cf9cf0312bd107 - languageName: node - linkType: hard - -"esutils@npm:^2.0.2": - version: 2.0.3 - resolution: "esutils@npm:2.0.3" - checksum: 10c0/9a2fe69a41bfdade834ba7c42de4723c97ec776e40656919c62cbd13607c45e127a003f05f724a1ea55e5029a4cf2de444b13009f2af71271e42d93a637137c7 - languageName: node - linkType: hard - -"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": - version: 3.1.3 - resolution: "fast-deep-equal@npm:3.1.3" - checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0 - languageName: node - linkType: hard - -"fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2": - version: 3.3.3 - resolution: "fast-glob@npm:3.3.3" - dependencies: - "@nodelib/fs.stat": "npm:^2.0.2" - "@nodelib/fs.walk": "npm:^1.2.3" - glob-parent: "npm:^5.1.2" - merge2: "npm:^1.3.0" - micromatch: "npm:^4.0.8" - checksum: 10c0/f6aaa141d0d3384cf73cbcdfc52f475ed293f6d5b65bfc5def368b09163a9f7e5ec2b3014d80f733c405f58e470ee0cc451c2937685045cddcdeaa24199c43fe - languageName: node - linkType: hard - -"fast-json-stable-stringify@npm:^2.0.0": - version: 2.1.0 - resolution: "fast-json-stable-stringify@npm:2.1.0" - checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b - languageName: node - linkType: hard - -"fast-levenshtein@npm:^2.0.6": - version: 2.0.6 - resolution: "fast-levenshtein@npm:2.0.6" - checksum: 10c0/111972b37338bcb88f7d9e2c5907862c280ebf4234433b95bc611e518d192ccb2d38119c4ac86e26b668d75f7f3894f4ff5c4982899afced7ca78633b08287c4 - languageName: node - linkType: hard - -"fastq@npm:^1.6.0": - version: 1.19.1 - resolution: "fastq@npm:1.19.1" - dependencies: - reusify: "npm:^1.0.4" - checksum: 10c0/ebc6e50ac7048daaeb8e64522a1ea7a26e92b3cee5cd1c7f2316cdca81ba543aa40a136b53891446ea5c3a67ec215fbaca87ad405f102dd97012f62916905630 - languageName: node - linkType: hard - -"file-entry-cache@npm:^8.0.0": - version: 8.0.0 - resolution: "file-entry-cache@npm:8.0.0" - dependencies: - flat-cache: "npm:^4.0.0" - checksum: 10c0/9e2b5938b1cd9b6d7e3612bdc533afd4ac17b2fc646569e9a8abbf2eb48e5eb8e316bc38815a3ef6a1b456f4107f0d0f055a614ca613e75db6bf9ff4d72c1638 - languageName: node - linkType: hard - -"fill-range@npm:^7.1.1": - version: 7.1.1 - resolution: "fill-range@npm:7.1.1" - dependencies: - to-regex-range: "npm:^5.0.1" - checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018 - languageName: node - linkType: hard - -"find-up@npm:^5.0.0": - version: 5.0.0 - resolution: "find-up@npm:5.0.0" - dependencies: - locate-path: "npm:^6.0.0" - path-exists: "npm:^4.0.0" - checksum: 10c0/062c5a83a9c02f53cdd6d175a37ecf8f87ea5bbff1fdfb828f04bfa021441bc7583e8ebc0872a4c1baab96221fb8a8a275a19809fb93fbc40bd69ec35634069a - languageName: node - linkType: hard - -"flat-cache@npm:^4.0.0": - version: 4.0.1 - resolution: "flat-cache@npm:4.0.1" - dependencies: - flatted: "npm:^3.2.9" - keyv: "npm:^4.5.4" - checksum: 10c0/2c59d93e9faa2523e4fda6b4ada749bed432cfa28c8e251f33b25795e426a1c6dbada777afb1f74fcfff33934fdbdea921ee738fcc33e71adc9d6eca984a1cfc - languageName: node - linkType: hard - -"flatted@npm:^3.2.9": - version: 3.3.3 - resolution: "flatted@npm:3.3.3" - checksum: 10c0/e957a1c6b0254aa15b8cce8533e24165abd98fadc98575db082b786b5da1b7d72062b81bfdcd1da2f4d46b6ed93bec2434e62333e9b4261d79ef2e75a10dd538 - languageName: node - linkType: hard - -"glob-parent@npm:^5.1.2": - version: 5.1.2 - resolution: "glob-parent@npm:5.1.2" - dependencies: - is-glob: "npm:^4.0.1" - checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee - languageName: node - linkType: hard - -"glob-parent@npm:^6.0.2": - version: 6.0.2 - resolution: "glob-parent@npm:6.0.2" - dependencies: - is-glob: "npm:^4.0.3" - checksum: 10c0/317034d88654730230b3f43bb7ad4f7c90257a426e872ea0bf157473ac61c99bf5d205fad8f0185f989be8d2fa6d3c7dce1645d99d545b6ea9089c39f838e7f8 - languageName: node - linkType: hard - -"globals@npm:^14.0.0": - version: 14.0.0 - resolution: "globals@npm:14.0.0" - checksum: 10c0/b96ff42620c9231ad468d4c58ff42afee7777ee1c963013ff8aabe095a451d0ceeb8dcd8ef4cbd64d2538cef45f787a78ba3a9574f4a634438963e334471302d - languageName: node - linkType: hard - -"globby@npm:^11.1.0": - version: 11.1.0 - resolution: "globby@npm:11.1.0" - dependencies: - array-union: "npm:^2.1.0" - dir-glob: "npm:^3.0.1" - fast-glob: "npm:^3.2.9" - ignore: "npm:^5.2.0" - merge2: "npm:^1.4.1" - slash: "npm:^3.0.0" - checksum: 10c0/b39511b4afe4bd8a7aead3a27c4ade2b9968649abab0a6c28b1a90141b96ca68ca5db1302f7c7bd29eab66bf51e13916b8e0a3d0ac08f75e1e84a39b35691189 - languageName: node - linkType: hard - -"graphemer@npm:^1.4.0": - version: 1.4.0 - resolution: "graphemer@npm:1.4.0" - checksum: 10c0/e951259d8cd2e0d196c72ec711add7115d42eb9a8146c8eeda5b8d3ac91e5dd816b9cd68920726d9fd4490368e7ed86e9c423f40db87e2d8dfafa00fa17c3a31 - languageName: node - linkType: hard - -"has-flag@npm:^4.0.0": - version: 4.0.0 - resolution: "has-flag@npm:4.0.0" - checksum: 10c0/2e789c61b7888d66993e14e8331449e525ef42aac53c627cc53d1c3334e768bcb6abdc4f5f0de1478a25beec6f0bd62c7549058b7ac53e924040d4f301f02fd1 - languageName: node - linkType: hard - -"ignore@npm:^5.2.0": - version: 5.3.2 - resolution: "ignore@npm:5.3.2" - checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 - languageName: node - linkType: hard - -"ignore@npm:^7.0.0": - version: 7.0.5 - resolution: "ignore@npm:7.0.5" - checksum: 10c0/ae00db89fe873064a093b8999fe4cc284b13ef2a178636211842cceb650b9c3e390d3339191acb145d81ed5379d2074840cf0c33a20bdbd6f32821f79eb4ad5d - languageName: node - linkType: hard - -"import-fresh@npm:^3.2.1": - version: 3.3.1 - resolution: "import-fresh@npm:3.3.1" - dependencies: - parent-module: "npm:^1.0.0" - resolve-from: "npm:^4.0.0" - checksum: 10c0/bf8cc494872fef783249709385ae883b447e3eb09db0ebd15dcead7d9afe7224dad7bd7591c6b73b0b19b3c0f9640eb8ee884f01cfaf2887ab995b0b36a0cbec - languageName: node - linkType: hard - -"imurmurhash@npm:^0.1.4": - version: 0.1.4 - resolution: "imurmurhash@npm:0.1.4" - checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 - languageName: node - linkType: hard - -"is-extglob@npm:^2.1.1": - version: 2.1.1 - resolution: "is-extglob@npm:2.1.1" - checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 - languageName: node - linkType: hard - -"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": - version: 4.0.3 - resolution: "is-glob@npm:4.0.3" - dependencies: - is-extglob: "npm:^2.1.1" - checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a - languageName: node - linkType: hard - -"is-number@npm:^7.0.0": - version: 7.0.0 - resolution: "is-number@npm:7.0.0" - checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811 - languageName: node - linkType: hard - -"isexe@npm:^2.0.0": - version: 2.0.0 - resolution: "isexe@npm:2.0.0" - checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d - languageName: node - linkType: hard - -"js-yaml@npm:^4.1.0": - version: 4.1.0 - resolution: "js-yaml@npm:4.1.0" - dependencies: - argparse: "npm:^2.0.1" - bin: - js-yaml: bin/js-yaml.js - checksum: 10c0/184a24b4eaacfce40ad9074c64fd42ac83cf74d8c8cd137718d456ced75051229e5061b8633c3366b8aada17945a7a356b337828c19da92b51ae62126575018f - languageName: node - linkType: hard - -"json-buffer@npm:3.0.1": - version: 3.0.1 - resolution: "json-buffer@npm:3.0.1" - checksum: 10c0/0d1c91569d9588e7eef2b49b59851f297f3ab93c7b35c7c221e288099322be6b562767d11e4821da500f3219542b9afd2e54c5dc573107c1126ed1080f8e96d7 - languageName: node - linkType: hard - -"json-schema-traverse@npm:^0.4.1": - version: 0.4.1 - resolution: "json-schema-traverse@npm:0.4.1" - checksum: 10c0/108fa90d4cc6f08243aedc6da16c408daf81793bf903e9fd5ab21983cda433d5d2da49e40711da016289465ec2e62e0324dcdfbc06275a607fe3233fde4942ce - languageName: node - linkType: hard - -"json-stable-stringify-without-jsonify@npm:^1.0.1": - version: 1.0.1 - resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" - checksum: 10c0/cb168b61fd4de83e58d09aaa6425ef71001bae30d260e2c57e7d09a5fd82223e2f22a042dedaab8db23b7d9ae46854b08bb1f91675a8be11c5cffebef5fb66a5 - languageName: node - linkType: hard - -"keyv@npm:^4.5.4": - version: 4.5.4 - resolution: "keyv@npm:4.5.4" - dependencies: - json-buffer: "npm:3.0.1" - checksum: 10c0/aa52f3c5e18e16bb6324876bb8b59dd02acf782a4b789c7b2ae21107fab95fab3890ed448d4f8dba80ce05391eeac4bfabb4f02a20221342982f806fa2cf271e - languageName: node - linkType: hard - -"levn@npm:^0.4.1": - version: 0.4.1 - resolution: "levn@npm:0.4.1" - dependencies: - prelude-ls: "npm:^1.2.1" - type-check: "npm:~0.4.0" - checksum: 10c0/effb03cad7c89dfa5bd4f6989364bfc79994c2042ec5966cb9b95990e2edee5cd8969ddf42616a0373ac49fac1403437deaf6e9050fbbaa3546093a59b9ac94e - languageName: node - linkType: hard - -"locate-path@npm:^6.0.0": - version: 6.0.0 - resolution: "locate-path@npm:6.0.0" - dependencies: - p-locate: "npm:^5.0.0" - checksum: 10c0/d3972ab70dfe58ce620e64265f90162d247e87159b6126b01314dd67be43d50e96a50b517bce2d9452a79409c7614054c277b5232377de50416564a77ac7aad3 - languageName: node - linkType: hard - -"lodash.merge@npm:4.6.2, lodash.merge@npm:^4.6.2": - version: 4.6.2 - resolution: "lodash.merge@npm:4.6.2" - checksum: 10c0/402fa16a1edd7538de5b5903a90228aa48eb5533986ba7fa26606a49db2572bf414ff73a2c9f5d5fd36b31c46a5d5c7e1527749c07cbcf965ccff5fbdf32c506 - languageName: node - linkType: hard - -"merge2@npm:^1.3.0, merge2@npm:^1.4.1": - version: 1.4.1 - resolution: "merge2@npm:1.4.1" - checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb - languageName: node - linkType: hard - -"micromatch@npm:^4.0.8": - version: 4.0.8 - resolution: "micromatch@npm:4.0.8" - dependencies: - braces: "npm:^3.0.3" - picomatch: "npm:^2.3.1" - checksum: 10c0/166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8 - languageName: node - linkType: hard - -"minimatch@npm:9.0.3": - version: 9.0.3 - resolution: "minimatch@npm:9.0.3" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10c0/85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac - languageName: node - linkType: hard - -"minimatch@npm:^3.1.2": - version: 3.1.2 - resolution: "minimatch@npm:3.1.2" - dependencies: - brace-expansion: "npm:^1.1.7" - checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311 - languageName: node - linkType: hard - -"minimatch@npm:^9.0.4": - version: 9.0.5 - resolution: "minimatch@npm:9.0.5" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10c0/de96cf5e35bdf0eab3e2c853522f98ffbe9a36c37797778d2665231ec1f20a9447a7e567cb640901f89e4daaa95ae5d70c65a9e8aa2bb0019b6facbc3c0575ed - languageName: node - linkType: hard - -"ms@npm:^2.1.3": - version: 2.1.3 - resolution: "ms@npm:2.1.3" - checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 - languageName: node - linkType: hard - -"natural-compare@npm:^1.4.0": - version: 1.4.0 - resolution: "natural-compare@npm:1.4.0" - checksum: 10c0/f5f9a7974bfb28a91afafa254b197f0f22c684d4a1731763dda960d2c8e375b36c7d690e0d9dc8fba774c537af14a7e979129bca23d88d052fbeb9466955e447 - languageName: node - linkType: hard - -"optionator@npm:^0.9.3": - version: 0.9.4 - resolution: "optionator@npm:0.9.4" - dependencies: - deep-is: "npm:^0.1.3" - fast-levenshtein: "npm:^2.0.6" - levn: "npm:^0.4.1" - prelude-ls: "npm:^1.2.1" - type-check: "npm:^0.4.0" - word-wrap: "npm:^1.2.5" - checksum: 10c0/4afb687a059ee65b61df74dfe87d8d6815cd6883cb8b3d5883a910df72d0f5d029821f37025e4bccf4048873dbdb09acc6d303d27b8f76b1a80dd5a7d5334675 - languageName: node - linkType: hard - -"p-limit@npm:^3.0.2": - version: 3.1.0 - resolution: "p-limit@npm:3.1.0" - dependencies: - yocto-queue: "npm:^0.1.0" - checksum: 10c0/9db675949dbdc9c3763c89e748d0ef8bdad0afbb24d49ceaf4c46c02c77d30db4e0652ed36d0a0a7a95154335fab810d95c86153105bb73b3a90448e2bb14e1a - languageName: node - linkType: hard - -"p-locate@npm:^5.0.0": - version: 5.0.0 - resolution: "p-locate@npm:5.0.0" - dependencies: - p-limit: "npm:^3.0.2" - checksum: 10c0/2290d627ab7903b8b70d11d384fee714b797f6040d9278932754a6860845c4d3190603a0772a663c8cb5a7b21d1b16acb3a6487ebcafa9773094edc3dfe6009a - languageName: node - linkType: hard - -"parent-module@npm:^1.0.0": - version: 1.0.1 - resolution: "parent-module@npm:1.0.1" - dependencies: - callsites: "npm:^3.0.0" - checksum: 10c0/c63d6e80000d4babd11978e0d3fee386ca7752a02b035fd2435960ffaa7219dc42146f07069fb65e6e8bf1caef89daf9af7535a39bddf354d78bf50d8294f556 - languageName: node - linkType: hard - -"path-exists@npm:^4.0.0": - version: 4.0.0 - resolution: "path-exists@npm:4.0.0" - checksum: 10c0/8c0bd3f5238188197dc78dced15207a4716c51cc4e3624c44fc97acf69558f5ebb9a2afff486fe1b4ee148e0c133e96c5e11a9aa5c48a3006e3467da070e5e1b - languageName: node - linkType: hard - -"path-key@npm:^3.1.0": - version: 3.1.1 - resolution: "path-key@npm:3.1.1" - checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c - languageName: node - linkType: hard - -"path-type@npm:^4.0.0": - version: 4.0.0 - resolution: "path-type@npm:4.0.0" - checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c - languageName: node - linkType: hard - -"picomatch@npm:^2.3.1": - version: 2.3.1 - resolution: "picomatch@npm:2.3.1" - checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be - languageName: node - linkType: hard - -"picomatch@npm:^4.0.3": - version: 4.0.3 - resolution: "picomatch@npm:4.0.3" - checksum: 10c0/9582c951e95eebee5434f59e426cddd228a7b97a0161a375aed4be244bd3fe8e3a31b846808ea14ef2c8a2527a6eeab7b3946a67d5979e81694654f939473ae2 - languageName: node - linkType: hard - -"prelude-ls@npm:^1.2.1": - version: 1.2.1 - resolution: "prelude-ls@npm:1.2.1" - checksum: 10c0/b00d617431e7886c520a6f498a2e14c75ec58f6d93ba48c3b639cf241b54232d90daa05d83a9e9b9fef6baa63cb7e1e4602c2372fea5bc169668401eb127d0cd - languageName: node - linkType: hard - -"punycode@npm:^2.1.0": - version: 2.3.1 - resolution: "punycode@npm:2.3.1" - checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9 - languageName: node - linkType: hard - -"queue-microtask@npm:^1.2.2": - version: 1.2.3 - resolution: "queue-microtask@npm:1.2.3" - checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102 - languageName: node - linkType: hard - -"resolve-from@npm:^4.0.0": - version: 4.0.0 - resolution: "resolve-from@npm:4.0.0" - checksum: 10c0/8408eec31a3112ef96e3746c37be7d64020cda07c03a920f5024e77290a218ea758b26ca9529fd7b1ad283947f34b2291c1c0f6aa0ed34acfdda9c6014c8d190 - languageName: node - linkType: hard - -"reusify@npm:^1.0.4": - version: 1.1.0 - resolution: "reusify@npm:1.1.0" - checksum: 10c0/4eff0d4a5f9383566c7d7ec437b671cc51b25963bd61bf127c3f3d3f68e44a026d99b8d2f1ad344afff8d278a8fe70a8ea092650a716d22287e8bef7126bb2fa - languageName: node - linkType: hard - -"run-parallel@npm:^1.1.9": - version: 1.2.0 - resolution: "run-parallel@npm:1.2.0" - dependencies: - queue-microtask: "npm:^1.2.2" - checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39 - languageName: node - linkType: hard - -"semver@npm:^7.5.4, semver@npm:^7.6.0": - version: 7.7.3 - resolution: "semver@npm:7.7.3" - bin: - semver: bin/semver.js - checksum: 10c0/4afe5c986567db82f44c8c6faef8fe9df2a9b1d98098fc1721f57c696c4c21cebd572f297fc21002f81889492345b8470473bc6f4aff5fb032a6ea59ea2bc45e - languageName: node - linkType: hard - -"shebang-command@npm:^2.0.0": - version: 2.0.0 - resolution: "shebang-command@npm:2.0.0" - dependencies: - shebang-regex: "npm:^3.0.0" - checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e - languageName: node - linkType: hard - -"shebang-regex@npm:^3.0.0": - version: 3.0.0 - resolution: "shebang-regex@npm:3.0.0" - checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 - languageName: node - linkType: hard - -"slash@npm:^3.0.0": - version: 3.0.0 - resolution: "slash@npm:3.0.0" - checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b - languageName: node - linkType: hard - -"strip-json-comments@npm:^3.1.1": - version: 3.1.1 - resolution: "strip-json-comments@npm:3.1.1" - checksum: 10c0/9681a6257b925a7fa0f285851c0e613cc934a50661fa7bb41ca9cbbff89686bb4a0ee366e6ecedc4daafd01e83eee0720111ab294366fe7c185e935475ebcecd - languageName: node - linkType: hard - -"supports-color@npm:^7.1.0": - version: 7.2.0 - resolution: "supports-color@npm:7.2.0" - dependencies: - has-flag: "npm:^4.0.0" - checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124 - languageName: node - linkType: hard - -"to-regex-range@npm:^5.0.1": - version: 5.0.1 - resolution: "to-regex-range@npm:5.0.1" - dependencies: - is-number: "npm:^7.0.0" - checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892 - languageName: node - linkType: hard - -"ts-api-utils@npm:^1.0.1": - version: 1.4.3 - resolution: "ts-api-utils@npm:1.4.3" - peerDependencies: - typescript: ">=4.2.0" - checksum: 10c0/e65dc6e7e8141140c23e1dc94984bf995d4f6801919c71d6dc27cf0cd51b100a91ffcfe5217626193e5bea9d46831e8586febdc7e172df3f1091a7384299e23a - languageName: node - linkType: hard - -"ts-api-utils@npm:^2.1.0": - version: 2.1.0 - resolution: "ts-api-utils@npm:2.1.0" - peerDependencies: - typescript: ">=4.8.4" - checksum: 10c0/9806a38adea2db0f6aa217ccc6bc9c391ddba338a9fe3080676d0d50ed806d305bb90e8cef0276e793d28c8a929f400abb184ddd7ff83a416959c0f4d2ce754f - languageName: node - linkType: hard - -"type-check@npm:^0.4.0, type-check@npm:~0.4.0": - version: 0.4.0 - resolution: "type-check@npm:0.4.0" - dependencies: - prelude-ls: "npm:^1.2.1" - checksum: 10c0/7b3fd0ed43891e2080bf0c5c504b418fbb3e5c7b9708d3d015037ba2e6323a28152ec163bcb65212741fa5d2022e3075ac3c76440dbd344c9035f818e8ecee58 - languageName: node - linkType: hard - -"typescript-eslint@npm:^8.46.1": - version: 8.46.1 - resolution: "typescript-eslint@npm:8.46.1" - dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.46.1" - "@typescript-eslint/parser": "npm:8.46.1" - "@typescript-eslint/typescript-estree": "npm:8.46.1" - "@typescript-eslint/utils": "npm:8.46.1" - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/002934d83eec1afcf94e9785399740efe39f1fe6538e469a01ed36c004303af8736e3aea9100c8733798fcb0d1e0301177bd70aa29e6d05d8cefbd8e18887ea6 - languageName: node - linkType: hard - -"typescript@npm:^5.6.0, typescript@npm:^5.9.3": - version: 5.9.3 - resolution: "typescript@npm:5.9.3" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/6bd7552ce39f97e711db5aa048f6f9995b53f1c52f7d8667c1abdc1700c68a76a308f579cd309ce6b53646deb4e9a1be7c813a93baaf0a28ccd536a30270e1c5 - languageName: node - linkType: hard - -"typescript@patch:typescript@npm%3A^5.6.0#optional!builtin, typescript@patch:typescript@npm%3A^5.9.3#optional!builtin": - version: 5.9.3 - resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=5786d5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/ad09fdf7a756814dce65bc60c1657b40d44451346858eea230e10f2e95a289d9183b6e32e5c11e95acc0ccc214b4f36289dcad4bf1886b0adb84d711d336a430 - languageName: node - linkType: hard - -"uri-js@npm:^4.2.2": - version: 4.4.1 - resolution: "uri-js@npm:4.4.1" - dependencies: - punycode: "npm:^2.1.0" - checksum: 10c0/4ef57b45aa820d7ac6496e9208559986c665e49447cb072744c13b66925a362d96dd5a46c4530a6b8e203e5db5fe849369444440cb22ecfc26c679359e5dfa3c - languageName: node - linkType: hard - -"which@npm:^2.0.1": - version: 2.0.2 - resolution: "which@npm:2.0.2" - dependencies: - isexe: "npm:^2.0.0" - bin: - node-which: ./bin/node-which - checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f - languageName: node - linkType: hard - -"word-wrap@npm:^1.2.5": - version: 1.2.5 - resolution: "word-wrap@npm:1.2.5" - checksum: 10c0/e0e4a1ca27599c92a6ca4c32260e8a92e8a44f4ef6ef93f803f8ed823f486e0889fc0b93be4db59c8d51b3064951d25e43d434e95dc8c960cc3a63d65d00ba20 - languageName: node - linkType: hard - -"yocto-queue@npm:^0.1.0": - version: 0.1.0 - resolution: "yocto-queue@npm:0.1.0" - checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f - languageName: node - linkType: hard From f26992cd639cc22d4ece1a10a9a5ee89f8dc604c Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sat, 25 Jul 2026 09:49:06 +0200 Subject: [PATCH 2/7] Add feasibility assessment tools for Vanilla Tweaks packs - Introduced `feasibility.json` to store feasibility verdicts for Vanilla Tweaks packs not shipped. - Implemented `feasibility.mjs` to validate entries and generate research worklists for agents. - Created `fetch.mjs` to download Vanilla Tweaks catalogs into a cache. - Added `ignore.json` to list Vanilla Tweaks packs that will never be ported. - Developed `issues.mjs` to manage GitHub issues related to missing packs, including creating, updating, and closing issues based on feasibility. - Implemented `lib.mjs` for shared utility functions across the tools. --- .claude/commands/vt-diff.md | 84 ++++++ .mcp.json | 8 + package.json | 6 +- tools/vt-diff/.gitignore | 2 + tools/vt-diff/AGENTS.md | 281 ++++++++++++++++++++ tools/vt-diff/README.md | 123 +++++++++ tools/vt-diff/aliases.json | 18 ++ tools/vt-diff/config.json | 65 +++++ tools/vt-diff/diff.mjs | 252 ++++++++++++++++++ tools/vt-diff/feasibility.json | 20 ++ tools/vt-diff/feasibility.mjs | 178 +++++++++++++ tools/vt-diff/fetch.mjs | 22 ++ tools/vt-diff/ignore.json | 39 +++ tools/vt-diff/issues.mjs | 472 +++++++++++++++++++++++++++++++++ tools/vt-diff/lib.mjs | 199 ++++++++++++++ 15 files changed, 1768 insertions(+), 1 deletion(-) create mode 100644 .claude/commands/vt-diff.md create mode 100644 .mcp.json create mode 100644 tools/vt-diff/.gitignore create mode 100644 tools/vt-diff/AGENTS.md create mode 100644 tools/vt-diff/README.md create mode 100644 tools/vt-diff/aliases.json create mode 100644 tools/vt-diff/config.json create mode 100644 tools/vt-diff/diff.mjs create mode 100644 tools/vt-diff/feasibility.json create mode 100644 tools/vt-diff/feasibility.mjs create mode 100644 tools/vt-diff/fetch.mjs create mode 100644 tools/vt-diff/ignore.json create mode 100644 tools/vt-diff/issues.mjs create mode 100644 tools/vt-diff/lib.mjs diff --git a/.claude/commands/vt-diff.md b/.claude/commands/vt-diff.md new file mode 100644 index 000000000..c8fefa02e --- /dev/null +++ b/.claude/commands/vt-diff.md @@ -0,0 +1,84 @@ +--- +description: Diff Vanilla Tweaks against our packs.json, research Bedrock feasibility, and prepare the tracking issues +allowed-tools: Bash, Read, Edit, Write, Glob, Grep, WebFetch, Agent +--- + +Run the Vanilla Tweaks parity check. + +**Read `tools/vt-diff/AGENTS.md` before doing anything else.** It holds the rules, the source +hierarchy and the verdict rubric. This command is the running order; that file is the method. + +Two rules override everything below: never run `issues.mjs --apply`, and never record an alias or a +verdict you have not verified. + +## 1. Confirm the pinned Vanilla Tweaks version + +Read `vanillaTweaks.version` from `tools/vt-diff/config.json`, then probe the next few candidates — +Vanilla Tweaks uses `YY.N` keys (`26.1`, `26.2`, ...): + +```sh +for v in ; do curl -s -o /dev/null -w "$v=%{http_code}\n" \ + "https://vanillatweaks.net/assets/resources/json/$v/rpcategories.json"; done +``` + +If a newer key returns `200`, update `config.json` and say so in your summary. Do not bump silently. + +## 2. Fetch and diff + +```sh +node tools/vt-diff/fetch.mjs && node tools/vt-diff/diff.mjs +``` + +## 3. Alias pass + +Follow `AGENTS.md` → *Pass A*. Work `missing[].suggestions` **and** cross-reference `bedrockOnly[]`, +since a rename appears on both lists. Verify each candidate against `packs.json` and +`
/files/` before writing to `aliases.json`, then rerun `diff.mjs` and confirm both counts +moved. + +Report aliases added, candidates rejected and why, and any `packs.json` defects found. + +## 4. Feasibility pass + +```sh +node tools/vt-diff/feasibility.mjs +``` + +Follow `AGENTS.md` → *Pass B*. Dispatch one agent per file in `out/feasibility-batches/`, running +them in parallel. Each agent researches only its own batch and returns a JSON fragment. Sources, in +order of preference: the `microsoft-learn` MCP server, `Mojang/bedrock-samples`, +`wiki.bedrock.dev/llms.txt` and its raw Markdown pages. + +Merge the fragments into `feasibility.json`, then: + +```sh +node tools/vt-diff/feasibility.mjs --validate +``` + +Fix every reported problem. `unknown` is a valid verdict; a guess is not. + +If the developer asked only for an issue refresh and not a research pass, skip this step and say +that the coverage number in the plan will be low. + +## 5. Build and review the issue plan + +```sh +node tools/vt-diff/issues.mjs +``` + +Follow `AGENTS.md` → *Pass C*. Verify `reopenCandidates` against `
/files/` before reporting +them — do not assume. + +## 6. Stop + +Present the plan and ask the developer to approve. Only they run `--apply`. + +If `gh auth status` fails, tell them to run `gh auth login` — dry runs work without it, `--apply` +does not. + +## Reporting rules + +Lead with the counts table from `report.md` and the feasibility coverage line from `issue-plan.md`. +Then, in order: newly missing packs since the last run, `reopenCandidates` you verified, `blocked` +verdicts recorded this run, and category drift. Leave `bedrockOnly` out unless asked — those are our +originals, not a gap. diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 000000000..a9af81654 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "microsoft-learn": { + "type": "http", + "url": "https://learn.microsoft.com/api/mcp" + } + } +} diff --git a/package.json b/package.json index ea240dc74..7ef9da491 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,11 @@ "regolith-install": "yarn workspaces foreach -i -A --topological --jobs=1 run regolith-install", "build": "yarn workspaces foreach -i -A run build", "lint": "yarn workspaces foreach -i -A run lint", - "test": "yarn workspaces foreach -i -A --continue run test" + "test": "yarn workspaces foreach -i -A --continue run test", + "vt:fetch": "node tools/vt-diff/fetch.mjs", + "vt:diff": "node tools/vt-diff/fetch.mjs && node tools/vt-diff/diff.mjs", + "vt:feasibility": "node tools/vt-diff/feasibility.mjs", + "vt:issues": "node tools/vt-diff/issues.mjs" }, "engines": { "node": ">=25.0.0" diff --git a/tools/vt-diff/.gitignore b/tools/vt-diff/.gitignore new file mode 100644 index 000000000..409586dd7 --- /dev/null +++ b/tools/vt-diff/.gitignore @@ -0,0 +1,2 @@ +.cache/ +out/ diff --git a/tools/vt-diff/AGENTS.md b/tools/vt-diff/AGENTS.md new file mode 100644 index 000000000..9f11a6332 --- /dev/null +++ b/tools/vt-diff/AGENTS.md @@ -0,0 +1,281 @@ +# vt-diff — agent playbook + +This tool is **initiated by a developer**, not by an agent on a schedule. The developer runs the +scripts; agents do the two passes that scripts cannot do — reconciling names and researching Bedrock +feasibility — and then stop. A human performs the final `--apply`. + +Read [README.md](./README.md) first for what each script does. This file is about the judgement +calls between the scripts. + +## Non-negotiable rules + +1. **Never run `issues.mjs --apply`.** Present the plan and stop. Only a developer applies it. +2. **Never add an alias you have not verified against the filesystem.** A matching name is not proof. +3. **Never record a feasibility verdict without a source URL.** `feasibility.mjs --validate` rejects + unsourced verdicts, but the point is to not write them in the first place. +4. **Never edit anything between `` and `` by hand.** It is + regenerated on every run. +5. **`unknown` is a valid answer.** A wrong verdict is worse than an unanswered one, because it ships + to a public issue with a confidence label attached. +6. **Do not edit `report.json`, `issue-plan.json` or anything in `out/`.** They are build artefacts. + Fix the inputs — `aliases.json`, `ignore.json`, `feasibility.json` — and rerun. + +## The pipeline + +``` +fetch.mjs ─→ diff.mjs ─→ [ PASS A: aliases ] ─→ diff.mjs ─→ feasibility.mjs + │ + [ PASS B: research ] + │ + issues.mjs + │ + [ PASS C: review ] ─→ human --apply +``` + +Passes A and B are agent work. Pass C is an agent preparing a decision for a human. + +--- + +# Pass A — alias reconciliation + +## Why this pass exists + +The two projects name the same pack differently, in ways no string algorithm resolves safely. + +Vanilla Tweaks stores `name` (a PascalCase or lowercase-spaced key) and `display` (the human label). +Bedrock Tweaks stores `id` (snake_case) and `name` (the human label). `diff.mjs` strips everything +except letters and digits before comparing, so `AlternateBlockDestruction`, +`Alternate Block Destruction` and `alternate_block_destruction` all collapse to one key and match +automatically. That handles most of the catalogue. + +It fails whenever we reworded the pack. Real cases from this repo: + +| Vanilla Tweaks | Bedrock Tweaks | Why the match failed | +| --- | --- | --- | +| `PotterySherdToShard` — "Rename 'Pottery Sherd' to 'Pottery Shard'" | `rename_pottery_sherds_to_pottery_shards` | Pluralisation | +| `ClassicSheep` — "Classic Sheep" | `classic_java_sheep` — "Classic Java Sheep" | We added a qualifier | +| `PackPngPanorama` — "pack.png Panorama" | `pack_panorama` — "Pack Panorama" | We simplified the wording | +| `blackstone cobblestone` — "Blackstone Cobblestone" | `alternate_cobblestone` — "Alternate Cobblestone" | Ours is a superset (Blackstone **and** Cobbled Deepslate) | +| `UniversalLushGrass` — "Lush Grass (Mostly) All 'Round!" | `lush_grass_all_round` — "Lush Grass All 'Round!" | We dropped a parenthetical | +| `ColoredXpBarsBrown` — "Brown Experience Bar" | `brown_xp_bar` — **"Brown Elytra"** | A typo in our own `packs.json` | + +That last row is the reason this pass is not busywork. The mismatch surfaced a live data bug on the +site. Treat every unmatched pack as either a missing port **or** a defect in our metadata. + +## Procedure + +1. Run `node tools/vt-diff/diff.mjs`, then read `out/report.json`. +2. Work through `sections[*].missing[]`. Entries with a non-empty `suggestions` array are the + likely renames — `suggestions` is a Levenshtein shortlist against our pack names, capped by + `suggestionMaxDistance` in `config.json`. +3. Also scan `sections[*].bedrockOnly[]`. A rename shows up on **both** lists: missing on one side, + unmatched on the other. Cross-referencing the two lists catches renames the distance metric + misses, such as `blackstone cobblestone` ↔ `alternate_cobblestone`. +4. For each candidate, confirm all three before writing an alias: + - the id exists in `
/packs.json`; + - a directory for it exists under `
/files/`; + - the descriptions describe the same behaviour. +5. Write the alias into `aliases.json` under the correct section. Key is the Vanilla Tweaks `name`, + value is our `id`. +6. Rerun `node tools/vt-diff/diff.mjs` and confirm both counts moved: `missing` down by one, + `bedrockOnly` down by one. + +## When it is not an alias + +- **Our pack is a superset or subset.** Still alias it, and say so in your report — the maintainer + may want the remaining coverage tracked as a separate issue. `alternate_cobblestone` covers + Blackstone plus Cobbled Deepslate, so aliasing is correct and nothing is lost. +- **Similar name, different subject.** `VariatedNylium` is not `variated_mycelium`. Different block. + Leave it missing. +- **Our metadata is wrong.** Do not paper over it with an alias. Report the defect so `packs.json` + gets fixed. `brown_xp_bar` needed both — a name fix *and* an alias, because the Vanilla Tweaks + `name` key (`ColoredXpBarsBrown`) would not match our id even after the display name was corrected. +- **Genuinely absent.** Most of the list. Leave it alone; Pass B picks it up. + +## Reporting + +Report the aliases added, the near-misses you rejected and why, and any metadata defects found. +Rejected candidates matter — they stop the next agent re-investigating the same pairs. + +--- + +# Pass B — Bedrock feasibility research + +## Why this pass exists + +Vanilla Tweaks targets Java Edition. A large share of its catalogue depends on capabilities Bedrock +resource packs do not expose, or exposes differently. Opening 116 issues that all read "port this +pack" without saying whether it is *portable* creates work for contributors and false expectations +for users. + +The output of this pass is a verdict per pack, with evidence, stored in `feasibility.json`. That +verdict drives the labels `issues.mjs` applies and a "Bedrock feasibility" section in the issue body. + +## Getting a worklist + +```sh +node tools/vt-diff/feasibility.mjs +``` + +Writes `out/feasibility-todo.md` and `out/feasibility-batches/batch-NN.json` — chunks of +`feasibility.batchSize` packs. Hand exactly one batch file to one agent. Batches are independent, so +run them in parallel; merge the results into `feasibility.json` afterwards. + +Packs already carrying a verdict other than `unknown` are excluded, so the worklist shrinks as +research lands and reruns are cheap. + +## Source hierarchy + +Work down this list. Stop at the highest tier that answers the question, and cite what you used. + +**Tier 1 — authoritative.** + +- The `microsoft-learn` MCP server (configured in the repo's `.mcp.json`, endpoint + `https://learn.microsoft.com/api/mcp`). Canonical for the add-on JSON schemas, block/entity/item + components, the Script API and resource pack structure. Prefer it over web search for anything + Microsoft documents. +- [`github.com/Mojang/bedrock-samples`](https://github.com/Mojang/bedrock-samples) — the shipped + vanilla resource and behaviour packs. The single best answer to "is this texture, model, UI file + or JSON control point actually there?" is to look for the file. Raw files are fetchable directly. + +**Tier 2 — community, high quality.** + +- [`wiki.bedrock.dev/llms.txt`](https://wiki.bedrock.dev/llms.txt) — an index of the Bedrock Wiki + written for machine consumption. Fetch it first to pick pages, then fetch the raw Markdown: + replace `https://wiki.bedrock.dev/` with + `https://raw.githubusercontent.com/Bedrock-OSS/bedrock-wiki/refs/heads/wiki/docs/` and append + `.md`. Sections most relevant here: **Visuals**, **Blocks → Sound & Visuals**, **JSON UI**, + **Particles**, **Entities → Render Controllers**, **Concepts → Shaders / Texture Atlases**, + **Text & Localization**. +- This machine's Bedrock JSON UI knowledge base, for anything touching HUD, menus, forms or + `ui_defs.json`. Its `AGENTS.md` is the routing entry point. + +**Tier 3 — corroborating only.** + +- `bugs.mojang.com` and `feedback.minecraft.net` — useful for "this is a known Bedrock limitation" + or "this is planned". Never the sole source for a `blocked` verdict. +- `minecraft.wiki` — good for confirming what the Java pack actually changes, which is often the + harder half of the question. + +Hosts outside `feasibility.trustedSourceHosts` in `config.json` are rejected by the validator. If you +need a new host, propose it to the developer rather than editing the allowlist yourself. + +## What to actually determine + +For each pack, answer in this order: + +1. **What does the Java pack change?** Read the Vanilla Tweaks description in the batch file and + look at the icon URL. If the description is ambiguous, confirm against `minecraft.wiki` what the + vanilla asset is. Getting this wrong invalidates everything downstream. +2. **Which Bedrock subsystem would have to deliver it?** Textures, block models, entity geometry, + render controllers, particles, JSON UI, fonts and glyphs, sounds, text and localization, or a + behaviour pack / Script API add-on. +3. **Does that subsystem expose the necessary control point in a resource pack?** This is the + question the sources answer. Be specific — "block models can be overridden" is not the same as + "the geometry of a *vanilla* block can be replaced by a resource pack alone". +4. **Does it need a behaviour pack?** If yes it is not a resource pack port; it belongs in + `addons`. Say so — the section may need to change. +5. **Is there a version floor or a platform caveat?** Note it in `caveats`. + +## Verdict rubric + +| Verdict | Use when | Effect | +| --- | --- | --- | +| `possible` | A resource pack (or, for `addons`, an add-on) can reproduce the effect with no meaningful loss. You can name the mechanism. | Labelled `enhancement` | +| `partial` | Reproducible but degraded, or only under conditions — a version floor, a platform gap, an approximation. | Labelled `enhancement`, `help wanted` | +| `blocked` | Bedrock does not expose the required control point. You have a source stating the limitation, or you demonstrated the asset or hook is absent from `bedrock-samples`. | Labelled `not_possible` | +| `unknown` | You could not establish it within the batch. **The correct answer when unsure.** | Labelled `enhancement`, stays on the worklist | + +`confidence` is about your evidence, not the outcome. Tier 1 source stating it outright is `high`. +Tier 2 tutorial demonstrating the technique is `medium`. Inference from adjacent facts is `low` — +and `low` confidence on a `blocked` verdict should usually be `unknown` instead. + +## Evidence standard + +`blocked` is the verdict that costs us. It tells a contributor not to try, and tells a user we will +never ship it. It requires either an explicit statement of the limitation from a Tier 1 or Tier 2 +source, or a concrete demonstration that the required file, component or binding does not exist in +`bedrock-samples`. + +"I could not find documentation showing it is possible" is **not** evidence of impossibility. That is +`unknown`. + +Bedrock's capabilities move. A verdict older than a couple of releases is a hypothesis, not a fact — +which is why `checkedAt` is mandatory. + +## Recording a verdict + +Add to `feasibility.json` under the section, keyed by the Vanilla Tweaks `name`: + +```json +"SomePackName": { + "verdict": "partial", + "confidence": "medium", + "summary": "One sentence a maintainer can act on without opening anything else.", + "mechanism": "How it would actually be built on Bedrock, naming the specific files or components — or exactly what is missing.", + "caveats": "Optional. Version floor, platform differences, what is lost versus Java.", + "sources": ["https://wiki.bedrock.dev/...", "https://learn.microsoft.com/..."], + "checkedAt": "2026-07-25", + "checkedBy": "agent" +} +``` + +Then validate: + +```sh +node tools/vt-diff/feasibility.mjs --validate +``` + +It checks the verdict enum, required prose fields, the date format, source count and source hosts. +Fix every problem before handing back. + +`summary` and `mechanism` are published verbatim into public GitHub issues. Write them for a +contributor deciding whether to pick the pack up, not as notes to yourself. + +## Batch protocol + +- One batch file per agent. Do not split a batch across agents, and do not merge batches. +- Each agent returns a JSON fragment for its packs only. The coordinating agent merges fragments + into `feasibility.json` and runs `--validate` once at the end. +- On a merge conflict for the same pack, keep the higher-confidence entry; if confidence ties, keep + the one with more Tier 1 sources. +- Report per batch: verdict counts, and every pack left `unknown` with what specifically blocked you. + +--- + +# Pass C — issue plan review + +```sh +node tools/vt-diff/issues.mjs +``` + +Read `out/issue-plan.md`, then verify before presenting it: + +1. **`reopenCandidates`** — closed as completed, yet absent from `packs.json`. Check + `
/files/` for each. Either an alias is missing (Pass A) or a port was lost. This bucket + found issue #927 "Glowier Glow": closed as done, no pack, no files. +2. **`rejected`** — closed as not planned. These are decisions already made. `--seed-ignore` copies + them into `ignore.json` with the issue number as the reason; replace those placeholder reasons + with the real rationale, and record a `blocked` verdict where one applies. +3. **`close`** — the pack now exists. Confirm the issue is a *request*, not a bug report about a + shipped pack. The filters in `config.json` (`closeRequiresLabels`, `closeExcludesLabels`) already + exclude bugs; verify the survivors anyway. +4. **`create`** — check the generated titles match the repo convention, `[Category > Sub] Pack Name`. +5. **Feasibility coverage** — the plan prints how many planned packs still have no verdict. Applying + with a large unresearched count publishes issues that say "not researched yet". Say so plainly. + +Then stop. Present counts, the verified `reopenCandidates`, and anything that looks wrong. Ask the +developer to approve. Do not apply. + +--- + +## Definition of done + +- [ ] `diff.mjs` rerun after the last `aliases.json` edit +- [ ] Every alias verified against `packs.json` **and** `
/files/` +- [ ] `feasibility.mjs --validate` exits clean +- [ ] Every `blocked` verdict carries an explicit source for the limitation +- [ ] Every `unknown` reported with the reason it stayed unknown +- [ ] `reopenCandidates` checked against the filesystem, not assumed +- [ ] Metadata defects found along the way reported separately, not silently aliased +- [ ] `--apply` **not** run diff --git a/tools/vt-diff/README.md b/tools/vt-diff/README.md new file mode 100644 index 000000000..65724e85a --- /dev/null +++ b/tools/vt-diff/README.md @@ -0,0 +1,123 @@ +# vt-diff + +Parity tracker between [Vanilla Tweaks](https://vanillatweaks.net) and Bedrock Tweaks. + +It answers three questions on demand: + +1. Which Vanilla Tweaks packs do we not ship yet? +2. Which of those are actually buildable on Bedrock? +3. Are the GitHub issues that track them up to date? + +A developer starts it. Scripts do the mechanical work; agents do the two passes that need judgement +— reconciling renamed packs and researching Bedrock feasibility — and a human performs the final +apply. **The agent procedure is [AGENTS.md](./AGENTS.md); read it before running an agent against +this tool.** + +Nothing is written to GitHub unless you pass `--apply`. + +## Usage + +```sh +node tools/vt-diff/fetch.mjs # download the Vanilla Tweaks catalogs into .cache/ +node tools/vt-diff/diff.mjs # write out/report.json and out/report.md +node tools/vt-diff/feasibility.mjs # write the research worklist and per-agent batch files +node tools/vt-diff/issues.mjs # write out/issue-plan.json and out/issue-plan.md (dry run) + +node tools/vt-diff/issues.mjs --apply # create, update and close issues +node tools/vt-diff/issues.mjs --seed-ignore # copy "closed as not planned" packs into ignore.json +node tools/vt-diff/feasibility.mjs --validate # check every recorded verdict +node tools/vt-diff/diff.mjs --section=addons # limit the diff to one section +``` + +Or via yarn: `yarn vt:diff`, `yarn vt:feasibility`, `yarn vt:issues`. + +`fetch.mjs`, `diff.mjs` and `feasibility.mjs` need no credentials. `issues.mjs` reads issues through +`gh` when it is authenticated and falls back to the public GitHub REST API otherwise, so dry runs +always work. `--apply` requires `gh auth login`. + +`.cache/` and `out/` are ignored by git. Everything else in this directory is checked in. + +## The full loop + +``` +fetch ─→ diff ─→ [agent: aliases] ─→ diff ─→ feasibility ─→ [agent: research] ─→ issues ─→ [human: --apply] +``` + +## How packs are matched + +A Vanilla Tweaks pack is considered shipped when any of these resolve to a pack in `packs.json`: + +1. an explicit entry in `aliases.json`, +2. the Vanilla Tweaks `name` compared against our `id` or `name`, +3. the Vanilla Tweaks `display` compared against our `id` or `name`. + +Comparison strips everything except letters and digits, so `AlternateBlockDestruction`, +`Alternate Block Destruction` and `alternate_block_destruction` are the same key. + +Vanilla Tweaks category trails map onto our category ids by slugging each segment and joining with +`/` — `GUI > Crosshairs` becomes `gui/crosshairs`. Matched packs sitting in a different category are +reported as **category drift**. + +## The three files you maintain + +`aliases.json` — a pack we already ship under a different name. Add an entry whenever the report +lists something as missing that you know exists. Most packs need one: the two projects use different +id formats and often different wording, so automatic matching only carries the identically-named +majority. See [AGENTS.md](./AGENTS.md#pass-a--alias-reconciliation) for the failure classes and the +verification each alias requires. + +`ignore.json` — a pack that will never be ported, with the reason. `--seed-ignore` populates this +from issues closed as *not planned*. + +`feasibility.json` — the Bedrock feasibility verdict per pack, with sources. Populated by the agent +research pass. Drives issue labels and the feasibility section of every managed issue body. +`feasibility.mjs --validate` rejects entries that are unsourced, undated or use an untrusted host. + +All three are committed so the whole team shares one answer. + +## Feasibility verdicts + +| Verdict | Meaning | Labels applied | +| --- | --- | --- | +| `possible` | Buildable on Bedrock with no meaningful loss | `enhancement` | +| `partial` | Buildable but degraded or conditional | `enhancement`, `help wanted` | +| `blocked` | Bedrock does not expose what it needs | `not_possible` | +| `unknown` | Not researched, or research was inconclusive | `enhancement` | + +Configured under `feasibility.verdictLabels` in `config.json`. `feasibility.skipCreateVerdicts` +controls which verdicts are excluded from issue creation entirely — empty by default, so `blocked` +packs still get a documented issue explaining why. + +## Report buckets + +| Bucket | Meaning | +| --- | --- | +| `missing` | On Vanilla Tweaks, not on Bedrock Tweaks, not ignored | +| `matched` | Shipped on both | +| `bedrockOnly` | Our own packs, no Vanilla Tweaks equivalent | +| `ignored` | Listed in `ignore.json` | +| `categoryDrift` | Shipped, but filed under a different category than Vanilla Tweaks | + +## Issue plan buckets + +| Bucket | `--apply` behaviour | +| --- | --- | +| `create` | Opens an issue titled `[Category > Sub] Pack Name` with verdict-derived labels | +| `update` | Refreshes the managed block in an open issue and adds any missing labels | +| `close` | Closes an open `enhancement` issue whose pack now exists | +| `skipped` | Not created, because its verdict is in `skipCreateVerdicts` | +| `reopenCandidates` | **Report only** — closed as completed, yet still absent from `packs.json` | +| `rejected` | **Report only** — closed as not planned; feed into `ignore.json` | + +Managed issue bodies carry a block delimited by `` and `` +containing a `` marker. The marker is what makes reruns idempotent — +text outside the block is never touched. + +## Bumping the Vanilla Tweaks version + +Edit `vanillaTweaks.version` in `config.json`, then rerun `fetch.mjs`. Live versions can be probed +directly: + +```sh +curl -o /dev/null -w '%{http_code}\n' https://vanillatweaks.net/assets/resources/json/26.2/rpcategories.json +``` diff --git a/tools/vt-diff/aliases.json b/tools/vt-diff/aliases.json new file mode 100644 index 000000000..957d0569d --- /dev/null +++ b/tools/vt-diff/aliases.json @@ -0,0 +1,18 @@ +{ + "$comment": "Manual overrides where a Vanilla Tweaks pack ships under a different name on Bedrock Tweaks. Keys are Vanilla Tweaks pack `name` values, values are Bedrock Tweaks pack ids. Add an entry whenever the diff reports a pack as missing that we already ship under another name.", + "resource_packs": { + "ClassicSheep": "classic_java_sheep", + "KindaClassicSheep": "kinda_classic_java_sheep", + "PackPngPanorama": "pack_panorama", + "PotterySherdToShard": "rename_pottery_sherds_to_pottery_shards", + "ColoredXpBarsBrown": "brown_xp_bar", + "UniversalLushGrass": "lush_grass_all_round", + "DirtPanoramaOverlay": "dirt_background", + "SGAToEnglish": "english_enchanting_table_translation" + }, + "addons": {}, + "crafting_tweaks": { + "blackstone cobblestone": "alternate_cobblestone", + "craftable notch apples": "craftable_enchanted_golden_apple" + } +} diff --git a/tools/vt-diff/config.json b/tools/vt-diff/config.json new file mode 100644 index 000000000..e68393caa --- /dev/null +++ b/tools/vt-diff/config.json @@ -0,0 +1,65 @@ +{ + "repository": "BedrockTweaks/Files", + "vanillaTweaks": { + "version": "26.2", + "catalogUrl": "https://vanillatweaks.net/assets/resources/json/{version}/{kind}categories.json", + "iconUrl": "https://vanillatweaks.net/assets/resources/icons/{iconDir}/{version}/{name}.png", + "pickerUrl": "https://vanillatweaks.net/picker/{picker}/" + }, + "sections": [ + { + "id": "resource_packs", + "name": "Resource Packs", + "vtKind": "rp", + "vtIconDir": "resourcepacks", + "vtPicker": "resource-packs", + "label": "resource_packs" + }, + { + "id": "addons", + "name": "Addons", + "vtKind": "dp", + "vtIconDir": "datapacks", + "vtPicker": "datapacks", + "label": "addons" + }, + { + "id": "crafting_tweaks", + "name": "Crafting Tweaks", + "vtKind": "ct", + "vtIconDir": "craftingtweaks", + "vtPicker": "crafting-tweaks", + "label": "crafting_tweaks" + } + ], + "issues": { + "createLabels": ["enhancement"], + "nonPackTitlePrefixes": ["update", "combination", "website", "bug", "site", "question"], + "closeRequiresLabels": ["enhancement"], + "closeExcludesLabels": ["bug", "not_possible"], + "markerStart": "", + "markerEnd": "" + }, + "suggestionMaxDistance": 4, + "feasibility": { + "batchSize": 10, + "verdicts": ["possible", "partial", "blocked", "unknown"], + "verdictLabels": { + "possible": ["enhancement"], + "partial": ["enhancement", "help wanted"], + "blocked": ["not_possible"], + "unknown": ["enhancement"] + }, + "skipCreateVerdicts": [], + "minimumSources": 1, + "trustedSourceHosts": [ + "learn.microsoft.com", + "wiki.bedrock.dev", + "raw.githubusercontent.com", + "github.com", + "bugs.mojang.com", + "feedback.minecraft.net", + "minecraft.wiki" + ] + } +} diff --git a/tools/vt-diff/diff.mjs b/tools/vt-diff/diff.mjs new file mode 100644 index 000000000..44c7487a7 --- /dev/null +++ b/tools/vt-diff/diff.mjs @@ -0,0 +1,252 @@ +import { join } from 'node:path'; + +import { + OUT_DIR, + TOOL_DIR, + config, + distance, + flattenBedrockTweaks, + flattenVanillaTweaks, + iconUrl, + norm, + pickerUrl, + readBedrockTweaks, + readCachedCatalog, + readJson, + slug, + stripHtml, + writeJson, + writeText, +} from './lib.mjs'; + +const aliases = readJson(join(TOOL_DIR, 'aliases.json')); +const ignored = readJson(join(TOOL_DIR, 'ignore.json')); + +/** + * Indexes Bedrock Tweaks packs by every key they can be matched on. + * + * @param {any[]} packs - Flattened Bedrock Tweaks packs. + * @returns {Map} Comparison key to pack. + */ +const indexBedrockTweaks = (packs) => { + const index = new Map(); + + for (const pack of packs) { + index.set(norm(pack.id), pack); + if (!index.has(norm(pack.name))) index.set(norm(pack.name), pack); + } + + return index; +}; + +/** + * Resolves a Vanilla Tweaks pack to its Bedrock Tweaks counterpart. + * + * @param {any} pack - A Vanilla Tweaks pack. + * @param {Record} sectionAliases - Alias overrides for the section. + * @param {Map} index - Bedrock Tweaks lookup index. + * @returns {{ pack: any, via: string } | null} The match, or `null` when absent. + */ +const resolve = (pack, sectionAliases, index) => { + const alias = sectionAliases[pack.name] ?? sectionAliases[pack.display]; + + if (alias) { + const aliased = index.get(norm(alias)); + + return aliased ? { pack: aliased, via: 'alias' } : null; + } + + const byName = index.get(norm(pack.name)); + if (byName) return { pack: byName, via: 'name' }; + + const byDisplay = index.get(norm(pack.display)); + if (byDisplay) return { pack: byDisplay, via: 'display' }; + + return null; +}; + +/** + * Finds close Bedrock Tweaks names for an unmatched pack, to speed up alias curation. + * + * @param {any} pack - An unmatched Vanilla Tweaks pack. + * @param {any[]} bedrockPacks - Flattened Bedrock Tweaks packs. + * @returns {any[]} Ranked suggestions. + */ +const suggest = (pack, bedrockPacks) => { + const target = norm(pack.display || pack.name); + + return bedrockPacks + .map((candidate) => ({ + id: candidate.id, + name: candidate.name, + category: candidate.category, + distance: distance(target, norm(candidate.name)), + })) + .filter((candidate) => candidate.distance <= config.suggestionMaxDistance) + .sort((a, b) => a.distance - b.distance) + .slice(0, 3); +}; + +/** + * Diffs one section of the Vanilla Tweaks catalog against Bedrock Tweaks. + * + * @param {any} section - A section entry from `config.json`. + * @returns {any} The section report. + */ +const diffSection = (section) => { + const catalog = readCachedCatalog(section); + const document = readBedrockTweaks(section); + + const vanillaPacks = flattenVanillaTweaks(catalog); + const bedrockPacks = flattenBedrockTweaks(document); + const index = indexBedrockTweaks(bedrockPacks); + + const sectionAliases = aliases[section.id] ?? {}; + const sectionIgnored = ignored[section.id] ?? {}; + const categoryIds = new Set((document.categories ?? []).map((category) => category.id)); + + const missing = []; + const matched = []; + const skipped = []; + const matchedIds = new Set(); + + for (const pack of vanillaPacks) { + const targetCategory = pack.categoryPath.map(slug).join('/'); + const reason = sectionIgnored[pack.name] ?? sectionIgnored[pack.display]; + + if (reason) { + skipped.push({ name: pack.name, display: pack.display, reason }); + continue; + } + + const match = resolve(pack, sectionAliases, index); + + if (match) { + matchedIds.add(match.pack.id); + matched.push({ + vanillaName: pack.name, + display: pack.display, + bedrockId: match.pack.id, + via: match.via, + vanillaCategory: targetCategory, + bedrockCategory: match.pack.category, + categoryDrift: targetCategory !== match.pack.category, + }); + continue; + } + + missing.push({ + name: pack.name, + display: pack.display, + description: stripHtml(pack.description), + categoryPath: pack.categoryPath, + targetCategory, + targetCategoryExists: categoryIds.has(targetCategory), + icon: iconUrl(section, pack), + picker: pickerUrl(section), + suggestions: suggest(pack, bedrockPacks), + }); + } + + const bedrockOnly = bedrockPacks + .filter((pack) => !matchedIds.has(pack.id)) + .map((pack) => ({ id: pack.id, name: pack.name, category: pack.category })); + + return { + section: section.id, + bedrockTweaksVersion: (document.version ?? []).join('.'), + counts: { + vanillaTweaks: vanillaPacks.length, + bedrockTweaks: bedrockPacks.length, + matched: matched.length, + missing: missing.length, + bedrockOnly: bedrockOnly.length, + ignored: skipped.length, + categoryDrift: matched.filter((entry) => entry.categoryDrift).length, + }, + missing, + matched, + bedrockOnly, + ignored: skipped, + }; +}; + +/** + * Renders the human-readable report. + * + * @param {any} report - The full report object. + * @returns {string} Markdown. + */ +const render = (report) => { + const lines = [ + '# Vanilla Tweaks parity report', + '', + `Vanilla Tweaks version \`${report.vanillaTweaksVersion}\` · generated \`${report.generatedAt}\``, + '', + '| Section | VT | BT | Matched | Missing | BT-only | Ignored | Category drift |', + '| --- | --: | --: | --: | --: | --: | --: | --: |', + ]; + + for (const entry of Object.values(report.sections)) { + const { counts } = entry; + + lines.push(`| \`${entry.section}\` | ${counts.vanillaTweaks} | ${counts.bedrockTweaks} | ${counts.matched} | **${counts.missing}** | ${counts.bedrockOnly} | ${counts.ignored} | ${counts.categoryDrift} |`); + } + + for (const entry of Object.values(report.sections)) { + lines.push('', `## ${entry.section} — missing (${entry.missing.length})`, ''); + + if (!entry.missing.length) lines.push('_Nothing missing._'); + + let currentCategory = null; + + for (const pack of entry.missing) { + const category = pack.categoryPath.join(' > '); + + if (category !== currentCategory) { + currentCategory = category; + lines.push('', `### ${category} → \`${pack.targetCategory}\`${pack.targetCategoryExists ? '' : ' _(category does not exist yet)_'}`, ''); + } + + const hint = pack.suggestions.length + ? ` — near: ${pack.suggestions.map((suggestion) => `\`${suggestion.id}\` (${suggestion.distance})`).join(', ')}` + : ''; + + lines.push(`- **${pack.display}** \`${pack.name}\`${hint}`); + } + + const drift = entry.matched.filter((match) => match.categoryDrift); + + if (drift.length) { + lines.push('', `### Category drift (${drift.length})`, ''); + for (const match of drift) lines.push(`- **${match.display}** — VT \`${match.vanillaCategory}\` vs BT \`${match.bedrockCategory}\``); + } + + if (entry.bedrockOnly.length) { + lines.push('', `### Bedrock Tweaks originals (${entry.bedrockOnly.length})`, ''); + for (const pack of entry.bedrockOnly) lines.push(`- **${pack.name}** \`${pack.id}\` — \`${pack.category}\``); + } + } + + return `${lines.join('\n')}\n`; +}; + +const only = process.argv.find((argument) => argument.startsWith('--section='))?.split('=')[1]; +const sections = config.sections.filter((section) => !only || section.id === only); + +const report = { + generatedAt: new Date().toISOString(), + vanillaTweaksVersion: config.vanillaTweaks.version, + sections: Object.fromEntries(sections.map((section) => [section.id, diffSection(section)])), +}; + +writeJson(join(OUT_DIR, 'report.json'), report); +writeText(join(OUT_DIR, 'report.md'), render(report)); + +for (const entry of Object.values(report.sections)) { + const { counts } = entry; + + console.log(`${entry.section.padEnd(16)} VT=${counts.vanillaTweaks} BT=${counts.bedrockTweaks} matched=${counts.matched} missing=${counts.missing} btOnly=${counts.bedrockOnly} ignored=${counts.ignored} drift=${counts.categoryDrift}`); +} + +console.log(`\nWrote ${join(OUT_DIR, 'report.json')}\nWrote ${join(OUT_DIR, 'report.md')}`); diff --git a/tools/vt-diff/feasibility.json b/tools/vt-diff/feasibility.json new file mode 100644 index 000000000..a39d9a25a --- /dev/null +++ b/tools/vt-diff/feasibility.json @@ -0,0 +1,20 @@ +{ + "$comment": "Bedrock feasibility verdicts for Vanilla Tweaks packs we do not ship. Populated by the agent research pass described in AGENTS.md. Every entry must cite at least one trusted source — `feasibility.mjs --validate` enforces it. Keys are Vanilla Tweaks pack `name` values.", + "$example": { + "SomeVanillaTweaksPackName": { + "verdict": "possible | partial | blocked | unknown", + "confidence": "high | medium | low", + "summary": "One sentence a maintainer can read without opening anything else.", + "mechanism": "How it would actually be built on Bedrock, or what specifically blocks it.", + "caveats": "Optional. Partial support, version floor, platform differences.", + "sources": [ + "https://wiki.bedrock.dev/..." + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + } + }, + "resource_packs": {}, + "addons": {}, + "crafting_tweaks": {} +} diff --git a/tools/vt-diff/feasibility.mjs b/tools/vt-diff/feasibility.mjs new file mode 100644 index 000000000..7adb37248 --- /dev/null +++ b/tools/vt-diff/feasibility.mjs @@ -0,0 +1,178 @@ +import { join } from 'node:path'; + +import { OUT_DIR, TOOL_DIR, config, readJson, writeJson, writeText } from './lib.mjs'; + +const RESERVED = new Set(['$comment', '$example']); + +const settings = config.feasibility; +const store = readJson(join(TOOL_DIR, 'feasibility.json')); + +/** + * Reads the verdict recorded for a pack, if any. + * + * @param {string} sectionId - The Bedrock Tweaks section id. + * @param {string} name - The Vanilla Tweaks pack name. + * @returns {any | null} The stored entry. + */ +export const verdictFor = (sectionId, name) => (store[sectionId] ?? {})[name] ?? null; + +/** + * Validates every stored entry. + * + * @returns {string[]} Human-readable problems, empty when the store is valid. + */ +export const validate = () => { + const problems = []; + + for (const [sectionId, entries] of Object.entries(store)) { + if (RESERVED.has(sectionId)) continue; + + if (!config.sections.some((section) => section.id === sectionId)) { + problems.push(`Unknown section "${sectionId}".`); + continue; + } + + for (const [name, entry] of Object.entries(entries)) { + const where = `${sectionId}/${name}`; + + if (!settings.verdicts.includes(entry.verdict)) + problems.push(`${where}: verdict "${entry.verdict}" is not one of ${settings.verdicts.join(', ')}.`); + + if (!entry.summary?.trim()) problems.push(`${where}: missing summary.`); + if (!entry.mechanism?.trim()) problems.push(`${where}: missing mechanism.`); + if (!['high', 'medium', 'low'].includes(entry.confidence)) problems.push(`${where}: confidence must be high, medium or low.`); + if (!/^\d{4}-\d{2}-\d{2}$/.test(entry.checkedAt ?? '')) problems.push(`${where}: checkedAt must be YYYY-MM-DD.`); + + const sources = entry.sources ?? []; + + if (entry.verdict !== 'unknown' && sources.length < settings.minimumSources) + problems.push(`${where}: needs at least ${settings.minimumSources} source(s).`); + + for (const source of sources) { + let host; + + try { + host = new URL(source).host; + } catch { + problems.push(`${where}: "${source}" is not a URL.`); + continue; + } + + if (!settings.trustedSourceHosts.some((trusted) => host === trusted || host.endsWith(`.${trusted}`))) + problems.push(`${where}: host "${host}" is not in trustedSourceHosts.`); + } + } + } + + return problems; +}; + +/** + * Lists missing packs that still need a verdict. + * + * @returns {any[]} The pending packs. + */ +const collectPending = () => { + const report = readJson(join(OUT_DIR, 'report.json')); + const pending = []; + + for (const section of config.sections) { + const entry = report.sections[section.id]; + + if (!entry) continue; + + for (const pack of entry.missing) { + const existing = verdictFor(section.id, pack.name); + + if (existing && existing.verdict !== 'unknown') continue; + + pending.push({ + section: section.id, + name: pack.name, + display: pack.display, + description: pack.description, + category: pack.categoryPath.join(' > '), + targetCategory: pack.targetCategory, + icon: pack.icon, + }); + } + } + + return pending; +}; + +/** + * Writes the research worklist and its per-agent batch files. + */ +const main = () => { + const pending = collectPending(); + const batches = []; + + for (let index = 0; index < pending.length; index += settings.batchSize) + batches.push(pending.slice(index, index + settings.batchSize)); + + batches.forEach((packs, index) => { + writeJson(join(OUT_DIR, 'feasibility-batches', `batch-${String(index + 1).padStart(2, '0')}.json`), { + batch: index + 1, + of: batches.length, + packs, + }); + }); + + const counts = {}; + + for (const [sectionId, entries] of Object.entries(store)) { + if (RESERVED.has(sectionId)) continue; + + for (const entry of Object.values(entries)) { + if (!entry?.verdict) continue; + + counts[entry.verdict] = (counts[entry.verdict] ?? 0) + 1; + } + } + + const recorded = Object.values(counts).reduce((total, count) => total + count, 0); + + const lines = [ + '# Bedrock feasibility worklist', + '', + `${pending.length} missing pack(s) have no verdict yet, split into ${batches.length} batch(es) of up to ${settings.batchSize}.`, + '', + `Recorded verdicts: ${Object.entries(counts).map(([verdict, count]) => `\`${verdict}\` ${count}`).join(' · ') || '_none yet_'}`, + '', + 'Batch files live in `out/feasibility-batches/`. Hand one file to one agent. The research procedure, the source hierarchy and the verdict rubric are in `AGENTS.md`.', + '', + ]; + + for (const [index, packs] of batches.entries()) { + lines.push(`## Batch ${index + 1}`, ''); + for (const pack of packs) lines.push(`- \`${pack.section}\` **${pack.display}** (\`${pack.name}\`) — ${pack.category} — ${pack.description}`); + lines.push(''); + } + + writeText(join(OUT_DIR, 'feasibility-todo.md'), `${lines.join('\n')}\n`); + + const problems = validate(); + + if (problems.length) { + console.error(`feasibility.json has ${problems.length} problem(s). Run with --validate for details.`); + process.exitCode = 1; + } + + console.log(`pending=${pending.length} batches=${batches.length} recorded=${recorded}`); + console.log(`Wrote ${join(OUT_DIR, 'feasibility-todo.md')}`); + console.log(`Wrote ${join(OUT_DIR, 'feasibility-batches')}/batch-NN.json`); +}; + +if (import.meta.filename === process.argv[1]) { + if (process.argv.includes('--validate')) { + const problems = validate(); + + for (const problem of problems) console.error(` ${problem}`); + + console.log(problems.length ? `\n${problems.length} problem(s) in feasibility.json.` : 'feasibility.json is valid.'); + process.exit(problems.length ? 1 : 0); + } + + main(); +} diff --git a/tools/vt-diff/fetch.mjs b/tools/vt-diff/fetch.mjs new file mode 100644 index 000000000..a9951b6fd --- /dev/null +++ b/tools/vt-diff/fetch.mjs @@ -0,0 +1,22 @@ +import { config, cachePath, catalogUrl, writeJson } from './lib.mjs'; + +/** + * Downloads every Vanilla Tweaks catalog for the configured version into `.cache/`. + */ +const main = async () => { + console.log(`Vanilla Tweaks version ${config.vanillaTweaks.version}`); + + for (const section of config.sections) { + const url = catalogUrl(section); + const response = await fetch(url); + + if (!response.ok) throw new Error(`${url} responded ${response.status}`); + + const catalog = await response.json(); + + writeJson(cachePath(section), catalog); + console.log(` ${section.vtKind} -> ${section.id}: ${JSON.stringify(catalog).length} bytes`); + } +}; + +await main(); diff --git a/tools/vt-diff/ignore.json b/tools/vt-diff/ignore.json new file mode 100644 index 000000000..d14d503a6 --- /dev/null +++ b/tools/vt-diff/ignore.json @@ -0,0 +1,39 @@ +{ + "$comment": "Vanilla Tweaks packs that will never be ported. Keys are Vanilla Tweaks pack `name` values, values are the reason. These are excluded from the missing list and from issue creation.", + "resource_packs": { + "WarmGlow": "Closed as not planned in BedrockTweaks/Files#5", + "EndlessEndRods": "Closed as not planned in BedrockTweaks/Files#6", + "AnimatedCampfireItem": "Closed as not planned in BedrockTweaks/Files#7", + "MossCarpetOverhang": "Closed as not planned in BedrockTweaks/Files#10", + "BushyLeaves": "Closed as not planned in BedrockTweaks/Files#15", + "WavyLeaves": "Closed as not planned in BedrockTweaks/Files#16", + "WavyPlants": "Closed as not planned in BedrockTweaks/Files#17", + "WavyWater": "Closed as not planned in BedrockTweaks/Files#18", + "TwinklingStars": "Closed as not planned in BedrockTweaks/Files#20", + "TallerSunflowers": "Closed as not planned in BedrockTweaks/Files#21", + "RandomCoarseDirtRotation": "Closed as not planned in BedrockTweaks/Files#22", + "VariatedNylium": "Closed as not planned in BedrockTweaks/Files#324", + "RandomSunflowerRotation": "Closed as not planned in BedrockTweaks/Files#23", + "DiminishingTools": "Closed as not planned in BedrockTweaks/Files#30", + "UniquePaintingItems": "Closed as not planned in BedrockTweaks/Files#550", + "UniqueAxolotlBuckets": "Closed as not planned in BedrockTweaks/Files#551", + "MobSpawnIndicator": "Closed as not planned in BedrockTweaks/Files#31", + "DirectionalDispensersDroppers": "Closed as not planned in BedrockTweaks/Files#37", + "GroovyLevers": "Closed as not planned in BedrockTweaks/Files#38", + "VisualCauldronStages": "Closed as not planned in BedrockTweaks/Files#39", + "VisualComposterStages": "Closed as not planned in BedrockTweaks/Files#40", + "VisualSaplingGrowth": "Closed as not planned in BedrockTweaks/Files#41", + "NoteblockBanners": "Closed as not planned in BedrockTweaks/Files#42", + "NoBeaconBeam": "Closed as not planned in BedrockTweaks/Files#45", + "OldAlexSteve": "Closed as not planned in BedrockTweaks/Files#56", + "HardcoreDarkness": "Closed as not planned in BedrockTweaks/Files#57", + "SpinningBurningSkullPainting": "Closed as not planned in BedrockTweaks/Files#58", + "DungeonsAlexSteve": "Closed as not planned in BedrockTweaks/Files#161" + }, + "addons": { + "player head drops": "Closed as not planned in BedrockTweaks/Files#442", + "unlock all recipes": "Closed as not planned in BedrockTweaks/Files#463", + "custom villager shops": "Closed as not planned in BedrockTweaks/Files#490" + }, + "crafting_tweaks": {} +} diff --git a/tools/vt-diff/issues.mjs b/tools/vt-diff/issues.mjs new file mode 100644 index 000000000..a30db6584 --- /dev/null +++ b/tools/vt-diff/issues.mjs @@ -0,0 +1,472 @@ +import { execFileSync } from 'node:child_process'; +import { existsSync } from 'node:fs'; +import { join } from 'node:path'; + +import { OUT_DIR, TOOL_DIR, config, norm, readJson, writeJson, writeText } from './lib.mjs'; +import { verdictFor } from './feasibility.mjs'; + +const GH_CANDIDATES = [ + process.env.GH_BIN, + 'gh', + 'C:/Program Files/GitHub CLI/gh.exe', + `${process.env.LOCALAPPDATA}/Programs/GitHub CLI/gh.exe`, +].filter(Boolean); + +/** + * Locates a usable `gh` executable. + * + * @returns {string | null} The command or absolute path, or `null` when unavailable. + */ +const resolveGh = () => { + for (const candidate of GH_CANDIDATES) { + try { + if (candidate.includes('/') && !existsSync(candidate)) continue; + + execFileSync(candidate, ['--version'], { stdio: 'ignore' }); + + return candidate; + } catch { + continue; + } + } + + return null; +}; + +const gh = resolveGh(); +const apply = process.argv.includes('--apply'); + +/** + * Reports whether gh is installed and authenticated. + * + * @returns {boolean} True when gh can be used. + */ +const ghReady = () => { + if (!gh) return false; + + try { + execFileSync(gh, ['auth', 'status'], { stdio: 'ignore' }); + + return true; + } catch { + return false; + } +}; + +const authenticated = ghReady(); + +if (apply && !authenticated) + throw new Error(gh + ? 'gh is installed but not authenticated. Run: gh auth login' + : 'gh CLI not found. Install it, then run: gh auth login'); + +/** + * Runs a gh command and returns stdout. + * + * @param {string[]} args - Arguments passed to gh. + * @returns {string} Standard output. + */ +const run = (args) => execFileSync(gh, args, { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 }); + +/** + * Reads every issue, preferring gh and falling back to the public REST API for dry runs. + * + * @returns {Promise} The issues. + */ +const loadIssues = async () => { + if (authenticated) return JSON.parse(run([ + 'issue', 'list', + '--repo', config.repository, + '--state', 'all', + '--limit', '2000', + '--json', 'number,title,body,state,stateReason,labels,url', + ])); + + console.log(' gh unavailable or unauthenticated — falling back to the public REST API (read only).'); + + const collected = []; + + for (let page = 1; page <= 20; page++) { + const url = `https://api.github.com/repos/${config.repository}/issues?state=all&per_page=100&page=${page}`; + const response = await fetch(url, { headers: { Accept: 'application/vnd.github+json' } }); + + if (!response.ok) throw new Error(`${url} responded ${response.status}`); + + const batch = await response.json(); + + collected.push(...batch.filter((issue) => !issue.pull_request)); + + if (batch.length < 100) break; + } + + return collected.map((issue) => ({ + number: issue.number, + title: issue.title, + body: issue.body ?? '', + state: issue.state.toUpperCase(), + stateReason: issue.state_reason ?? null, + labels: issue.labels.map((label) => ({ name: label.name })), + url: issue.html_url, + })); +}; + +/** + * Splits an issue title into its bracketed prefix and pack name. + * + * @param {string} title - The issue title. + * @returns {{ prefix: string, name: string }} The parsed parts. + */ +const parseTitle = (title) => { + const match = /^\s*\[([^\]]+)\]\s*(.+?)\s*$/.exec(title ?? ''); + + return match ? { prefix: match[1].trim(), name: match[2].trim() } : { prefix: '', name: (title ?? '').trim() }; +}; + +/** + * Builds the machine-readable marker embedded in every managed issue body. + * + * @param {any} section - A section entry from `config.json`. + * @param {any} pack - A missing Vanilla Tweaks pack. + * @returns {string} The marker comment. + */ +const packMarker = (section, pack) => ``; + +/** + * Renders the managed block appended to (or refreshed inside) an issue body. + * + * @param {any} section - A section entry from `config.json`. + * @param {any} pack - A missing Vanilla Tweaks pack. + * @returns {string} The block, including its markers. + */ +const renderBlock = (section, pack) => { + const verdict = verdictFor(section.id, pack.name); + + const lines = [ + config.issues.markerStart, + '### Vanilla Tweaks reference', + '', + '| | |', + '| --- | --- |', + `| Pack | **${pack.display}** (\`${pack.name}\`) |`, + `| Section | ${section.name} |`, + `| Vanilla Tweaks category | ${pack.categoryPath.join(' > ')} |`, + `| Bedrock Tweaks category | \`${pack.targetCategory}\`${pack.targetCategoryExists ? '' : ' — **does not exist yet**'} |`, + `| Picker | ${pack.picker} |`, + `| Version | \`${config.vanillaTweaks.version}\` |`, + '', + `> ${pack.description || '_No description._'}`, + '', + `${pack.display}`, + ]; + + if (verdict) { + lines.push( + '', + '### Bedrock feasibility', + '', + '| | |', + '| --- | --- |', + `| Verdict | **${verdict.verdict}** (${verdict.confidence} confidence) |`, + `| Checked | ${verdict.checkedAt} by ${verdict.checkedBy} |`, + '', + verdict.summary, + '', + `**How it would work on Bedrock.** ${verdict.mechanism}`, + ); + + if (verdict.caveats) lines.push('', `**Caveats.** ${verdict.caveats}`); + + lines.push('', '
Sources', ''); + for (const source of verdict.sources ?? []) lines.push(`- ${source}`); + lines.push('', '
'); + } else { + lines.push('', '### Bedrock feasibility', '', '_Not researched yet._'); + } + + lines.push( + '', + 'Maintained by `tools/vt-diff`. Edits inside this block are overwritten on the next run.', + packMarker(section, pack), + config.issues.markerEnd, + ); + + return lines.join('\n'); +}; + +/** + * Resolves the labels an issue should carry for a pack, based on its feasibility verdict. + * + * @param {any} section - A section entry from `config.json`. + * @param {any} pack - A missing Vanilla Tweaks pack. + * @returns {string[]} The label names. + */ +const labelsFor = (section, pack) => { + const verdict = verdictFor(section.id, pack.name)?.verdict ?? 'unknown'; + const fromVerdict = config.feasibility.verdictLabels[verdict] ?? config.issues.createLabels; + + return [...new Set([...fromVerdict, section.label])]; +}; + +/** + * Replaces the managed block in a body, or appends it when absent. + * + * @param {string} body - The existing issue body. + * @param {string} block - The rendered block. + * @returns {string} The updated body. + */ +const applyBlock = (body, block) => { + const start = body.indexOf(config.issues.markerStart); + const end = body.indexOf(config.issues.markerEnd); + + if (start !== -1 && end !== -1 && end > start) + return `${body.slice(0, start)}${block}${body.slice(end + config.issues.markerEnd.length)}`.trim(); + + return `${body.trim()}\n\n${block}`.trim(); +}; + +const report = readJson(join(OUT_DIR, 'report.json')); + +console.log(`Fetching issues from ${config.repository} ...`); + +const issues = await loadIssues(); + +console.log(` ${issues.length} issues (${issues.filter((issue) => issue.state === 'OPEN').length} open)`); + +const byMarker = new Map(); +const byName = new Map(); + +for (const issue of issues) { + const marker = //.exec(issue.body ?? ''); + + if (marker) byMarker.set(marker[1], issue); + + const key = norm(parseTitle(issue.title).name); + + if (!byName.has(key)) byName.set(key, []); + byName.get(key).push(issue); +}; + +const plan = { create: [], update: [], close: [], skipped: [], reopenCandidates: [], rejected: [], upToDate: [] }; + +for (const section of config.sections) { + const entry = report.sections[section.id]; + + if (!entry) continue; + + for (const pack of entry.missing) { + const marker = `${section.vtKind}/${pack.name}`; + const candidates = byMarker.has(marker) + ? [byMarker.get(marker)] + : (byName.get(norm(pack.display)) ?? byName.get(norm(pack.name)) ?? []); + + const open = candidates.filter((issue) => issue.state === 'OPEN'); + const block = renderBlock(section, pack); + + const verdict = verdictFor(section.id, pack.name)?.verdict ?? 'unknown'; + + if (!candidates.length) { + if (config.feasibility.skipCreateVerdicts.includes(verdict)) { + plan.skipped.push({ section: section.id, pack: pack.name, display: pack.display, verdict }); + continue; + } + + plan.create.push({ + section: section.id, + pack: pack.name, + title: `[${pack.categoryPath.join(' > ')}] ${pack.display}`, + labels: labelsFor(section, pack), + verdict, + body: block, + }); + continue; + } + + if (!open.length) { + const entryFor = (issue) => ({ + section: section.id, + pack: pack.name, + display: pack.display, + number: issue.number, + title: issue.title, + url: issue.url, + stateReason: issue.stateReason ?? null, + }); + + for (const issue of candidates) + // Closed as "not planned" is a deliberate rejection; closed as completed while the pack is still + // absent from packs.json means either an alias is missing or the port silently regressed. + (issue.stateReason === 'not_planned' ? plan.rejected : plan.reopenCandidates).push(entryFor(issue)); + + continue; + } + + for (const issue of open) { + const body = applyBlock(issue.body ?? '', block); + const existing = issue.labels.map((label) => label.name); + const addLabels = labelsFor(section, pack).filter((label) => !existing.includes(label)); + const bodyChanged = body.trim() !== (issue.body ?? '').trim(); + + if (!bodyChanged && !addLabels.length) { + plan.upToDate.push({ number: issue.number, title: issue.title }); + continue; + } + + plan.update.push({ + section: section.id, + pack: pack.name, + number: issue.number, + title: issue.title, + url: issue.url, + verdict, + addLabels, + bodyChanged, + body, + }); + } + } + + const shipped = new Set(entry.matched.map((match) => norm(match.display))); + + for (const issue of issues) { + if (issue.state !== 'OPEN') continue; + + const { prefix, name } = parseTitle(issue.title); + + const labels = issue.labels.map((label) => label.name); + + if (config.issues.nonPackTitlePrefixes.includes(prefix.toLowerCase())) continue; + if (!labels.includes(section.label)) continue; + if (!config.issues.closeRequiresLabels.every((label) => labels.includes(label))) continue; + if (config.issues.closeExcludesLabels.some((label) => labels.includes(label))) continue; + if (!shipped.has(norm(name))) continue; + if (plan.close.some((candidate) => candidate.number === issue.number)) continue; + + plan.close.push({ section: section.id, number: issue.number, title: issue.title, url: issue.url, labels }); + } +} + +const planned = [...plan.create, ...plan.update]; +const researched = planned.filter((item) => item.verdict && item.verdict !== 'unknown').length; +const unresearched = planned.length - researched; + +const lines = [ + '# Vanilla Tweaks issue plan', + '', + `Repository \`${config.repository}\` · Vanilla Tweaks \`${config.vanillaTweaks.version}\` · report generated \`${report.generatedAt}\``, + '', + `- **Create**: ${plan.create.length}`, + `- **Update** (add or refresh reference block): ${plan.update.length}`, + `- **Close** (pack now shipped): ${plan.close.length}`, + `- **Closed as completed but still missing** (alias gap or regression): ${plan.reopenCandidates.length}`, + `- **Closed as not planned** (candidates for \`ignore.json\`): ${plan.rejected.length}`, + `- Skipped by feasibility verdict: ${plan.skipped.length}`, + `- Already up to date: ${plan.upToDate.length}`, + '', + `Feasibility coverage: ${researched} of ${researched + unresearched} planned packs have a verdict.${unresearched ? ` Run \`node tools/vt-diff/feasibility.mjs\` and complete the research pass before applying.` : ''}`, + '', + 'Only **Create**, **Update** and **Close** are executed by `--apply`. The two closed-issue buckets are reports for a human.', + '', + 'Run `node tools/vt-diff/issues.mjs --apply` to execute.', +]; + +if (plan.close.length) { + lines.push('', '## Close — pack now exists in packs.json', ''); + for (const item of plan.close) lines.push(`- #${item.number} ${item.title} — ${item.url}`); +} + +if (plan.reopenCandidates.length) { + lines.push('', '## Closed as completed, yet still missing from packs.json', '', 'Either `aliases.json` needs an entry, or the pack was never actually shipped.', ''); + for (const item of plan.reopenCandidates) + lines.push(`- **${item.display}** (\`${item.pack}\`) → #${item.number} ${item.title} — ${item.url}`); +} + +if (plan.rejected.length) { + lines.push('', '## Closed as not planned', '', 'Add these to `ignore.json` with a reason so they stop appearing as missing.', ''); + for (const item of plan.rejected) + lines.push(`- **${item.display}** (\`${item.pack}\`) → #${item.number} — ${item.url}`); +} + +if (plan.update.length) { + lines.push('', '## Update', ''); + for (const item of plan.update) { + const changes = [item.bodyChanged ? 'body' : null, item.addLabels.length ? `labels +${item.addLabels.join(' +')}` : null].filter(Boolean); + + lines.push(`- #${item.number} ${item.title} — ${changes.join(', ')} — verdict \`${item.verdict}\``); + } +} + +if (plan.create.length) { + lines.push('', '## Create', ''); + for (const item of plan.create) lines.push(`- \`${item.section}\` **${item.title}** — labels: ${item.labels.join(', ')} — verdict \`${item.verdict}\``); +} + +if (plan.skipped.length) { + lines.push('', '## Skipped by feasibility verdict', ''); + for (const item of plan.skipped) lines.push(`- **${item.display}** (\`${item.pack}\`) — verdict \`${item.verdict}\``); +} + +writeJson(join(OUT_DIR, 'issue-plan.json'), plan); +writeText(join(OUT_DIR, 'issue-plan.md'), `${lines.join('\n')}\n`); + +console.log(`\ncreate=${plan.create.length} update=${plan.update.length} close=${plan.close.length} skipped=${plan.skipped.length} reopenCandidates=${plan.reopenCandidates.length} rejected=${plan.rejected.length} upToDate=${plan.upToDate.length}`); +console.log(`feasibility: ${researched} researched, ${unresearched} still unknown`); +console.log(`Wrote ${join(OUT_DIR, 'issue-plan.json')}\nWrote ${join(OUT_DIR, 'issue-plan.md')}`); + +if (process.argv.includes('--seed-ignore')) { + const path = join(TOOL_DIR, 'ignore.json'); + const current = readJson(path); + let added = 0; + + for (const item of plan.rejected) { + const bucket = current[item.section] ??= {}; + + if (bucket[item.pack]) continue; + + bucket[item.pack] = `Closed as not planned in ${config.repository}#${item.number}`; + added++; + } + + writeJson(path, current); + console.log(`\nSeeded ${added} entries into ignore.json. Review the reasons, then re-run diff.mjs.`); +} + +if (!apply) { + console.log('\nDry run. Nothing was sent to GitHub. Re-run with --apply to execute.'); + process.exit(0); +} + +console.log('\nApplying ...'); + +for (const item of plan.update) { + const path = join(OUT_DIR, 'bodies', `update-${item.number}.md`); + const args = ['issue', 'edit', String(item.number), '--repo', config.repository]; + + if (item.bodyChanged) { + writeText(path, item.body); + args.push('--body-file', path); + } + + for (const label of item.addLabels) args.push('--add-label', label); + + run(args); + console.log(` updated #${item.number}${item.addLabels.length ? ` (+${item.addLabels.join(' +')})` : ''}`); +} + +for (const item of plan.create) { + const path = join(OUT_DIR, 'bodies', `create-${item.section}-${norm(item.pack)}.md`); + + writeText(path, item.body); + + const args = ['issue', 'create', '--repo', config.repository, '--title', item.title, '--body-file', path]; + + for (const label of item.labels) args.push('--label', label); + + console.log(` created ${run(args).trim()}`); +} + +for (const item of plan.close) { + run(['issue', 'close', String(item.number), '--repo', config.repository, '--comment', 'This pack is now available on Bedrock Tweaks. Closed automatically by `tools/vt-diff`.']); + console.log(` closed #${item.number}`); +} + +console.log('\nDone.'); diff --git a/tools/vt-diff/lib.mjs b/tools/vt-diff/lib.mjs new file mode 100644 index 000000000..e4580e391 --- /dev/null +++ b/tools/vt-diff/lib.mjs @@ -0,0 +1,199 @@ +import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +export const TOOL_DIR = dirname(fileURLToPath(import.meta.url)); +export const REPO_DIR = join(TOOL_DIR, '..', '..'); +export const CACHE_DIR = join(TOOL_DIR, '.cache'); +export const OUT_DIR = join(TOOL_DIR, 'out'); + +/** + * Reads and parses a JSON file. + * + * @param {string} path - Absolute path to the file. + * @returns {any} The parsed contents. + */ +export const readJson = (path) => JSON.parse(readFileSync(path, 'utf8')); + +/** + * Writes a value as tab-indented JSON, creating parent directories as needed. + * + * @param {string} path - Absolute path to the file. + * @param {any} data - The value to serialise. + */ +export const writeJson = (path, data) => { + mkdirSync(dirname(path), { recursive: true }); + writeFileSync(path, `${JSON.stringify(data, null, '\t')}\n`); +}; + +/** + * Writes a text file, creating parent directories as needed. + * + * @param {string} path - Absolute path to the file. + * @param {string} text - The contents to write. + */ +export const writeText = (path, text) => { + mkdirSync(dirname(path), { recursive: true }); + writeFileSync(path, text); +}; + +export const config = readJson(join(TOOL_DIR, 'config.json')); + +/** + * Collapses a pack name into a comparison key: lowercase, alphanumerics only. + * + * @param {unknown} value - The name to normalise. + * @returns {string} The comparison key. + */ +export const norm = (value) => String(value ?? '').toLowerCase().replace(/[^a-z0-9]/g, ''); + +/** + * Converts a Vanilla Tweaks display category into a Bedrock Tweaks category id. + * + * @param {unknown} value - The display category name. + * @returns {string} The category id. + */ +export const slug = (value) => String(value ?? '') + .toLowerCase() + .replace(/['’]/g, '') + .replace(/&/g, 'and') + .replace(/[^a-z0-9+]+/g, '_') + .replace(/^_+|_+$/g, ''); + +/** + * Removes HTML markup from a Vanilla Tweaks description. + * + * @param {unknown} value - The raw description. + * @returns {string} Plain text. + */ +export const stripHtml = (value) => String(value ?? '') + .replace(/<[^>]*>/g, ' ') + .replace(/ /g, ' ') + .replace(/\s+/g, ' ') + .trim(); + +/** + * Levenshtein distance between two strings, used only to suggest alias candidates. + * + * @param {string} a - First string. + * @param {string} b - Second string. + * @returns {number} The edit distance. + */ +export const distance = (a, b) => { + if (a === b) return 0; + if (!a.length || !b.length) return Math.max(a.length, b.length); + + let previous = Array.from({ length: b.length + 1 }, (_, index) => index); + + for (let i = 1; i <= a.length; i++) { + const current = [i]; + + for (let j = 1; j <= b.length; j++) { + current[j] = Math.min( + previous[j] + 1, + current[j - 1] + 1, + previous[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1), + ); + } + + previous = current; + } + + return previous[b.length]; +}; + +/** + * Flattens a Vanilla Tweaks catalog into a list of packs carrying their category trail. + * + * @param {any} catalog - A parsed `{kind}categories.json` document. + * @returns {any[]} The flattened packs. + */ +export const flattenVanillaTweaks = (catalog) => { + const packs = []; + + const walk = (node, trail) => { + const categoryPath = [...trail, node.category]; + + for (const pack of node.packs ?? []) packs.push({ ...pack, categoryPath }); + for (const child of node.categories ?? []) walk(child, categoryPath); + }; + + for (const node of catalog.categories ?? []) walk(node, []); + + return packs; +}; + +/** + * Flattens a Bedrock Tweaks `packs.json` into a list of packs carrying their category id. + * + * @param {any} document - A parsed `packs.json` document. + * @returns {any[]} The flattened packs. + */ +export const flattenBedrockTweaks = (document) => { + const packs = []; + + for (const category of document.categories ?? []) + for (const pack of category.packs ?? []) packs.push({ ...pack, category: category.id }); + + return packs; +}; + +/** + * Builds the Vanilla Tweaks catalog URL for a section. + * + * @param {any} section - A section entry from `config.json`. + * @returns {string} The catalog URL. + */ +export const catalogUrl = (section) => config.vanillaTweaks.catalogUrl + .replace('{version}', config.vanillaTweaks.version) + .replace('{kind}', section.vtKind); + +/** + * Builds the Vanilla Tweaks icon URL for a pack. + * + * @param {any} section - A section entry from `config.json`. + * @param {any} pack - A Vanilla Tweaks pack. + * @returns {string} The icon URL. + */ +export const iconUrl = (section, pack) => config.vanillaTweaks.iconUrl + .replace('{iconDir}', section.vtIconDir) + .replace('{version}', config.vanillaTweaks.version) + .replace('{name}', encodeURIComponent(pack.name)); + +/** + * Builds the Vanilla Tweaks picker URL for a section. + * + * @param {any} section - A section entry from `config.json`. + * @returns {string} The picker URL. + */ +export const pickerUrl = (section) => config.vanillaTweaks.pickerUrl.replace('{picker}', section.vtPicker); + +/** + * Path to a cached Vanilla Tweaks catalog for the configured version. + * + * @param {any} section - A section entry from `config.json`. + * @returns {string} The cache file path. + */ +export const cachePath = (section) => join(CACHE_DIR, `${config.vanillaTweaks.version}-${section.vtKind}.json`); + +/** + * Loads a cached catalog, failing with a clear message when `fetch.mjs` has not run. + * + * @param {any} section - A section entry from `config.json`. + * @returns {any} The parsed catalog. + */ +export const readCachedCatalog = (section) => { + const path = cachePath(section); + + if (!existsSync(path)) throw new Error(`Missing cache for "${section.id}". Run: node tools/vt-diff/fetch.mjs`); + + return readJson(path); +}; + +/** + * Loads a Bedrock Tweaks `packs.json` for a section. + * + * @param {any} section - A section entry from `config.json`. + * @returns {any} The parsed document. + */ +export const readBedrockTweaks = (section) => readJson(join(REPO_DIR, section.id, 'packs.json')); From 9291bd62573a3f9eebb0e7684ef0e870a6466060 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sat, 25 Jul 2026 10:09:02 +0200 Subject: [PATCH 3/7] Add new entries to ignore.json for colored inventory and widget variations - Added entries for colored inventories (Gray, Black, Brown, Red, Orange, Yellow, Lime, Green, Cyan, Light Blue, Blue, Purple, Magenta, Pink) indicating their status as experimental in Vanilla Tweaks. - Added corresponding entries for colored widgets, explaining the limitations of Bedrock's UI and the status of colored tooltips. --- tools/vt-diff/feasibility.json | 2659 +++++++++++++++++++++++++++++++- tools/vt-diff/ignore.json | 30 +- 2 files changed, 2685 insertions(+), 4 deletions(-) diff --git a/tools/vt-diff/feasibility.json b/tools/vt-diff/feasibility.json index a39d9a25a..afe193cdf 100644 --- a/tools/vt-diff/feasibility.json +++ b/tools/vt-diff/feasibility.json @@ -14,7 +14,2660 @@ "checkedBy": "agent" } }, - "resource_packs": {}, - "addons": {}, - "crafting_tweaks": {} + "resource_packs": { + "PalerPaleOak": { + "verdict": "possible", + "confidence": "high", + "summary": "Pure texture recolour of an existing Bedrock block set - drop desaturated PNGs at the vanilla pale oak paths, no JSON required.", + "mechanism": "Bedrock ships every pale oak texture: `textures/terrain_texture.json` defines `pale_oak_planks`, `pale_oak_log_side`, `pale_oak_log_top`, `stripped_pale_oak_log_side/top`, `pale_oak_door_top/bottom`, `pale_oak_trapdoor` and `pale_oak_shelf`, all pointing at `textures/blocks/*.png`. Textures are overwritten by path (the pack simply places a file at the same path), so the port is a set of desaturated PNGs under `textures/blocks/`, plus the matching item icons under `textures/items/` (pale oak door, sign, boat) if the Java pack recolours those too. No `blocks.json` or `terrain_texture.json` edit is needed.", + "caveats": "Pale oak/Pale Garden requires Bedrock 1.21.50+. Bedrock splits some wood textures differently from Java (e.g. `pale_oak_shelf` exists as its own texture), so the file list must be taken from Bedrock's `terrain_texture.json` rather than copied from the Java pack.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/terrain_texture.json", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "FencierFences": { + "verdict": "possible", + "confidence": "medium", + "summary": "Doable by pointing the vanilla fence and fence gate blocks at new, pre-rotated plank texture shortnames in `blocks.json` + `terrain_texture.json`.", + "mechanism": "In Bedrock's `blocks.json` every fence reuses the plank shortname (`oak_fence` -> `oak_planks`, `pale_oak_fence` -> `pale_oak_planks`, `oak_fence_gate` -> `wood_oak`, ...). A resource pack ships its own `blocks.json` that repoints each `*_fence` / `*_fence_gate` entry at a new shortname (e.g. `oak_fence_vertical`), defines those shortnames in `textures/terrain_texture.json`, and supplies plank PNGs rotated 90 degrees under `textures/blocks/`. This is the same vanilla-block `blocks.json` rewrite Bedrock Tweaks already uses in `variated_planks`, so the technique is proven in this repo.", + "caveats": "Bedrock applies one texture to all faces of a block, so the top face of a fence post and the ends of a gate also get the rotated planks (Java can rotate UVs per face). Bamboo and nether brick fences already use their own textures and need no change.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/blocks.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/terrain_texture.json", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "HorizontalWorldBorder": { + "verdict": "blocked", + "confidence": "medium", + "summary": "Bedrock has no world border at all, so there is no texture to retexture.", + "mechanism": "Nothing to hook. The world border is a Java Edition exclusive feature; Minecraft Wiki states outright \"This feature is exclusive to Java Edition\", and there is no world border asset anywhere in `bedrock-samples` - `resource_pack/textures/` contains only `forcefield_atlas.png`, a 16x16 grayscale noise tile used by Bedrock's own Border Block (`border_block` in `blocks.json`) and world boundary, not the diagonal striped Java border. Retexturing that noise tile would change the Border Block, not reproduce this pack.", + "caveats": "If Mojang ever ships Java-parity world borders on Bedrock (multiple open feedback requests), re-check - the port would then be a single texture override.", + "sources": [ + "https://minecraft.wiki/w/World_border", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures", + "https://feedback.minecraft.net/hc/en-us/community/posts/360011038271--Java-Parity-World-Border" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "CopperToolOxidization": { + "verdict": "partial", + "confidence": "medium", + "summary": "The held-item render can be made durability-driven with attachables + Molang, but the inventory and hotbar icon cannot change - Bedrock item textures have no damage selector.", + "mechanism": "`textures/item_texture.json` maps the `pickaxe` / `axe` / `shovel` / `hoe` shortnames to a tier-indexed array (index 6 is `textures/items/copper_pickaxe` etc.); there is no damage or durability dimension anywhere in that file, so the GUI sprite is fixed. What does work: add one attachable per copper tool under `attachables/` with `\"identifier\": \"minecraft:copper_pickaxe\"` (the Bedrock Wiki demonstrates attachables bound to vanilla item identifiers using `minecraft:stick`), give it a flat extruded geometry and a render controller that picks the texture from an array indexed by Molang, e.g. `Array.oxid[math.floor((1 - q.remaining_durability / q.max_durability) * 4)]`. `query.remaining_durability` and `query.max_durability` are documented Molang queries.", + "caveats": "Only first- and third-person held rendering oxidizes. Inventory, hotbar, dropped item entities, item frames and armour stands keep the single sprite from `item_texture.json`. Each of the five copper tools needs its own attachable, geometry and hold animations. Copper tools require Bedrock 1.21.111+. The exact Molang context available to an attachable render controller should be smoke-tested before committing to the approach.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/reference/content/molangreference/examples/molangconcepts/queryfunctions/query_remaining_durability?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/molangreference/examples/molangconcepts/queryfunctions/query_max_durability?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/items/attachables", + "https://wiki.bedrock.dev/entities/render-controllers", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/item_texture.json" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "GlowierGlow": { + "verdict": "blocked", + "confidence": "medium", + "summary": "The Glowing outline does not exist in Bedrock, and Bedrock resource packs cannot ship the shaders this pack rewrites.", + "mechanism": "Nothing to hook, twice over. The Glowing status effect outline is a Java Edition exclusive - Minecraft Wiki states \"This feature is exclusive to Java Edition\". Even if it existed, the Java pack works by rewriting core/post render shaders, and Bedrock resource-pack shaders and `.material` files stopped being loaded with RenderDragon: the Bedrock Wiki states they \"will not work on Windows and Console devices past 1.16.200, nor other devices past 1.18.30\". `bedrock-samples/resource_pack/` ships no `materials` or `shaders` folder at all.", + "caveats": "Bedrock's `lighting/global.json` and Vibrant Visuals expose some global light tuning, but nothing that touches entity outline rendering.", + "sources": [ + "https://minecraft.wiki/w/Glowing", + "https://wiki.bedrock.dev/concepts/shaders", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "HDEndFlash": { + "verdict": "possible", + "confidence": "medium", + "summary": "Bedrock renders the End flash from `textures/environment/end_flash.png`, so this is a single higher-resolution texture override.", + "mechanism": "`bedrock-samples/resource_pack/textures/environment/end_flash.png` is the 64x64 purple radial sprite Bedrock draws for End flashes. Textures are overwritten by path, so the pack is one file at `textures/environment/end_flash.png` drawn at 256x256 or higher (and, if the Java pack also touches the noise, `textures/environment/end_sky.png`).", + "caveats": "End flashes only became visible on Bedrock with Vibrant Visuals in 1.21.80; under Vibrant Visuals the flash is also a directional light source configured through `lighting/global.json`, so perceived brightness is not fully texture-driven. Players can disable End flashes in accessibility settings.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/environment/end_flash.png", + "https://minecraft.wiki/w/End_sky", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "HDCelestialGlow": { + "verdict": "possible", + "confidence": "medium", + "summary": "Bedrock bakes the sun and moon glow into the same sprite sheets Java uses, so upscaling them is a plain texture override.", + "mechanism": "`bedrock-samples/resource_pack/textures/environment/` ships `sun.png` (32x32, the disc plus its baked halo), `moon_phases.png` (128x64, a 4x2 phase grid) and `sun_vv.png` (32x32, the Vibrant Visuals sun). Textures are overwritten by path, so the pack is upscaled/smoothed replacements at those three paths, keeping the same aspect ratio and grid layout.", + "caveats": "Keep `moon_phases.png` at 2:1 with the same 4x2 phase grid or phases will be mis-sampled. Vibrant Visuals adds its own procedural sun scattering/glow on top of the sprite, so the effect is only fully texture-controlled under classic graphics; remember `sun_vv.png` or the pack will look inconsistent between the two graphics modes.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/environment", + "https://minecraft.wiki/w/Sun", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "VariatedFireflyBushes": { + "verdict": "partial", + "confidence": "medium", + "summary": "The randomised firefly animation timing is reproducible with per-position flipbook variants; the random model offset is not, because vanilla block models are hardcoded.", + "mechanism": "Animation half: vanilla defines `firefly_bush` in `textures/terrain_texture.json` as a two-entry array (`textures/blocks/firefly_bush`, `textures/blocks/firefly_bush_firefly`) and animates index 1 via `textures/flipbook_textures.json` (`atlas_index: 1`, `ticks_per_frame: 3`). Replace index 1 with a `variations` array of N copies of the firefly texture and add N `flipbook_textures.json` entries, each with `atlas_tile: \"firefly_bush\"`, `atlas_index: 1`, a distinct `atlas_tile_variant`, and a rotated `frames` list - the exact pattern vanilla already uses for `bubble_column_outer`, which ships 8 phase-shifted variants. Offset half: not possible. Bedrock exposes no geometry or offset control for vanilla blocks - `blocks.json` for `firefly_bush` carries only `textures`, `carried_textures` and `sound`, and the Bedrock Wiki states vanilla block models \"are not data-driven, so cannot be modified nor found as JSON files in the vanilla resource pack\".", + "caveats": "Ships as the animation-timing half only; the bushes stay grid-aligned. Texture variation is position-hashed, so the phase is random per block but fixed for that position, which matches the Java behaviour.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/flipbook_textures.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/terrain_texture.json", + "https://wiki.bedrock.dev/blocks/flipbook-textures", + "https://wiki.bedrock.dev/blocks/block-texture-variation", + "https://wiki.bedrock.dev/blocks/vanilla-block-models" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "OffsetBushes": { + "verdict": "blocked", + "confidence": "medium", + "summary": "Bedrock resource packs cannot move a vanilla block's model, so there is no way to offset Bushes.", + "mechanism": "Nothing to hook. The only per-block control Bedrock gives a resource pack for the vanilla `bush` block is its `blocks.json` entry, which carries just `textures`, `carried_textures` and `sound` (plus `isotropic` for random texture rotation) - there is no position offset, translation or geometry field. The Bedrock Wiki states vanilla block models \"are not data-driven, so cannot be modified nor found as JSON files in the vanilla resource pack\", and the `minecraft:geometry` component that would allow a custom model is a custom-block component, not something a resource pack can attach to a vanilla block.", + "caveats": "The nearest analogue - `variations` in `terrain_texture.json` with the art shifted inside the 16x16 tile - is not a usable substitute for a cross-shaped plant: shifting the sprite horizontally moves the two crossed planes in opposite world directions and visibly splits the model.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/blocks.json", + "https://wiki.bedrock.dev/blocks/block-texture-variation" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ConnectedBookshelves": { + "verdict": "blocked", + "confidence": "medium", + "summary": "Vanilla Tweaks does this with cullfaced faces in the Java bookshelf block model, and Bedrock resource packs cannot modify a vanilla block's model or culling.", + "mechanism": "Nothing to hook. Vanilla Tweaks' own Connected Textures category note says these packs \"use a cullfacing method\", i.e. extra model faces that vanish when a neighbour block is present - a block model edit, not a texture edit. Bedrock's `blocks.json` entry for `bookshelf` exposes only `sound` and a `textures` map (`bookshelf`, `bookshelf_top`), and the Bedrock Wiki states vanilla block models \"are not data-driven, so cannot be modified\" and \"are not compatible with the `bone_visibility` and `culling` parameters of the geometry component\". `minecraft:block_culling` rules only apply to custom blocks, which cannot replace `minecraft:bookshelf`. There is no connected-texture (CTM) system in Bedrock either - `terrain_texture.json` variation is position-hashed, never neighbour-aware.", + "caveats": "A seam-hiding retexture of `textures/blocks/bookshelf.png` alone is possible but would make single, isolated bookshelves look wrong, since the texture cannot react to neighbours.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/blocks.json", + "https://wiki.bedrock.dev/blocks/block-texture-variation" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ConnectedPolishedStones": { + "verdict": "blocked", + "confidence": "medium", + "summary": "Bedrock resource packs have no neighbour-aware texture selection and cannot supply geometry for vanilla blocks, so the seamless join between polished stone blocks cannot be reproduced.", + "mechanism": "Connecting textures needs either a neighbour-aware texture rule or altered block geometry. Neither control point exists: the documented properties of a vanilla block entry in `blocks.json` are only `sound`, `textures`, `carried_textures` and `isotropic`, and `textures/terrain_texture.json` resolves an alias to a single texture, a data-value-indexed array, or position-random `variations` - none of which can see adjacent blocks. Geometry is also closed: `resource_pack/models/` in Mojang/bedrock-samples contains 193 entity `.geo.json` files and zero block models, and the Bedrock Wiki states \"Currently, vanilla block models are not data-driven, so cannot be modified nor found as JSON files in the vanilla resource pack.\" The polished-stone textures themselves are reachable (e.g. the `stone` alias array in `terrain_texture.json` includes `stone_andesite_smooth`, `stone_diorite_smooth`, `stone_granite_smooth`), so a flat retexture is possible - connecting them is not.", + "caveats": "The `variations` block-texture feature (blocks.json `format_version` 1.21.110+) randomises by world position only, not by neighbouring blocks, and is documented for custom blocks. A flat 'seamless-looking' retexture that simply removes the per-block border is the only approximation.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/textures/terrain_texture.json" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ConnectedIronBlocks": { + "verdict": "blocked", + "confidence": "medium", + "summary": "Same limitation as the other connected-texture packs: Bedrock exposes no neighbour-aware texture rule and no vanilla block geometry, so iron blocks cannot be made to connect.", + "mechanism": "In Mojang/bedrock-samples, `blocks.json` maps `iron_block` to the single alias `iron_block`, and `terrain_texture.json` resolves that alias to one file, `textures/blocks/iron_block`. There is no array slot or condition keyed on neighbouring blocks, and `blocks.json` supports only `sound`, `textures`, `carried_textures` and `isotropic` for a vanilla block. The alternative route - shipping a block model whose extra faces are culled against neighbours - is unavailable because vanilla block models are not data-driven in Bedrock (`resource_pack/models/` holds entity geometry only).", + "caveats": "Retexturing `textures/blocks/iron_block.png` to a lower-contrast, borderless design is possible and is the closest achievable approximation.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/blocks.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ConnectedLapisBlocks": { + "verdict": "blocked", + "confidence": "medium", + "summary": "Same limitation as the other connected-texture packs: no neighbour-aware texture selection and no vanilla block geometry in Bedrock resource packs.", + "mechanism": "`blocks.json` in Mojang/bedrock-samples maps `lapis_block` to the alias `lapis_block`, which `terrain_texture.json` resolves to the single file `textures/blocks/lapis_block`. A vanilla block entry accepts only `sound`, `textures`, `carried_textures` and `isotropic`; nothing keys off adjacent blocks. Adding culled faces via a custom model is impossible because Bedrock does not ship or accept vanilla block geometry - `resource_pack/models/` contains only entity `.geo.json` files.", + "caveats": "A borderless flat retexture of `textures/blocks/lapis_block.png` is the only approximation.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/blocks.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "RedstonePowerLevels": { + "verdict": "blocked", + "confidence": "medium", + "summary": "A Bedrock resource pack cannot vary redstone dust's texture by signal strength or draw anything above the block, so the power number cannot be shown.", + "mechanism": "Two things are needed and neither is exposed. (1) Per-power textures: in Mojang/bedrock-samples `blocks.json`, `redstone_wire` maps `down`/`side`/`up` to the aliases `redstone_dust_line` and `redstone_dust_cross`, and both resolve in `terrain_texture.json` to a single texture string - unlike aliases such as `wool` or `bee_nest_front`, which are arrays the engine indexes. Bedrock instead tints redstone dust by power in the renderer, which a pack cannot re-map to distinct artwork. (2) Digits floating above the wire need extra geometry, and vanilla block models are not data-driven in Bedrock - `resource_pack/models/` in bedrock-samples contains entity geometry only, and a vanilla `blocks.json` entry accepts only `sound`, `textures`, `carried_textures` and `isotropic`.", + "caveats": "A behaviour-pack/Script API add-on that spawns text-bearing entities above powered dust could in principle display the value, but that belongs in the `addons` section, would be per-block expensive, and was not verified here. Retexturing the dust itself (as `clean_redstone_dust` already does) remains possible.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/blocks.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/textures/terrain_texture.json", + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "VisualHoney": { + "verdict": "blocked", + "confidence": "medium", + "summary": "Bedrock only renders two beehive/bee nest states (empty and full), so the intermediate honey stages a resource pack would need to show do not exist as addressable texture slots.", + "mechanism": "In Mojang/bedrock-samples, `textures/terrain_texture.json` defines `bee_nest_front` and `beehive_front` as two-entry arrays - `[textures/blocks/bee_nest_front, textures/blocks/bee_nest_front_honey]` and `[textures/blocks/beehive_front, textures/blocks/beehive_front_honey]`. The engine selects index 0 or 1 (not-full vs. full); there is no slot keyed to `honey_level` 1-4, and `blocks.json` offers no block-state condition for a vanilla block (only `sound`, `textures`, `carried_textures`, `isotropic`). Extra array entries would never be selected, so the five-stage readout the Java pack provides cannot be produced.", + "caveats": "The two existing states can still be retextured - e.g. making the 'full' front face read more clearly - but that is a different, much weaker pack than the Java one.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/textures/terrain_texture.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/blocks.json", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "NoFog": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock fog is fully data-driven from a resource pack, so pushing distance fog out of view is straightforward and needs no shader edits.", + "mechanism": "Add a `fogs/no_fog.json` containing `minecraft:fog_settings` (`format_version` 1.16.100+) with a namespaced `description.identifier`, then ship a `biomes_client.json` that points `biomes.default.fog_identifier` - and every biome entry you want covered - at that identifier. Set `distance.air.fog_start`/`fog_end` far out (`render_distance_type: \"fixed\"` with a large block count, or `\"render\"` at ~0.99/1.0). Templates for both files are in Mojang/bedrock-samples: `resource_pack/fogs/default_fog_setting.json` and `resource_pack/biomes_client.json`, whose header comment states that overwriting `default` in a resource pack overwrites all biomes unless the pack defines them.", + "caveats": "Minimum `format_version` 1.16.100. Vanilla fog identifiers in the `minecraft` namespace cannot be redefined, so use your own namespace and repoint `biomes_client.json`. Chunks still stop rendering at the client's render distance, so the result is a hard chunk edge instead of a fade. `water`, `lava`, `lava_resistance`, `powder_snow` and `weather` fog are separate entries and Nether/End biomes need their own overrides. Unlike the Java pack this does not touch shaders, so it has no mod-compatibility problem.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/foginresourcepacks", + "https://learn.microsoft.com/minecraft/creator/reference/content/fogsreference/fogs", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/fogs/default_fog_setting.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/biomes_client.json" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "CleanerWorldBorder": { + "verdict": "blocked", + "confidence": "medium", + "summary": "Bedrock has no world border feature and ships no world-border texture, so there is nothing for a pack to clean up.", + "mechanism": "The Java pack replaces `textures/misc/forcefield.png`. Mojang/bedrock-samples has no such file - `resource_pack/textures/misc/` contains only `enchanted_actor_glint.png`, `enchanted_item_glint.png`, `missing_texture.png` and `pumpkinblur.png`. The one force-field asset in the vanilla pack is `resource_pack/textures/forcefield_atlas.png` (16x16), which serves the `border_block` (`blocks.json` entry `border_block`, alias `border_block`), not a world border. minecraft.wiki states of the world border that \"This feature is exclusive to Java Edition\", and no Bedrock creator update notes on learn.microsoft.com introduce one.", + "caveats": "If the border block's force-field wall is considered close enough, `textures/forcefield_atlas.png` is an ordinary overridable texture and a 'cleaner border block' pack is possible - but it is a different feature from the Java world border and would need its own pack entry.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/misc", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/blocks.json", + "https://minecraft.wiki/w/World_border" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "SmallerUtilities": { + "verdict": "possible", + "confidence": "high", + "summary": "Attachables let a resource pack replace how a vanilla item renders in hand, including scaling it down in first and third person - and an unregistered implementation already exists in this repo.", + "mechanism": "For each item, add `attachables/.attachable.json` whose `description.identifier` is the vanilla item id (e.g. `minecraft:golden_apple`); this replaces the model shown when the item is held. Point `geometry` at a flat `models/entity/.geo.json`, `textures` at the existing item texture, and drive `animations.hold_first_person` / `hold_third_person` from `scripts.animate` with `context.is_first_person == 1.0` / `== 0.0`, using a shared `animations/small_item.animation.json` that scales and repositions the bone. Bind to `query.item_slot_to_bone_name` so both `main_hand` and `off_hand` are covered. Note for the maintainer: `resource_packs/files/unobtrusive/smaller_utilities/` already exists on disk with ~60 attachables and `animations/small_item.animation.json`, but there is no `smaller_utilities` entry in `resource_packs/packs.json` - this looks like a registration gap rather than a missing port.", + "caveats": "One attachable file per item, so the pack is large and needs maintenance whenever new food/utility items ship. Attachable rendering replaces the vanilla in-hand model entirely, so enchanted-glint and other special materials must be declared explicitly (`materials.enchanted`).", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/attachables", + "https://learn.microsoft.com/minecraft/creator/reference/content/attachablereference/examples/attachabledefinitions/attachable", + "https://wiki.bedrock.dev/items/attachables" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DBookshelves": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot change the model of a vanilla block, so bookshelves cannot be given 3D depth.", + "mechanism": "The pack needs new geometry on `minecraft:bookshelf`. Bedrock does not expose that: the Bedrock Wiki states \"Currently, vanilla block models are not data-driven, so cannot be modified nor found as JSON files in the vanilla resource pack\", and Mojang/bedrock-samples confirms it - `resource_pack/models/` contains only `entity/` and `mobs.json`, with no block geometry anywhere, while `blocks.json` gives `bookshelf` only a texture alias. `minecraft:geometry` and `minecraft:material_instances` exist only for custom blocks defined in a behaviour pack, and the wiki's Overwriting Assets page lists vanilla blocks among the things that cannot be overwritten.", + "caveats": "Re-checked 2026-07-25 against the `item_display_transforms` hypothesis; still blocked, for two reasons. First, that field only changes how a block's ITEM form is drawn (gui, hands, ground, item frame) - it never touches the placed block in the world, which is the whole point of this pack. Second, it is read from the geometry named by a data-driven block's `minecraft:geometry` component, and `minecraft:bookshelf` has no data-driven definition (`behavior_pack/` in bedrock-samples has no `blocks/` folder), so there is no geometry file to write it into. It also requires geometry version 1.21.0+ and the `Upcoming Creator Features` experimental toggle. An `addons`-style workaround (a namespaced custom block with `minecraft:geometry`, or an entity-based 'fake block') could look 3D, but it would be a new block, not the vanilla bookshelf, and would lose enchanting-table power, recipes and world compatibility. Only `textures/blocks/bookshelf.png` can be changed by a resource pack.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://github.com/Mojang/bedrock-samples/tree/main/behavior_pack", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/itemdisplaytransforms?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DChiseledBookshelves": { + "verdict": "blocked", + "confidence": "high", + "summary": "Same limitation as 3D Bookshelves - vanilla block geometry is not data-driven in Bedrock, so the chiseled bookshelf cannot be remodelled by a resource pack.", + "mechanism": "Remodelling `minecraft:chiseled_bookshelf` requires block geometry, which Bedrock resource packs cannot provide: `resource_pack/models/` in Mojang/bedrock-samples holds entity models only, and the Bedrock Wiki states vanilla block models \"are not data-driven, so cannot be modified nor found as JSON files in the vanilla resource pack\"; the same wiki's Overwriting Assets page lists vanilla blocks as not overwritable. A resource pack is limited to swapping the existing flat textures - `chiseled_bookshelf_empty`, `chiseled_bookshelf_occupied`, `chiseled_bookshelf_side`, `chiseled_bookshelf_top` - via `blocks.json` / `terrain_texture.json`.", + "caveats": "Bedrock does render per-slot occupancy on the chiseled bookshelf, so the occupied/empty textures can still be restyled; only the protruding 3D books are impossible.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/blocks.json" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DChains": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot change the shape of vanilla blocks, so the Chain, Copper Chain and Lantern blocks cannot be remodelled into 3D.", + "mechanism": "There is no control point for this. A Bedrock resource pack's block definition file, `blocks.json`, only accepts `sound`, `textures`, `carried_textures` and `isotropic` — it has no geometry field. Block geometry only exists as the behaviour-pack components `minecraft:geometry` + `minecraft:material_instances`, and those apply only to custom blocks you define yourself; vanilla blocks such as `minecraft:chain` and `minecraft:lantern` have no data-driven definition to override. The vanilla resource pack in `Mojang/bedrock-samples` proves the absence: `resource_pack/models/` contains only `entity/` and `mobs.json` — there is no `models/blocks/` directory and no chain or lantern geometry file anywhere in the shipped pack. The only shippable win here is a texture-only fake-depth retexture of `textures/blocks/chain1.png` / `lantern.png`, the same trick this repo's `3d_sun_and_moon` pack uses, which is not what the Java pack does.", + "caveats": "Verified against bedrock-samples 1.26.30.5. Re-checked 2026-07-25 against the `item_display_transforms` hypothesis; still blocked. That field only affects a block's ITEM representation (gui, first/third person, ground, item frame), not the block as placed in the world, so even in the best case it could not give a placed chain or lantern 3D geometry — and it is read from the geometry referenced by a data-driven block's `minecraft:geometry` component, which vanilla chain and lantern do not have. It additionally requires geometry version 1.21.0+ and the `Upcoming Creator Features` experimental toggle. Not solvable by moving to `addons` either: a behaviour pack can only give geometry to new custom blocks, so reproducing this would mean replacing every vanilla chain and lantern in the world with a custom block, breaking vanilla parity, item IDs, crafting and world compatibility. Revisit if Mojang ever data-drives vanilla block models.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://github.com/Mojang/bedrock-samples/tree/main/behavior_pack", + "https://learn.microsoft.com/minecraft/creator/documents/advancedcustomblocks", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/itemdisplaytransforms?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DPointedDripstone": { + "verdict": "blocked", + "confidence": "high", + "summary": "Pointed Dripstone is a vanilla block and Bedrock resource packs cannot replace vanilla block geometry, so a 3D remodel is not shippable.", + "mechanism": "Nothing in a resource pack reaches vanilla block shape. `blocks.json` exposes only `sound`, `textures`, `carried_textures` and `isotropic`; the only geometry hook in the engine is the behaviour-pack `minecraft:geometry` component, which is scoped to custom blocks. The Bedrock Wiki states it plainly: \"Currently, vanilla block models are not data-driven, so cannot be modified nor found as JSON files in the vanilla resource pack.\" That is corroborated by `Mojang/bedrock-samples`, whose `resource_pack/models/` folder holds only `entity/` and `mobs.json` — no `pointed_dripstone` geometry exists to override. Only the flat textures under `textures/blocks/pointed_dripstone_*.png` are editable.", + "caveats": "Verified against bedrock-samples 1.26.30.5. Moving this to `addons` does not help — a behaviour pack can only model a brand-new custom block, so the vanilla dripstone would have to be swapped out entirely, breaking parity and world compatibility.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DAmethyst": { + "verdict": "blocked", + "confidence": "high", + "summary": "Amethyst clusters, buds and the Calibrated Sculk Sensor are vanilla blocks whose geometry a Bedrock resource pack cannot touch.", + "mechanism": "The cross-shaped amethyst cluster/bud models and the Calibrated Sculk Sensor's amethyst-plate model are hardcoded in the client. A resource pack's `blocks.json` carries no geometry property, and the `minecraft:geometry` / `minecraft:material_instances` components that do carry geometry live in a behaviour pack and only bind to custom blocks. `Mojang/bedrock-samples` confirms the assets simply are not there: `resource_pack/models/` contains only `entity/` and `mobs.json`, and `behavior_pack/` has no `blocks/` folder at all, so no vanilla block definition exists to override. Editable surface is limited to `textures/blocks/amethyst_cluster.png`, the bud textures, and `sculk_sensor_*`/`calibrated_sculk_sensor_*` textures plus `terrain_texture.json` mappings.", + "caveats": "Verified against bedrock-samples 1.26.30.5. The `behavior_pack/shapes/` folder in bedrock-samples looks promising but defines collision/selection boxes only, not render geometry.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://github.com/Mojang/bedrock-samples/tree/main/behavior_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DRedstoneWire": { + "verdict": "blocked", + "confidence": "high", + "summary": "Redstone Wire's flat-on-the-floor model is engine-side on Bedrock and cannot be given depth by a resource pack.", + "mechanism": "Redstone dust is rendered by hardcoded client geometry with a connection-state-driven shape. Bedrock exposes no per-block-state model selection to resource packs at all — there is no Java-style `blockstates/redstone_dust.json` equivalent, `blocks.json` accepts only sound and texture keys, and geometry is a behaviour-pack component restricted to custom blocks. `Mojang/bedrock-samples` has no `resource_pack/models/blocks/` directory (only `models/entity/` and `models/mobs.json`), so there is no redstone wire geometry file to replace. Only `textures/blocks/redstone_dust_line_0/1.png`, `redstone_dust_cross.png` and the `redstone_dust_dot` texture can be edited, and Bedrock additionally tints these through a hardcoded power-level colour ramp.", + "caveats": "Verified against bedrock-samples 1.26.30.5. Even a behaviour-pack add-on cannot help: redstone dust's placement and connection logic is not data-driven, so it cannot be substituted with a custom block without losing redstone behaviour.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DTiles": { + "verdict": "partial", + "confidence": "medium", + "summary": "Held-in-hand 3D models for these items are achievable with attachables (this repo already ships `3d_mace` that way), but Bedrock item icons in the inventory, hotbar, dropped items and item frames stay flat 2D sprites.", + "mechanism": "Build one file per item under `attachables/.attachable.json` with `identifier` set to the vanilla item id (e.g. `minecraft:boat`, `minecraft:cauldron`, `minecraft:hopper`, `minecraft:brewing_stand`, `minecraft:flower_pot`, `minecraft:campfire`, `minecraft:minecart`), a `geometry` entry pointing at a new `models/entity/.geo.json` whose root bone is bound with `query.item_slot_to_bone_name(context.item_slot)`, a texture, and first/third-person hold animations in `animations/.animation.json` selected by `context.is_first_person` — exactly the layout of this repo's existing `resource_packs/files/3d/3d_mace` pack. What cannot be reproduced is the inventory side: Bedrock's `minecraft:icon` component takes a texture key from `textures/item_texture.json` and nothing else, so `cauldron`, `hopper`, `brewing_stand`, `campfire`, `flower_pot`, `boat*` and `minecart_*` will keep rendering their existing flat PNG in the UI. Every documented 3D-icon route is custom-content-only: `minecraft:item_visual` is a BLOCK component (format version 1.21.60+, `Upcoming Creator Features` toggle) that customises the item form of a data-driven block; `minecraft:block_placer` with `replace_block_item` is likewise scoped to a custom block you author; and `item_display_transforms` (geometry version 1.21.0+, same experimental toggle) is a geometry-file field whose tutorial and reference both scope it to custom block geometry. None of the three has a vanilla item to attach to.", + "caveats": "Re-checked 2026-07-25 against the maintainer's `item_display_transforms` hypothesis. The field does live in the geometry file and does list a `\"gui\"` context with `fit_to_frame`, which is why it looks like it should give 3D inventory icons — but a resource pack has nothing to override with it. `Mojang/bedrock-samples` `resource_pack/models/` contains only `entity/` and `mobs.json`; there is no vanilla item geometry file and no `resource_pack/items/` directory at all, so no vanilla item ever reaches a geometry document through the item render path. Vanilla item definitions live in `behavior_pack/items/` (122 files, and most vanilla items are not even data-driven there — `diamond_sword.json`, `totem_of_undying.json` and `firework_rocket.json` do not exist), and the ones that do exist expose only `minecraft:icon`; the full item component list has no geometry, no display-transform and no `item_visual` entry. Scope also shrinks because several members of the Java list are already 3D on Bedrock: `bell`, `lantern` and `turtle_egg` have no entry in `resource_pack/textures/item_texture.json`, meaning Bedrock already renders their item form from the block. Attachables affect held/worn rendering only — dropped item entities, item frames and armour stands are unaffected. Expect this to be a per-item grind rather than one pack; consider shipping it as a subset.", + "sources": [ + "https://wiki.bedrock.dev/items/attachables", + "https://learn.microsoft.com/minecraft/creator/documents/attachables", + "https://learn.microsoft.com/minecraft/creator/reference/content/itemreference/examples/itemcomponents/minecraft_icon", + "https://learn.microsoft.com/minecraft/creator/reference/content/itemreference/examples/itemcomponentlist?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/itemdisplaytransforms?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/visualreference/geometry.v1.21.0?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_item_visual?view=minecraft-bedrock-stable", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/item_texture.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/items/apple.json", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/customizingitemforablock" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DLadders": { + "verdict": "blocked", + "confidence": "high", + "summary": "Ladders are vanilla blocks rendered by hardcoded client geometry, so a Bedrock resource pack cannot give them depth.", + "mechanism": "The ladder's flat wall-mounted quad is not data-driven. A resource pack can only redirect its texture via `blocks.json` / `textures/blocks/ladder.png`; `blocks.json` has no geometry property. Geometry on Bedrock comes from the behaviour-pack `minecraft:geometry` component, which the docs scope to custom blocks — and `Mojang/bedrock-samples` contains no vanilla block definitions at all (`behavior_pack/` has no `blocks/` folder) and no block geometry (`resource_pack/models/` holds only `entity/` and `mobs.json`). The Bedrock Wiki states it directly: vanilla block models \"cannot be modified nor found as JSON files in the vanilla resource pack\".", + "caveats": "Verified against bedrock-samples 1.26.30.5. Re-checked 2026-07-25 against the `item_display_transforms` hypothesis; still blocked. `item_display_transforms` changes only how a block is drawn as an ITEM (gui, hands, ground, item frame), never the placed block, so it is the wrong lever for this pack — and it must be written into the geometry file a data-driven block's `minecraft:geometry` component points at, which `minecraft:ladder` does not have. It is also gated behind geometry version 1.21.0+ and the `Upcoming Creator Features` experimental toggle.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://github.com/Mojang/bedrock-samples/tree/main/behavior_pack", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/itemdisplaytransforms?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DRails": { + "verdict": "blocked", + "confidence": "high", + "summary": "Rail, Powered Rail, Detector Rail and Activator Rail all use hardcoded Bedrock block geometry that a resource pack cannot replace.", + "mechanism": "Rails would need raised sleepers and side rails, which is a geometry change. Bedrock resource packs have no geometry hook for vanilla blocks: `blocks.json` exposes only `sound`, `textures`, `carried_textures` and `isotropic`, and the `minecraft:geometry` component that does define block shape is a behaviour-pack component documented for custom blocks. `Mojang/bedrock-samples` shows the files are absent — `resource_pack/models/` contains only `entity/` and `mobs.json`, so there is no `rail.geo.json` to override, and there is no vanilla `behavior_pack/blocks/` folder to patch. Only `textures/blocks/rail_normal*.png`, `rail_golden*.png`, `rail_detector*.png` and `rail_activator*.png` are editable, plus their `terrain_texture.json` mappings.", + "caveats": "Verified against bedrock-samples 1.26.30.5. Rails also carry curve/slope render states that Bedrock does not expose to packs at all, so even a partial approximation has no entry point.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DIronBars": { + "verdict": "blocked", + "confidence": "high", + "summary": "Iron Bars and Copper Bars are vanilla blocks whose cross-plane geometry cannot be replaced by a Bedrock resource pack.", + "mechanism": "Making bars round/3D requires new geometry, and Bedrock has no resource-pack control point for vanilla block shape. `blocks.json` accepts sound and texture keys only; the `minecraft:geometry` + `minecraft:material_instances` pair that defines block shape is a behaviour-pack component that binds to custom blocks. `Mojang/bedrock-samples` demonstrates the absence directly: `resource_pack/models/` contains only `entity/` and `mobs.json`, so no `iron_bars` geometry exists in the shipped pack, and the Bedrock Wiki states vanilla block models are not data-driven. Editable surface is limited to `textures/blocks/iron_bars.png` / `copper_bars*.png` and their `terrain_texture.json` entries.", + "caveats": "Verified against bedrock-samples 1.26.30.5. Copper Bars are a recent block; if Mojang ships them data-driven in a future bedrock-samples release this verdict should be rechecked for that half of the pack.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DSugarcane": { + "verdict": "blocked", + "confidence": "high", + "summary": "Sugar Cane uses the hardcoded cross-plane vanilla block model on Bedrock, which a resource pack has no way to remodel.", + "mechanism": "The Java pack replaces the two intersecting quads with a thicker stalk model. On Bedrock that is a geometry change, and geometry for vanilla blocks is not exposed anywhere in a resource pack — `blocks.json` has only `sound`, `textures`, `carried_textures` and `isotropic`, and `minecraft:geometry` is a behaviour-pack component for custom blocks. `Mojang/bedrock-samples` has no `resource_pack/models/blocks/` directory (only `models/entity/` and `models/mobs.json`) and no vanilla `behavior_pack/blocks/` folder, so there is no sugar cane model file to override. Only `textures/blocks/reeds.png` can be changed.", + "caveats": "Verified against bedrock-samples 1.26.30.5.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DLilyPads": { + "verdict": "blocked", + "confidence": "high", + "summary": "Lily Pads render from hardcoded Bedrock block geometry, so a resource pack cannot give them thickness or a raised edge.", + "mechanism": "Adding depth to the lily pad's single flat quad is a geometry edit. Bedrock resource packs cannot supply geometry for vanilla blocks: `blocks.json` carries no geometry property, and the `minecraft:geometry` component that does is a behaviour-pack component the docs scope to custom blocks. The Bedrock Wiki states vanilla block models \"are not data-driven, so cannot be modified nor found as JSON files in the vanilla resource pack\", and `Mojang/bedrock-samples` bears that out — `resource_pack/models/` holds only `entity/` and `mobs.json`. Only `textures/blocks/waterlily.png` is editable, and Bedrock also applies a hardcoded green tint to it.", + "caveats": "Verified against bedrock-samples 1.26.30.5.", + "sources": [ + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DDoors": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot change the geometry of vanilla Doors or Trapdoors — vanilla block models are hardcoded in the engine and are not exposed as data anywhere in a resource pack.", + "mechanism": "There is no control point to build this on. A Bedrock resource pack's block surface is `blocks.json` (texture set, carried texture, isotropic flag, placement/break sound) and `textures/terrain_texture.json` (which image each texture set points at) — neither carries geometry. `resource_pack/models/` in bedrock-samples contains only `entity/` and `mobs.json`; there are no block model files at all. The `minecraft:geometry` / `minecraft:material_instances` components that do drive block shape are behaviour-pack components and apply only to new custom blocks — bedrock-samples has no `behavior_pack/blocks/` directory, so `minecraft:door` and `minecraft:trapdoor` cannot be redefined. `behavior_pack/shapes/*.json` are `minecraft:voxel_shape` collision/selection boxes, not render geometry, and contain no door entry.", + "caveats": "The only thing a pack can do here is repaint `textures/blocks/door_*.png` and `trapdoor.png` with painted-on shading to fake depth; the block stays a flat plane. A behaviour-pack add-on could ship 3D custom blocks, but they would be new block IDs, would not replace naturally generated or existing doors, and would lose vanilla door behaviour.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DMushrooms": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot remodel vanilla Mushrooms or Nether Fungi — their cross-plane models are hardcoded in the engine and are not data-driven.", + "mechanism": "Mushrooms, Crimson Fungus and Warped Fungus render with the engine's built-in cross model. A resource pack can only swap their images via `blocks.json` / `textures/terrain_texture.json`; it has no geometry control point. bedrock-samples ships no block models (`resource_pack/models/` holds only `entity/` and `mobs.json`) and no vanilla block definitions in the behaviour pack (`behavior_pack/blocks/` does not exist), so `minecraft:red_mushroom`, `minecraft:crimson_fungus` etc. cannot be given a `minecraft:geometry` component.", + "caveats": "A behaviour-pack add-on can create 3D custom fungus blocks, but they are new block IDs — world generation, bone meal growth and Huge Fungus growth would still produce the vanilla flat ones.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DBushes": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot remodel Bushes or Sweet Berry Bushes — vanilla block geometry is hardcoded and no resource-pack file describes it.", + "mechanism": "Both blocks render with the engine's built-in cross model. The only resource-pack surface for a vanilla block is the texture set in `blocks.json` plus the image mapping in `textures/terrain_texture.json`; neither expresses geometry. bedrock-samples has no block models under `resource_pack/models/` and no `behavior_pack/blocks/` directory, so there is nothing to override with a `minecraft:geometry` component — that component only works on new custom blocks.", + "caveats": "Sweet Berry Bush has four growth-stage textures that could be repainted with faked depth, but the block stays two crossed planes. A behaviour-pack add-on could add 3D look-alike blocks, but they would not be the vanilla bushes that generate in the world.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DVines": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot give Vines depth — the vine block's flat wall-hugging quad is hardcoded engine geometry with no resource-pack representation.", + "mechanism": "Vines are a multi-face block drawn by the engine as flat quads offset from each attached face. A resource pack reaches only `blocks.json` (texture set / sound) and `textures/terrain_texture.json` (which PNG a texture set uses); there is no geometry, no per-face offset and no model file. bedrock-samples contains no block models under `resource_pack/models/` and no `behavior_pack/blocks/` to redefine `minecraft:vine`, so the `minecraft:geometry` component — behaviour-pack only, custom blocks only — is not reachable.", + "caveats": "Painting shading into `textures/blocks/vine.png` is the only available approximation and does not produce actual depth.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DGlowLichen": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot remodel Glow Lichen — like all vanilla blocks its geometry is hardcoded in the engine and absent from the resource pack.", + "mechanism": "Glow Lichen is a multi-face decoration block rendered by the engine. The resource-pack control points for a vanilla block are the texture set in `blocks.json` and the image mapping in `textures/terrain_texture.json` — geometry is not among them, and `resource_pack/models/` in bedrock-samples contains only entity models. Redefining the block with a `minecraft:geometry` component is a behaviour-pack operation limited to new custom blocks; bedrock-samples ships no `behavior_pack/blocks/` directory for vanilla blocks.", + "caveats": "Emissive/glow appearance is separately controlled and unaffected; only the flat geometry is the blocker.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DSculkVein": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot remodel Sculk Veins — vanilla block models are hardcoded and are not exposed as JSON in any resource pack.", + "mechanism": "Sculk Vein is a multi-face block drawn as flat quads by the engine. A resource pack can only change which PNG it uses, through `blocks.json` and `textures/terrain_texture.json`. There is no block-model file anywhere in `resource_pack/models/` (entity models only) and no vanilla block definition in `behavior_pack/` to attach a `minecraft:geometry` component to — that component applies to custom blocks only.", + "caveats": "No approximation beyond repainting `textures/blocks/sculk_vein.png` with painted-in depth.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "3DStonecutters": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot add a 3D saw blade to the Stonecutter — the block's shape is hardcoded engine geometry and the Stonecutter is not rendered as a block entity either.", + "mechanism": "The Stonecutter's saw is part of the block's built-in model. A resource pack's only levers are the texture set in `blocks.json` and the image mapping in `textures/terrain_texture.json`. Unlike chests or beds, the Stonecutter has no entry under `resource_pack/models/entity/`, so the identifier-based model override that works for entity/block-entity geometry does not apply. `behavior_pack/blocks/` does not exist in bedrock-samples, so `minecraft:stonecutter` cannot be given a `minecraft:geometry` component; `behavior_pack/shapes/` holds only `minecraft:voxel_shape` collision boxes and has no stonecutter entry.", + "caveats": "`ui/stonecutter_screen.json` (the crafting UI) is moddable, but that is unrelated to the in-world block model.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://github.com/Mojang/bedrock-samples/tree/main/behavior_pack/shapes" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "TransparentUI": { + "verdict": "partial", + "confidence": "medium", + "summary": "Container and HUD screens can be made transparent with texture and JSON UI overrides, but the newer Ore UI screens (main menu, settings, play/worlds, store) are hardcoded and cannot be touched, so \"all UIs\" is not reachable.", + "mechanism": "Two levers, both standard resource-pack overrides. (1) Path-override the nine-slice background art in `textures/ui/` with transparent or alpha-reduced PNGs — `dialog_background_opaque.png`, `dialog_background_hollow_1..8.png`, `background_panel.png`, `slot_enabled.png` / `slot_disabled.png`, `hotbar_0..8.png`, `hotbar_start_cap.png` / `hotbar_end_cap.png`, `highlight_slot.png` — keeping each PNG's sibling nine-slice `.json` intact. (2) For anything colour- rather than texture-driven, ship JSON UI overrides of the vanilla screen files in `ui/` (`inventory_screen.json`, `chest_screen.json`, `furnace_screen.json`, `hud_screen.json`, …), preferably via the `modifications` property so only the background panels' `alpha`/`color` change and other packs still compose. Every container has a desktop and a `*_screen_pocket.json` touch variant, and `ui/pocket_containers.json` — all must be covered.", + "caveats": "JSON UI is being deprecated in favour of Ore UI, which the Bedrock Wiki states is hardcoded and cannot be modified by resource packs; screens already migrated to Ore UI cannot be made transparent, so this ports as \"transparent inventories/containers\", not \"transparent everything\". Nine-slice `.json` files must be shipped alongside any replaced PNG or the panel will stretch wrongly. Expect maintenance whenever Mojang restructures a screen.", + "sources": [ + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/ui" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "NoJavaEditionTitle": { + "verdict": "blocked", + "confidence": "high", + "summary": "Nothing to port — Bedrock's title logo has no edition subtitle to remove.", + "mechanism": "Bedrock's start and pause screens draw the logo from a single image: `ui/ui_art_assets_common.json` defines `common_art.title_image` with `\"texture\": \"textures/ui/title\"`, used by `title_panel_win10`, `title_panel_osx`, `title_panel_pocket` and `pause_logo_panel`. `resource_pack/textures/ui/title.png` in bedrock-samples is the bare \"MINECRAFT\" wordmark with no subtitle beneath it; the only edition variants that exist are `title_edu` / `title_edu_preview` for Education Edition. There is no \"Java Edition\" line, and therefore no equivalent change for a Bedrock pack to make.", + "caveats": "If a maintainer wants a related pack, the reverse is possible: `textures/ui/title.png` is a plain path-override, so a pack could replace the wordmark with a custom logo.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/ui/ui_art_assets_common.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/ui/title.png", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "PingColorIndicator": { + "verdict": "possible", + "confidence": "high", + "summary": "Straightforward texture override — Bedrock already picks a different ping icon per connection quality, and a resource pack can restyle each one, though Bedrock's ping icons appear in the server/friends list rather than on a Java-style tab player list.", + "mechanism": "The engine supplies the icon path at runtime through the JSON UI bindings `#info_ping_texture_name` and `#info_additional_server_ping_texture_name` (see `ui/play_screen.json`, controls `ping_rate_icon` / `ping_rate_panel`), selecting from the textures shipped in `resource_pack/textures/ui/`: `Ping_Green.png`, `Ping_Yellow.png`, `Ping_Red.png`, `Ping_Offline_Red.png` and their `_Dark` variants, plus the alternate set `ping_high.png`, `ping_medium.png`, `ping_low.png`, `ping_none.png`. Textures are overridden by path, so the pack is just those PNGs at the same paths — no JSON UI edits needed. The high-ping warning dialog additionally hardcodes `textures/ui/Ping_Yellow_Dark` and `textures/ui/Ping_Red_Dark`, which the same overrides cover.", + "caveats": "Vanilla Bedrock already colour-codes ping green/yellow/red, so this is a restyle rather than new behaviour and the maintainer may judge it redundant. Bedrock has no Java-style tab player list with per-player ping bars, and no in-world ping HUD element (the HUD lag indicator is the separate `ui/perf_turtle.json` turtle icon), so the effect is confined to the Play/Servers/Friends lists.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/ui/play_screen.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "LiteralGameruleNames": { + "verdict": "partial", + "confidence": "medium", + "summary": "Bedrock's world-settings toggles are driven by overridable `createWorldScreen.*` keys in `texts/en_US.lang`, so they can be renamed to technical gamerule names, but the pack must be applied as a Global Resource and Bedrock exposes a smaller gamerule set than Java.", + "mechanism": "Ship a resource pack containing only `texts/languages.json` and `texts/en_US.lang`, redefining the vanilla keys that label the world settings toggles. The shipped vanilla resource pack (`resource_pack/texts/en_US.lang` in Mojang/bedrock-samples) defines them as `createWorldScreen.tntexplodes=TNT Explodes`, `createWorldScreen.fireSpreads=Fire Spreads`, `createWorldScreen.mobgriefing=Mob Griefing`, `createWorldScreen.keepInventory=Keep Inventory`, `createWorldScreen.tileDrops=Tile Drops`, `createWorldScreen.showCoordinates=Show Coordinates` and so on, each with a matching `.name` and often a `.description` sub-key. Setting those values to the technical names (`tntExplodes`, `doFireTick`, `mobGriefing`, `keepInventory`, `doTileDrops`, `showCoordinates`, ...) reproduces the Java pack. Microsoft documents language files as pack-overridable (`Overwriting Vanilla Assets` lists 'All language files' under catalog-file overrides), and only the keys you redefine need to be present.", + "caveats": "The world creation screen is outside any world, so a per-world pack will not affect it — the pack has to be enabled under Settings > Global Resources; the Bedrock Wiki documents global resource packs supplying languages that the in-game Settings > Language tab picks up, which is the same mechanism. The screen itself is Ore UI, which the Bedrock Wiki states is hardcoded and cannot be modified by resource packs, so only the strings can change, not the layout or grouping. Bedrock surfaces a smaller and differently named subset of gamerules than Java's world creation menu, so the port is a mapping exercise, not a 1:1 copy; the same keys also drive the in-game Settings > Game screen, which will be renamed too. Worth a quick in-game test that lang overrides reach Ore UI screens before investing in the full mapping.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/texts/en_US.lang", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://learn.microsoft.com/minecraft/creator/documents/preparingrawtextforlocalization", + "https://wiki.bedrock.dev/text/text-intro", + "https://wiki.bedrock.dev/json-ui/json-ui-intro" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvGray": { + "verdict": "possible", + "confidence": "medium", + "summary": "A gray container UI is reproducible by recolouring the `textures/ui/` nine-slice sprites and repointing them from the JSON UI container screens, which are still data-driven in the shipped vanilla pack.", + "mechanism": "Bedrock has no per-container GUI sheet; container screens are assembled from shared nine-slice sprites in `textures/ui/` — `dialog_background_opaque.png`, `dialog_background_hollow_1..8.png`, `cell_image.png`, `item_cell.png`, `highlight_slot.png`, `hotbar_start_cap.png`/`hotbar_end_cap.png`, each with a companion `.json` nine-slice descriptor. Textures are overridden by path, so same-named PNGs in the pack replace vanilla. To keep the gray tint scoped to inventories instead of every dialog in the game, add the recoloured PNGs under a new path and repoint them from `ui/inventory_screen.json`, `ui/inventory_screen_pocket.json`, `ui/chest_screen.json` and `ui/pocket_containers.json` using the JSON UI `modifications` property, or tint the existing sprites in place with the JSON UI `color` property.", + "caveats": "The sprites are reused by the pause menu, chat and every other JSON UI dialog, so a naive in-place retexture bleeds outside containers unless the screen files are repointed. Ore UI screens (main menu, settings, marketplace, world creation) cannot be recoloured at all, and the Bedrock Wiki states JSON UI is being deprecated in favour of Ore UI, so JSON UI edits carry long-term breakage risk. Touch/pocket layouts need the `_pocket` screen variants covered separately. Nine of these colour variants exist upstream, so consider one pack with subpacks rather than nine packs.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvBlack": { + "verdict": "possible", + "confidence": "medium", + "summary": "A black container UI is reproducible by recolouring the `textures/ui/` nine-slice sprites and repointing them from the JSON UI container screens, which are still data-driven in the shipped vanilla pack.", + "mechanism": "Bedrock has no per-container GUI sheet; container screens are assembled from shared nine-slice sprites in `textures/ui/` — `dialog_background_opaque.png`, `dialog_background_hollow_1..8.png`, `cell_image.png`, `item_cell.png`, `highlight_slot.png`, `hotbar_start_cap.png`/`hotbar_end_cap.png`, each with a companion `.json` nine-slice descriptor. Textures are overridden by path, so same-named PNGs in the pack replace vanilla. To keep the black tint scoped to inventories instead of every dialog in the game, add the recoloured PNGs under a new path and repoint them from `ui/inventory_screen.json`, `ui/inventory_screen_pocket.json`, `ui/chest_screen.json` and `ui/pocket_containers.json` using the JSON UI `modifications` property, or tint the existing sprites in place with the JSON UI `color` property.", + "caveats": "The sprites are reused by the pause menu, chat and every other JSON UI dialog, so a naive in-place retexture bleeds outside containers unless the screen files are repointed. Ore UI screens (main menu, settings, marketplace, world creation) cannot be recoloured at all, and the Bedrock Wiki states JSON UI is being deprecated in favour of Ore UI, so JSON UI edits carry long-term breakage risk. Touch/pocket layouts need the `_pocket` screen variants covered separately. A black background needs a contrast check against the white slot/item-count text.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvBrown": { + "verdict": "possible", + "confidence": "medium", + "summary": "A brown container UI is reproducible by recolouring the `textures/ui/` nine-slice sprites and repointing them from the JSON UI container screens, which are still data-driven in the shipped vanilla pack.", + "mechanism": "Bedrock has no per-container GUI sheet; container screens are assembled from shared nine-slice sprites in `textures/ui/` — `dialog_background_opaque.png`, `dialog_background_hollow_1..8.png`, `cell_image.png`, `item_cell.png`, `highlight_slot.png`, `hotbar_start_cap.png`/`hotbar_end_cap.png`, each with a companion `.json` nine-slice descriptor. Textures are overridden by path, so same-named PNGs in the pack replace vanilla. To keep the brown tint scoped to inventories instead of every dialog in the game, add the recoloured PNGs under a new path and repoint them from `ui/inventory_screen.json`, `ui/inventory_screen_pocket.json`, `ui/chest_screen.json` and `ui/pocket_containers.json` using the JSON UI `modifications` property, or tint the existing sprites in place with the JSON UI `color` property.", + "caveats": "The sprites are reused by the pause menu, chat and every other JSON UI dialog, so a naive in-place retexture bleeds outside containers unless the screen files are repointed. Ore UI screens (main menu, settings, marketplace, world creation) cannot be recoloured at all, and the Bedrock Wiki states JSON UI is being deprecated in favour of Ore UI, so JSON UI edits carry long-term breakage risk. Touch/pocket layouts need the `_pocket` screen variants covered separately.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvRed": { + "verdict": "possible", + "confidence": "medium", + "summary": "A red container UI is reproducible by recolouring the `textures/ui/` nine-slice sprites and repointing them from the JSON UI container screens, which are still data-driven in the shipped vanilla pack.", + "mechanism": "Bedrock has no per-container GUI sheet; container screens are assembled from shared nine-slice sprites in `textures/ui/` — `dialog_background_opaque.png`, `dialog_background_hollow_1..8.png`, `cell_image.png`, `item_cell.png`, `highlight_slot.png`, `hotbar_start_cap.png`/`hotbar_end_cap.png`, each with a companion `.json` nine-slice descriptor. Textures are overridden by path, so same-named PNGs in the pack replace vanilla. To keep the red tint scoped to inventories instead of every dialog in the game, add the recoloured PNGs under a new path and repoint them from `ui/inventory_screen.json`, `ui/inventory_screen_pocket.json`, `ui/chest_screen.json` and `ui/pocket_containers.json` using the JSON UI `modifications` property, or tint the existing sprites in place with the JSON UI `color` property.", + "caveats": "The sprites are reused by the pause menu, chat and every other JSON UI dialog, so a naive in-place retexture bleeds outside containers unless the screen files are repointed. Ore UI screens (main menu, settings, marketplace, world creation) cannot be recoloured at all, and the Bedrock Wiki states JSON UI is being deprecated in favour of Ore UI, so JSON UI edits carry long-term breakage risk. Touch/pocket layouts need the `_pocket` screen variants covered separately. Red risks colliding with `cell_image_red.png`, which vanilla uses to flag invalid slots.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvOrange": { + "verdict": "possible", + "confidence": "medium", + "summary": "An orange container UI is reproducible by recolouring the `textures/ui/` nine-slice sprites and repointing them from the JSON UI container screens, which are still data-driven in the shipped vanilla pack.", + "mechanism": "Bedrock has no per-container GUI sheet; container screens are assembled from shared nine-slice sprites in `textures/ui/` — `dialog_background_opaque.png`, `dialog_background_hollow_1..8.png`, `cell_image.png`, `item_cell.png`, `highlight_slot.png`, `hotbar_start_cap.png`/`hotbar_end_cap.png`, each with a companion `.json` nine-slice descriptor. Textures are overridden by path, so same-named PNGs in the pack replace vanilla. To keep the orange tint scoped to inventories instead of every dialog in the game, add the recoloured PNGs under a new path and repoint them from `ui/inventory_screen.json`, `ui/inventory_screen_pocket.json`, `ui/chest_screen.json` and `ui/pocket_containers.json` using the JSON UI `modifications` property, or tint the existing sprites in place with the JSON UI `color` property.", + "caveats": "The sprites are reused by the pause menu, chat and every other JSON UI dialog, so a naive in-place retexture bleeds outside containers unless the screen files are repointed. Ore UI screens (main menu, settings, marketplace, world creation) cannot be recoloured at all, and the Bedrock Wiki states JSON UI is being deprecated in favour of Ore UI, so JSON UI edits carry long-term breakage risk. Touch/pocket layouts need the `_pocket` screen variants covered separately.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvYellow": { + "verdict": "possible", + "confidence": "medium", + "summary": "A yellow container UI is reproducible by recolouring the `textures/ui/` nine-slice sprites and repointing them from the JSON UI container screens, which are still data-driven in the shipped vanilla pack.", + "mechanism": "Bedrock has no per-container GUI sheet; container screens are assembled from shared nine-slice sprites in `textures/ui/` — `dialog_background_opaque.png`, `dialog_background_hollow_1..8.png`, `cell_image.png`, `item_cell.png`, `highlight_slot.png`, `hotbar_start_cap.png`/`hotbar_end_cap.png`, each with a companion `.json` nine-slice descriptor. Textures are overridden by path, so same-named PNGs in the pack replace vanilla. To keep the yellow tint scoped to inventories instead of every dialog in the game, add the recoloured PNGs under a new path and repoint them from `ui/inventory_screen.json`, `ui/inventory_screen_pocket.json`, `ui/chest_screen.json` and `ui/pocket_containers.json` using the JSON UI `modifications` property, or tint the existing sprites in place with the JSON UI `color` property.", + "caveats": "The sprites are reused by the pause menu, chat and every other JSON UI dialog, so a naive in-place retexture bleeds outside containers unless the screen files are repointed. Ore UI screens (main menu, settings, marketplace, world creation) cannot be recoloured at all, and the Bedrock Wiki states JSON UI is being deprecated in favour of Ore UI, so JSON UI edits carry long-term breakage risk. Touch/pocket layouts need the `_pocket` screen variants covered separately. A light yellow background needs a contrast check against the white slot/item-count text.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvLime": { + "verdict": "possible", + "confidence": "medium", + "summary": "A lime container UI is reproducible by recolouring the `textures/ui/` nine-slice sprites and repointing them from the JSON UI container screens, which are still data-driven in the shipped vanilla pack.", + "mechanism": "Bedrock has no per-container GUI sheet; container screens are assembled from shared nine-slice sprites in `textures/ui/` — `dialog_background_opaque.png`, `dialog_background_hollow_1..8.png`, `cell_image.png`, `item_cell.png`, `highlight_slot.png`, `hotbar_start_cap.png`/`hotbar_end_cap.png`, each with a companion `.json` nine-slice descriptor. Textures are overridden by path, so same-named PNGs in the pack replace vanilla. To keep the lime tint scoped to inventories instead of every dialog in the game, add the recoloured PNGs under a new path and repoint them from `ui/inventory_screen.json`, `ui/inventory_screen_pocket.json`, `ui/chest_screen.json` and `ui/pocket_containers.json` using the JSON UI `modifications` property, or tint the existing sprites in place with the JSON UI `color` property.", + "caveats": "The sprites are reused by the pause menu, chat and every other JSON UI dialog, so a naive in-place retexture bleeds outside containers unless the screen files are repointed. Ore UI screens (main menu, settings, marketplace, world creation) cannot be recoloured at all, and the Bedrock Wiki states JSON UI is being deprecated in favour of Ore UI, so JSON UI edits carry long-term breakage risk. Touch/pocket layouts need the `_pocket` screen variants covered separately. A light lime background needs a contrast check against the white slot/item-count text.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvGreen": { + "verdict": "possible", + "confidence": "medium", + "summary": "A green container UI is reproducible by recolouring the `textures/ui/` nine-slice sprites and repointing them from the JSON UI container screens, which are still data-driven in the shipped vanilla pack.", + "mechanism": "Bedrock has no per-container GUI sheet; container screens are assembled from shared nine-slice sprites in `textures/ui/` — `dialog_background_opaque.png`, `dialog_background_hollow_1..8.png`, `cell_image.png`, `item_cell.png`, `highlight_slot.png`, `hotbar_start_cap.png`/`hotbar_end_cap.png`, each with a companion `.json` nine-slice descriptor. Textures are overridden by path, so same-named PNGs in the pack replace vanilla. To keep the green tint scoped to inventories instead of every dialog in the game, add the recoloured PNGs under a new path and repoint them from `ui/inventory_screen.json`, `ui/inventory_screen_pocket.json`, `ui/chest_screen.json` and `ui/pocket_containers.json` using the JSON UI `modifications` property, or tint the existing sprites in place with the JSON UI `color` property.", + "caveats": "The sprites are reused by the pause menu, chat and every other JSON UI dialog, so a naive in-place retexture bleeds outside containers unless the screen files are repointed. Ore UI screens (main menu, settings, marketplace, world creation) cannot be recoloured at all, and the Bedrock Wiki states JSON UI is being deprecated in favour of Ore UI, so JSON UI edits carry long-term breakage risk. Touch/pocket layouts need the `_pocket` screen variants covered separately.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvCyan": { + "verdict": "possible", + "confidence": "medium", + "summary": "A cyan container UI is reproducible by recolouring the `textures/ui/` nine-slice sprites and repointing them from the JSON UI container screens, which are still data-driven in the shipped vanilla pack.", + "mechanism": "Bedrock has no per-container GUI sheet; container screens are assembled from shared nine-slice sprites in `textures/ui/` — `dialog_background_opaque.png`, `dialog_background_hollow_1..8.png`, `cell_image.png`, `item_cell.png`, `highlight_slot.png`, `hotbar_start_cap.png`/`hotbar_end_cap.png`, each with a companion `.json` nine-slice descriptor. Textures are overridden by path, so same-named PNGs in the pack replace vanilla. To keep the cyan tint scoped to inventories instead of every dialog in the game, add the recoloured PNGs under a new path and repoint them from `ui/inventory_screen.json`, `ui/inventory_screen_pocket.json`, `ui/chest_screen.json` and `ui/pocket_containers.json` using the JSON UI `modifications` property, or tint the existing sprites in place with the JSON UI `color` property.", + "caveats": "The sprites are reused by the pause menu, chat and every other JSON UI dialog, so a naive in-place retexture bleeds outside containers unless the screen files are repointed. Ore UI screens (main menu, settings, marketplace, world creation) cannot be recoloured at all, and the Bedrock Wiki states JSON UI is being deprecated in favour of Ore UI, so JSON UI edits carry long-term breakage risk. Touch/pocket layouts need the `_pocket` screen variants covered separately.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvLightBlue": { + "verdict": "possible", + "confidence": "medium", + "summary": "Doable as a resource pack, but not a straight texture swap: Bedrock draws every container from one shared nine-slice panel, so a light blue tint needs recoloured `textures/ui/` sprites plus JSON UI screen overrides to keep the tint on containers only.", + "mechanism": "Bedrock container GUIs are JSON UI screens, not Java-style `gui/container/*.png` sheets. The panel behind every container comes from `common.common_panel` in `ui/ui_common.json`, whose `$dialog_background` variable defaults to `common.dialog_background_opaque` -> `textures/ui/dialog_background_opaque.png` (a nine-slice; its sidecar `dialog_background_opaque.json` declares `nineslice_size: 4`, `base_size: [16,16]`). Item slots come from `textures/ui/item_cell.png` and `textures/ui/cell_image*.png`, and `ui/inventory_screen.json` additionally uses `textures/ui/dialog_background_opaque_overlap_bottom`. A minimal port ships recoloured PNGs at those exact paths (Microsoft Learn: textures and binary assets are overwritten by matching path). To scope the tint to containers instead of every dialog, also ship `ui/_ui_defs.json` plus overrides for the container screens (`ui/inventory_screen.json`, `ui/chest_screen.json`, `ui/furnace_screen.json`, `ui/anvil_screen.json`, `ui/brewing_stand_screen.json`, ... and their `*_screen_pocket.json` touch twins) that repoint `$dialog_background` at a custom light-blue element, using the JSON UI `modifications` property for pack compatibility.", + "caveats": "`dialog_background_opaque` is shared by the pause menu, settings and most non-container dialogs, so a texture-only pack recolours far more than the Java version does; scoping it properly means JSON UI overrides across roughly 25 desktop screens plus their `_pocket` variants. Bedrock's container art is a dark rounded panel, not Java's beige sheet, so the result re-tints Bedrock's own look rather than porting Java pixels. JSON UI overrides are version-fragile and break when Mojang restructures `ui_common.json`. Vanilla Tweaks itself marks this category WIP/EXPERIMENTAL.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/textures/ui/dialog_background_opaque.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/reference/content/jsonuireference/examples/jsonuicomponents/ui_defs" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvBlue": { + "verdict": "possible", + "confidence": "medium", + "summary": "Doable as a resource pack, but not a straight texture swap: Bedrock draws every container from one shared nine-slice panel, so a blue tint needs recoloured `textures/ui/` sprites plus JSON UI screen overrides to keep the tint on containers only.", + "mechanism": "Bedrock container GUIs are JSON UI screens, not Java-style `gui/container/*.png` sheets. The panel behind every container comes from `common.common_panel` in `ui/ui_common.json`, whose `$dialog_background` variable defaults to `common.dialog_background_opaque` -> `textures/ui/dialog_background_opaque.png` (a nine-slice; its sidecar `dialog_background_opaque.json` declares `nineslice_size: 4`, `base_size: [16,16]`). Item slots come from `textures/ui/item_cell.png` and `textures/ui/cell_image*.png`, and `ui/inventory_screen.json` additionally uses `textures/ui/dialog_background_opaque_overlap_bottom`. A minimal port ships recoloured PNGs at those exact paths (Microsoft Learn: textures and binary assets are overwritten by matching path). To scope the tint to containers instead of every dialog, also ship `ui/_ui_defs.json` plus overrides for the container screens (`ui/inventory_screen.json`, `ui/chest_screen.json`, `ui/furnace_screen.json`, `ui/anvil_screen.json`, `ui/brewing_stand_screen.json`, ... and their `*_screen_pocket.json` touch twins) that repoint `$dialog_background` at a custom blue element, using the JSON UI `modifications` property for pack compatibility.", + "caveats": "`dialog_background_opaque` is shared by the pause menu, settings and most non-container dialogs, so a texture-only pack recolours far more than the Java version does; scoping it properly means JSON UI overrides across roughly 25 desktop screens plus their `_pocket` variants. Bedrock's container art is a dark rounded panel, not Java's beige sheet, so the result re-tints Bedrock's own look rather than porting Java pixels. JSON UI overrides are version-fragile and break when Mojang restructures `ui_common.json`. Vanilla Tweaks itself marks this category WIP/EXPERIMENTAL.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/textures/ui/dialog_background_opaque.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/reference/content/jsonuireference/examples/jsonuicomponents/ui_defs" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvPurple": { + "verdict": "possible", + "confidence": "medium", + "summary": "Doable as a resource pack, but not a straight texture swap: Bedrock draws every container from one shared nine-slice panel, so a purple tint needs recoloured `textures/ui/` sprites plus JSON UI screen overrides to keep the tint on containers only.", + "mechanism": "Bedrock container GUIs are JSON UI screens, not Java-style `gui/container/*.png` sheets. The panel behind every container comes from `common.common_panel` in `ui/ui_common.json`, whose `$dialog_background` variable defaults to `common.dialog_background_opaque` -> `textures/ui/dialog_background_opaque.png` (a nine-slice; its sidecar `dialog_background_opaque.json` declares `nineslice_size: 4`, `base_size: [16,16]`). Item slots come from `textures/ui/item_cell.png` and `textures/ui/cell_image*.png`, and `ui/inventory_screen.json` additionally uses `textures/ui/dialog_background_opaque_overlap_bottom`. A minimal port ships recoloured PNGs at those exact paths (Microsoft Learn: textures and binary assets are overwritten by matching path). To scope the tint to containers instead of every dialog, also ship `ui/_ui_defs.json` plus overrides for the container screens (`ui/inventory_screen.json`, `ui/chest_screen.json`, `ui/furnace_screen.json`, `ui/anvil_screen.json`, `ui/brewing_stand_screen.json`, ... and their `*_screen_pocket.json` touch twins) that repoint `$dialog_background` at a custom purple element, using the JSON UI `modifications` property for pack compatibility.", + "caveats": "`dialog_background_opaque` is shared by the pause menu, settings and most non-container dialogs, so a texture-only pack recolours far more than the Java version does; scoping it properly means JSON UI overrides across roughly 25 desktop screens plus their `_pocket` variants. Bedrock's container art is a dark rounded panel, not Java's beige sheet, so the result re-tints Bedrock's own look rather than porting Java pixels. JSON UI overrides are version-fragile and break when Mojang restructures `ui_common.json`. Vanilla Tweaks itself marks this category WIP/EXPERIMENTAL.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/textures/ui/dialog_background_opaque.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/reference/content/jsonuireference/examples/jsonuicomponents/ui_defs" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvMagenta": { + "verdict": "possible", + "confidence": "medium", + "summary": "Doable as a resource pack, but not a straight texture swap: Bedrock draws every container from one shared nine-slice panel, so a magenta tint needs recoloured `textures/ui/` sprites plus JSON UI screen overrides to keep the tint on containers only.", + "mechanism": "Bedrock container GUIs are JSON UI screens, not Java-style `gui/container/*.png` sheets. The panel behind every container comes from `common.common_panel` in `ui/ui_common.json`, whose `$dialog_background` variable defaults to `common.dialog_background_opaque` -> `textures/ui/dialog_background_opaque.png` (a nine-slice; its sidecar `dialog_background_opaque.json` declares `nineslice_size: 4`, `base_size: [16,16]`). Item slots come from `textures/ui/item_cell.png` and `textures/ui/cell_image*.png`, and `ui/inventory_screen.json` additionally uses `textures/ui/dialog_background_opaque_overlap_bottom`. A minimal port ships recoloured PNGs at those exact paths (Microsoft Learn: textures and binary assets are overwritten by matching path). To scope the tint to containers instead of every dialog, also ship `ui/_ui_defs.json` plus overrides for the container screens (`ui/inventory_screen.json`, `ui/chest_screen.json`, `ui/furnace_screen.json`, `ui/anvil_screen.json`, `ui/brewing_stand_screen.json`, ... and their `*_screen_pocket.json` touch twins) that repoint `$dialog_background` at a custom magenta element, using the JSON UI `modifications` property for pack compatibility.", + "caveats": "`dialog_background_opaque` is shared by the pause menu, settings and most non-container dialogs, so a texture-only pack recolours far more than the Java version does; scoping it properly means JSON UI overrides across roughly 25 desktop screens plus their `_pocket` variants. Bedrock's container art is a dark rounded panel, not Java's beige sheet, so the result re-tints Bedrock's own look rather than porting Java pixels. JSON UI overrides are version-fragile and break when Mojang restructures `ui_common.json`. Vanilla Tweaks itself marks this category WIP/EXPERIMENTAL.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/textures/ui/dialog_background_opaque.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/reference/content/jsonuireference/examples/jsonuicomponents/ui_defs" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredInvPink": { + "verdict": "possible", + "confidence": "medium", + "summary": "Doable as a resource pack, but not a straight texture swap: Bedrock draws every container from one shared nine-slice panel, so a pink tint needs recoloured `textures/ui/` sprites plus JSON UI screen overrides to keep the tint on containers only.", + "mechanism": "Bedrock container GUIs are JSON UI screens, not Java-style `gui/container/*.png` sheets. The panel behind every container comes from `common.common_panel` in `ui/ui_common.json`, whose `$dialog_background` variable defaults to `common.dialog_background_opaque` -> `textures/ui/dialog_background_opaque.png` (a nine-slice; its sidecar `dialog_background_opaque.json` declares `nineslice_size: 4`, `base_size: [16,16]`). Item slots come from `textures/ui/item_cell.png` and `textures/ui/cell_image*.png`, and `ui/inventory_screen.json` additionally uses `textures/ui/dialog_background_opaque_overlap_bottom`. A minimal port ships recoloured PNGs at those exact paths (Microsoft Learn: textures and binary assets are overwritten by matching path). To scope the tint to containers instead of every dialog, also ship `ui/_ui_defs.json` plus overrides for the container screens (`ui/inventory_screen.json`, `ui/chest_screen.json`, `ui/furnace_screen.json`, `ui/anvil_screen.json`, `ui/brewing_stand_screen.json`, ... and their `*_screen_pocket.json` touch twins) that repoint `$dialog_background` at a custom pink element, using the JSON UI `modifications` property for pack compatibility.", + "caveats": "`dialog_background_opaque` is shared by the pause menu, settings and most non-container dialogs, so a texture-only pack recolours far more than the Java version does; scoping it properly means JSON UI overrides across roughly 25 desktop screens plus their `_pocket` variants. Bedrock's container art is a dark rounded panel, not Java's beige sheet, so the result re-tints Bedrock's own look rather than porting Java pixels. JSON UI overrides are version-fragile and break when Mojang restructures `ui_common.json`. Vanilla Tweaks itself marks this category WIP/EXPERIMENTAL.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/textures/ui/dialog_background_opaque.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/reference/content/jsonuireference/examples/jsonuicomponents/ui_defs" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsGray": { + "verdict": "possible", + "confidence": "high", + "summary": "Plain texture-only resource pack: drop gray-recoloured hotbar and button PNGs into `textures/ui/` — the same one-file-per-variant technique this repo already uses for `hotbar_selector`.", + "mechanism": "Java's single `gui/widgets.png` atlas maps onto a set of individual Bedrock PNGs, all overridable by path with no JSON UI work. `ui/hud_screen.json` draws the hotbar from `textures/ui/hotbar_start_cap.png`, `textures/ui/hotbar_end_cap.png` and `textures/ui/hotbar_0.png` through `hotbar_8.png`, and the selection box from `textures/ui/selected_hotbar_slot.png`. Widget buttons come from `textures/ui/NormalButtonStroke.png`, `NormalButtonNoStroke.png`, `NormalButtonThin.png` and `button_borderless_light*.png`, all defined in `ui/ui_common.json`. Microsoft Learn states textures and binary assets (.png) are overwritten simply by placing the custom asset at the same path, so the pack is just recoloured PNGs under `textures/ui/` — keeping each sprite's nine-slice `.json` sidecar (e.g. `hotbar_start_cap.json`, `NormalButtonStroke.json`) intact so the stretch regions still line up.", + "caveats": "Java's one `widgets.png` has no 1:1 Bedrock file, so decide up front whether the pack covers only the hotbar or the button widgets too — the two live in different sprite sets. Bedrock's button textures are shared with the main menu, settings and pause screen, so recolouring them tints those screens as well. Touch/pocket UI uses extra sprites (`pocket_ui_highlight_slot.png`, `slot_enabled_pocket.png`, `slot_disabled_pocket.png`) that need matching art for cross-platform parity.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/hud_screen.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsBlack": { + "verdict": "possible", + "confidence": "high", + "summary": "Plain texture-only resource pack: drop black-recoloured hotbar and button PNGs into `textures/ui/` — the same one-file-per-variant technique this repo already uses for `hotbar_selector`.", + "mechanism": "Java's single `gui/widgets.png` atlas maps onto a set of individual Bedrock PNGs, all overridable by path with no JSON UI work. `ui/hud_screen.json` draws the hotbar from `textures/ui/hotbar_start_cap.png`, `textures/ui/hotbar_end_cap.png` and `textures/ui/hotbar_0.png` through `hotbar_8.png`, and the selection box from `textures/ui/selected_hotbar_slot.png`. Widget buttons come from `textures/ui/NormalButtonStroke.png`, `NormalButtonNoStroke.png`, `NormalButtonThin.png` and `button_borderless_light*.png`, all defined in `ui/ui_common.json`. Microsoft Learn states textures and binary assets (.png) are overwritten simply by placing the custom asset at the same path, so the pack is just recoloured PNGs under `textures/ui/` — keeping each sprite's nine-slice `.json` sidecar (e.g. `hotbar_start_cap.json`, `NormalButtonStroke.json`) intact so the stretch regions still line up.", + "caveats": "Java's one `widgets.png` has no 1:1 Bedrock file, so decide up front whether the pack covers only the hotbar or the button widgets too — the two live in different sprite sets. Bedrock's button textures are shared with the main menu, settings and pause screen, so recolouring them tints those screens as well. Touch/pocket UI uses extra sprites (`pocket_ui_highlight_slot.png`, `slot_enabled_pocket.png`, `slot_disabled_pocket.png`) that need matching art for cross-platform parity.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/hud_screen.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsBrown": { + "verdict": "possible", + "confidence": "high", + "summary": "Plain texture-only resource pack: drop brown-recoloured hotbar and button PNGs into `textures/ui/` — the same one-file-per-variant technique this repo already uses for `hotbar_selector`.", + "mechanism": "Java's single `gui/widgets.png` atlas maps onto a set of individual Bedrock PNGs, all overridable by path with no JSON UI work. `ui/hud_screen.json` draws the hotbar from `textures/ui/hotbar_start_cap.png`, `textures/ui/hotbar_end_cap.png` and `textures/ui/hotbar_0.png` through `hotbar_8.png`, and the selection box from `textures/ui/selected_hotbar_slot.png`. Widget buttons come from `textures/ui/NormalButtonStroke.png`, `NormalButtonNoStroke.png`, `NormalButtonThin.png` and `button_borderless_light*.png`, all defined in `ui/ui_common.json`. Microsoft Learn states textures and binary assets (.png) are overwritten simply by placing the custom asset at the same path, so the pack is just recoloured PNGs under `textures/ui/` — keeping each sprite's nine-slice `.json` sidecar (e.g. `hotbar_start_cap.json`, `NormalButtonStroke.json`) intact so the stretch regions still line up.", + "caveats": "Java's one `widgets.png` has no 1:1 Bedrock file, so decide up front whether the pack covers only the hotbar or the button widgets too — the two live in different sprite sets. Bedrock's button textures are shared with the main menu, settings and pause screen, so recolouring them tints those screens as well. Touch/pocket UI uses extra sprites (`pocket_ui_highlight_slot.png`, `slot_enabled_pocket.png`, `slot_disabled_pocket.png`) that need matching art for cross-platform parity.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/hud_screen.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsRed": { + "verdict": "possible", + "confidence": "high", + "summary": "Plain texture-only resource pack: drop red-recoloured hotbar and button PNGs into `textures/ui/` — the same one-file-per-variant technique this repo already uses for `hotbar_selector`.", + "mechanism": "Java's single `gui/widgets.png` atlas maps onto a set of individual Bedrock PNGs, all overridable by path with no JSON UI work. `ui/hud_screen.json` draws the hotbar from `textures/ui/hotbar_start_cap.png`, `textures/ui/hotbar_end_cap.png` and `textures/ui/hotbar_0.png` through `hotbar_8.png`, and the selection box from `textures/ui/selected_hotbar_slot.png`. Widget buttons come from `textures/ui/NormalButtonStroke.png`, `NormalButtonNoStroke.png`, `NormalButtonThin.png` and `button_borderless_light*.png`, all defined in `ui/ui_common.json`. Microsoft Learn states textures and binary assets (.png) are overwritten simply by placing the custom asset at the same path, so the pack is just recoloured PNGs under `textures/ui/` — keeping each sprite's nine-slice `.json` sidecar (e.g. `hotbar_start_cap.json`, `NormalButtonStroke.json`) intact so the stretch regions still line up.", + "caveats": "Java's one `widgets.png` has no 1:1 Bedrock file, so decide up front whether the pack covers only the hotbar or the button widgets too — the two live in different sprite sets. Bedrock's button textures are shared with the main menu, settings and pause screen, so recolouring them tints those screens as well. Touch/pocket UI uses extra sprites (`pocket_ui_highlight_slot.png`, `slot_enabled_pocket.png`, `slot_disabled_pocket.png`) that need matching art for cross-platform parity.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/hud_screen.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsOrange": { + "verdict": "possible", + "confidence": "high", + "summary": "Plain texture-only resource pack: drop orange-recoloured hotbar and button PNGs into `textures/ui/` — the same one-file-per-variant technique this repo already uses for `hotbar_selector`.", + "mechanism": "Java's single `gui/widgets.png` atlas maps onto a set of individual Bedrock PNGs, all overridable by path with no JSON UI work. `ui/hud_screen.json` draws the hotbar from `textures/ui/hotbar_start_cap.png`, `textures/ui/hotbar_end_cap.png` and `textures/ui/hotbar_0.png` through `hotbar_8.png`, and the selection box from `textures/ui/selected_hotbar_slot.png`. Widget buttons come from `textures/ui/NormalButtonStroke.png`, `NormalButtonNoStroke.png`, `NormalButtonThin.png` and `button_borderless_light*.png`, all defined in `ui/ui_common.json`. Microsoft Learn states textures and binary assets (.png) are overwritten simply by placing the custom asset at the same path, so the pack is just recoloured PNGs under `textures/ui/` — keeping each sprite's nine-slice `.json` sidecar (e.g. `hotbar_start_cap.json`, `NormalButtonStroke.json`) intact so the stretch regions still line up.", + "caveats": "Java's one `widgets.png` has no 1:1 Bedrock file, so decide up front whether the pack covers only the hotbar or the button widgets too — the two live in different sprite sets. Bedrock's button textures are shared with the main menu, settings and pause screen, so recolouring them tints those screens as well. Touch/pocket UI uses extra sprites (`pocket_ui_highlight_slot.png`, `slot_enabled_pocket.png`, `slot_disabled_pocket.png`) that need matching art for cross-platform parity.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/hud_screen.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsYellow": { + "verdict": "partial", + "confidence": "medium", + "summary": "A resource pack can tint Bedrock's classic UI buttons yellow by replacing the textures/ui button PNGs, but the recolour only reaches screens still drawn by JSON UI - Ore UI screens such as the main menu and settings are hardcoded and stay vanilla.", + "mechanism": "Recolour the classic JSON UI button art in a resource pack: replace textures/ui/button_borderless_light.png, button_borderless_lighthover.png, button_borderless_lightpressed.png, button_borderless_lightpressednohover.png, the matching button_borderless_dark* set, disabledButtonNoBorder.png and NormalButtonNoStroke.png / NormalButtonStroke.png, keeping each PNG next to its existing .json nine-slice descriptor. Those exact filenames are the defaults declared in the vanilla ui/ui_template_buttons.json ($default_button_texture, $hover_button_texture, $pressed_button_texture, $locked_button_texture) and in ui/ui_common.json (common.normal_button, common.normal_stroke_button), so no JSON override is strictly needed; shipping ui/ui_template_buttons.json or ui/_global_variables.json is only required if you want to point the variables at new texture names or restyle the button label colours. This repo already proves the technique - resource_packs/files/gui/dark_ui ships NormalButtonNoStroke.png, NormalButtonStroke.png and an overridden ui/ui_template_buttons.json.", + "caveats": "Degraded versus Java, which recolours every button in the game. On Bedrock only screens still rendered by JSON UI pick the new art up (containers, chat, sign editor, classic dialogs); the Bedrock Wiki states plainly that JSON UI is being deprecated in favour of Ore UI and that \"Ore UI is hardcoded and cannot be modified by resource packs\", so the main menu, settings, play/world-list and any other already-migrated screen keep vanilla buttons. Bedrock also has no single widgets.png - the art is spread over roughly a dozen separate nine-sliced PNGs, and the hotbar is a separate texture set (textures/ui/hotbar_*.png, selected_hotbar_slot.png) already covered by the existing hotbar_selector packs.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_template_buttons.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsLime": { + "verdict": "partial", + "confidence": "medium", + "summary": "A resource pack can tint Bedrock's classic UI buttons lime by replacing the textures/ui button PNGs, but the recolour only reaches screens still drawn by JSON UI - Ore UI screens such as the main menu and settings are hardcoded and stay vanilla.", + "mechanism": "Recolour the classic JSON UI button art in a resource pack: replace textures/ui/button_borderless_light.png, button_borderless_lighthover.png, button_borderless_lightpressed.png, button_borderless_lightpressednohover.png, the matching button_borderless_dark* set, disabledButtonNoBorder.png and NormalButtonNoStroke.png / NormalButtonStroke.png, keeping each PNG next to its existing .json nine-slice descriptor. Those exact filenames are the defaults declared in the vanilla ui/ui_template_buttons.json ($default_button_texture, $hover_button_texture, $pressed_button_texture, $locked_button_texture) and in ui/ui_common.json (common.normal_button, common.normal_stroke_button), so no JSON override is strictly needed; shipping ui/ui_template_buttons.json or ui/_global_variables.json is only required if you want to point the variables at new texture names or restyle the button label colours. This repo already proves the technique - resource_packs/files/gui/dark_ui ships NormalButtonNoStroke.png, NormalButtonStroke.png and an overridden ui/ui_template_buttons.json.", + "caveats": "Degraded versus Java, which recolours every button in the game. On Bedrock only screens still rendered by JSON UI pick the new art up (containers, chat, sign editor, classic dialogs); the Bedrock Wiki states plainly that JSON UI is being deprecated in favour of Ore UI and that \"Ore UI is hardcoded and cannot be modified by resource packs\", so the main menu, settings, play/world-list and any other already-migrated screen keep vanilla buttons. Bedrock also has no single widgets.png - the art is spread over roughly a dozen separate nine-sliced PNGs, and the hotbar is a separate texture set (textures/ui/hotbar_*.png, selected_hotbar_slot.png) already covered by the existing hotbar_selector packs.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_template_buttons.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsGreen": { + "verdict": "partial", + "confidence": "medium", + "summary": "A resource pack can tint Bedrock's classic UI buttons green by replacing the textures/ui button PNGs, but the recolour only reaches screens still drawn by JSON UI - Ore UI screens such as the main menu and settings are hardcoded and stay vanilla.", + "mechanism": "Recolour the classic JSON UI button art in a resource pack: replace textures/ui/button_borderless_light.png, button_borderless_lighthover.png, button_borderless_lightpressed.png, button_borderless_lightpressednohover.png, the matching button_borderless_dark* set, disabledButtonNoBorder.png and NormalButtonNoStroke.png / NormalButtonStroke.png, keeping each PNG next to its existing .json nine-slice descriptor. Those exact filenames are the defaults declared in the vanilla ui/ui_template_buttons.json ($default_button_texture, $hover_button_texture, $pressed_button_texture, $locked_button_texture) and in ui/ui_common.json (common.normal_button, common.normal_stroke_button), so no JSON override is strictly needed; shipping ui/ui_template_buttons.json or ui/_global_variables.json is only required if you want to point the variables at new texture names or restyle the button label colours. This repo already proves the technique - resource_packs/files/gui/dark_ui ships NormalButtonNoStroke.png, NormalButtonStroke.png and an overridden ui/ui_template_buttons.json.", + "caveats": "Degraded versus Java, which recolours every button in the game. On Bedrock only screens still rendered by JSON UI pick the new art up (containers, chat, sign editor, classic dialogs); the Bedrock Wiki states plainly that JSON UI is being deprecated in favour of Ore UI and that \"Ore UI is hardcoded and cannot be modified by resource packs\", so the main menu, settings, play/world-list and any other already-migrated screen keep vanilla buttons. Bedrock also has no single widgets.png - the art is spread over roughly a dozen separate nine-sliced PNGs, and the hotbar is a separate texture set (textures/ui/hotbar_*.png, selected_hotbar_slot.png) already covered by the existing hotbar_selector packs.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_template_buttons.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsCyan": { + "verdict": "partial", + "confidence": "medium", + "summary": "A resource pack can tint Bedrock's classic UI buttons cyan by replacing the textures/ui button PNGs, but the recolour only reaches screens still drawn by JSON UI - Ore UI screens such as the main menu and settings are hardcoded and stay vanilla.", + "mechanism": "Recolour the classic JSON UI button art in a resource pack: replace textures/ui/button_borderless_light.png, button_borderless_lighthover.png, button_borderless_lightpressed.png, button_borderless_lightpressednohover.png, the matching button_borderless_dark* set, disabledButtonNoBorder.png and NormalButtonNoStroke.png / NormalButtonStroke.png, keeping each PNG next to its existing .json nine-slice descriptor. Those exact filenames are the defaults declared in the vanilla ui/ui_template_buttons.json ($default_button_texture, $hover_button_texture, $pressed_button_texture, $locked_button_texture) and in ui/ui_common.json (common.normal_button, common.normal_stroke_button), so no JSON override is strictly needed; shipping ui/ui_template_buttons.json or ui/_global_variables.json is only required if you want to point the variables at new texture names or restyle the button label colours. This repo already proves the technique - resource_packs/files/gui/dark_ui ships NormalButtonNoStroke.png, NormalButtonStroke.png and an overridden ui/ui_template_buttons.json.", + "caveats": "Degraded versus Java, which recolours every button in the game. On Bedrock only screens still rendered by JSON UI pick the new art up (containers, chat, sign editor, classic dialogs); the Bedrock Wiki states plainly that JSON UI is being deprecated in favour of Ore UI and that \"Ore UI is hardcoded and cannot be modified by resource packs\", so the main menu, settings, play/world-list and any other already-migrated screen keep vanilla buttons. Bedrock also has no single widgets.png - the art is spread over roughly a dozen separate nine-sliced PNGs, and the hotbar is a separate texture set (textures/ui/hotbar_*.png, selected_hotbar_slot.png) already covered by the existing hotbar_selector packs.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_template_buttons.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsLightBlue": { + "verdict": "partial", + "confidence": "medium", + "summary": "A resource pack can tint Bedrock's classic UI buttons light blue by replacing the textures/ui button PNGs, but the recolour only reaches screens still drawn by JSON UI - Ore UI screens such as the main menu and settings are hardcoded and stay vanilla.", + "mechanism": "Recolour the classic JSON UI button art in a resource pack: replace textures/ui/button_borderless_light.png, button_borderless_lighthover.png, button_borderless_lightpressed.png, button_borderless_lightpressednohover.png, the matching button_borderless_dark* set, disabledButtonNoBorder.png and NormalButtonNoStroke.png / NormalButtonStroke.png, keeping each PNG next to its existing .json nine-slice descriptor. Those exact filenames are the defaults declared in the vanilla ui/ui_template_buttons.json ($default_button_texture, $hover_button_texture, $pressed_button_texture, $locked_button_texture) and in ui/ui_common.json (common.normal_button, common.normal_stroke_button), so no JSON override is strictly needed; shipping ui/ui_template_buttons.json or ui/_global_variables.json is only required if you want to point the variables at new texture names or restyle the button label colours. This repo already proves the technique - resource_packs/files/gui/dark_ui ships NormalButtonNoStroke.png, NormalButtonStroke.png and an overridden ui/ui_template_buttons.json.", + "caveats": "Degraded versus Java, which recolours every button in the game. On Bedrock only screens still rendered by JSON UI pick the new art up (containers, chat, sign editor, classic dialogs); the Bedrock Wiki states plainly that JSON UI is being deprecated in favour of Ore UI and that \"Ore UI is hardcoded and cannot be modified by resource packs\", so the main menu, settings, play/world-list and any other already-migrated screen keep vanilla buttons. Bedrock also has no single widgets.png - the art is spread over roughly a dozen separate nine-sliced PNGs, and the hotbar is a separate texture set (textures/ui/hotbar_*.png, selected_hotbar_slot.png) already covered by the existing hotbar_selector packs.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_template_buttons.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsBlue": { + "verdict": "partial", + "confidence": "medium", + "summary": "A resource pack can tint Bedrock's classic UI buttons blue by replacing the textures/ui button PNGs, but the recolour only reaches screens still drawn by JSON UI - Ore UI screens such as the main menu and settings are hardcoded and stay vanilla.", + "mechanism": "Recolour the classic JSON UI button art in a resource pack: replace textures/ui/button_borderless_light.png, button_borderless_lighthover.png, button_borderless_lightpressed.png, button_borderless_lightpressednohover.png, the matching button_borderless_dark* set, disabledButtonNoBorder.png and NormalButtonNoStroke.png / NormalButtonStroke.png, keeping each PNG next to its existing .json nine-slice descriptor. Those exact filenames are the defaults declared in the vanilla ui/ui_template_buttons.json ($default_button_texture, $hover_button_texture, $pressed_button_texture, $locked_button_texture) and in ui/ui_common.json (common.normal_button, common.normal_stroke_button), so no JSON override is strictly needed; shipping ui/ui_template_buttons.json or ui/_global_variables.json is only required if you want to point the variables at new texture names or restyle the button label colours. This repo already proves the technique - resource_packs/files/gui/dark_ui ships NormalButtonNoStroke.png, NormalButtonStroke.png and an overridden ui/ui_template_buttons.json.", + "caveats": "Degraded versus Java, which recolours every button in the game. On Bedrock only screens still rendered by JSON UI pick the new art up (containers, chat, sign editor, classic dialogs); the Bedrock Wiki states plainly that JSON UI is being deprecated in favour of Ore UI and that \"Ore UI is hardcoded and cannot be modified by resource packs\", so the main menu, settings, play/world-list and any other already-migrated screen keep vanilla buttons. Bedrock also has no single widgets.png - the art is spread over roughly a dozen separate nine-sliced PNGs, and the hotbar is a separate texture set (textures/ui/hotbar_*.png, selected_hotbar_slot.png) already covered by the existing hotbar_selector packs.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_template_buttons.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsPurple": { + "verdict": "partial", + "confidence": "medium", + "summary": "A resource pack can tint Bedrock's classic UI buttons purple by replacing the textures/ui button PNGs, but the recolour only reaches screens still drawn by JSON UI - Ore UI screens such as the main menu and settings are hardcoded and stay vanilla.", + "mechanism": "Recolour the classic JSON UI button art in a resource pack: replace textures/ui/button_borderless_light.png, button_borderless_lighthover.png, button_borderless_lightpressed.png, button_borderless_lightpressednohover.png, the matching button_borderless_dark* set, disabledButtonNoBorder.png and NormalButtonNoStroke.png / NormalButtonStroke.png, keeping each PNG next to its existing .json nine-slice descriptor. Those exact filenames are the defaults declared in the vanilla ui/ui_template_buttons.json ($default_button_texture, $hover_button_texture, $pressed_button_texture, $locked_button_texture) and in ui/ui_common.json (common.normal_button, common.normal_stroke_button), so no JSON override is strictly needed; shipping ui/ui_template_buttons.json or ui/_global_variables.json is only required if you want to point the variables at new texture names or restyle the button label colours. This repo already proves the technique - resource_packs/files/gui/dark_ui ships NormalButtonNoStroke.png, NormalButtonStroke.png and an overridden ui/ui_template_buttons.json.", + "caveats": "Degraded versus Java, which recolours every button in the game. On Bedrock only screens still rendered by JSON UI pick the new art up (containers, chat, sign editor, classic dialogs); the Bedrock Wiki states plainly that JSON UI is being deprecated in favour of Ore UI and that \"Ore UI is hardcoded and cannot be modified by resource packs\", so the main menu, settings, play/world-list and any other already-migrated screen keep vanilla buttons. Bedrock also has no single widgets.png - the art is spread over roughly a dozen separate nine-sliced PNGs, and the hotbar is a separate texture set (textures/ui/hotbar_*.png, selected_hotbar_slot.png) already covered by the existing hotbar_selector packs.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_template_buttons.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsMagenta": { + "verdict": "partial", + "confidence": "medium", + "summary": "A resource pack can tint Bedrock's classic UI buttons magenta by replacing the textures/ui button PNGs, but the recolour only reaches screens still drawn by JSON UI - Ore UI screens such as the main menu and settings are hardcoded and stay vanilla.", + "mechanism": "Recolour the classic JSON UI button art in a resource pack: replace textures/ui/button_borderless_light.png, button_borderless_lighthover.png, button_borderless_lightpressed.png, button_borderless_lightpressednohover.png, the matching button_borderless_dark* set, disabledButtonNoBorder.png and NormalButtonNoStroke.png / NormalButtonStroke.png, keeping each PNG next to its existing .json nine-slice descriptor. Those exact filenames are the defaults declared in the vanilla ui/ui_template_buttons.json ($default_button_texture, $hover_button_texture, $pressed_button_texture, $locked_button_texture) and in ui/ui_common.json (common.normal_button, common.normal_stroke_button), so no JSON override is strictly needed; shipping ui/ui_template_buttons.json or ui/_global_variables.json is only required if you want to point the variables at new texture names or restyle the button label colours. This repo already proves the technique - resource_packs/files/gui/dark_ui ships NormalButtonNoStroke.png, NormalButtonStroke.png and an overridden ui/ui_template_buttons.json.", + "caveats": "Degraded versus Java, which recolours every button in the game. On Bedrock only screens still rendered by JSON UI pick the new art up (containers, chat, sign editor, classic dialogs); the Bedrock Wiki states plainly that JSON UI is being deprecated in favour of Ore UI and that \"Ore UI is hardcoded and cannot be modified by resource packs\", so the main menu, settings, play/world-list and any other already-migrated screen keep vanilla buttons. Bedrock also has no single widgets.png - the art is spread over roughly a dozen separate nine-sliced PNGs, and the hotbar is a separate texture set (textures/ui/hotbar_*.png, selected_hotbar_slot.png) already covered by the existing hotbar_selector packs.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_template_buttons.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredWidgetsPink": { + "verdict": "partial", + "confidence": "medium", + "summary": "A resource pack can tint Bedrock's classic UI buttons pink by replacing the textures/ui button PNGs, but the recolour only reaches screens still drawn by JSON UI - Ore UI screens such as the main menu and settings are hardcoded and stay vanilla.", + "mechanism": "Recolour the classic JSON UI button art in a resource pack: replace textures/ui/button_borderless_light.png, button_borderless_lighthover.png, button_borderless_lightpressed.png, button_borderless_lightpressednohover.png, the matching button_borderless_dark* set, disabledButtonNoBorder.png and NormalButtonNoStroke.png / NormalButtonStroke.png, keeping each PNG next to its existing .json nine-slice descriptor. Those exact filenames are the defaults declared in the vanilla ui/ui_template_buttons.json ($default_button_texture, $hover_button_texture, $pressed_button_texture, $locked_button_texture) and in ui/ui_common.json (common.normal_button, common.normal_stroke_button), so no JSON override is strictly needed; shipping ui/ui_template_buttons.json or ui/_global_variables.json is only required if you want to point the variables at new texture names or restyle the button label colours. This repo already proves the technique - resource_packs/files/gui/dark_ui ships NormalButtonNoStroke.png, NormalButtonStroke.png and an overridden ui/ui_template_buttons.json.", + "caveats": "Degraded versus Java, which recolours every button in the game. On Bedrock only screens still rendered by JSON UI pick the new art up (containers, chat, sign editor, classic dialogs); the Bedrock Wiki states plainly that JSON UI is being deprecated in favour of Ore UI and that \"Ore UI is hardcoded and cannot be modified by resource packs\", so the main menu, settings, play/world-list and any other already-migrated screen keep vanilla buttons. Bedrock also has no single widgets.png - the art is spread over roughly a dozen separate nine-sliced PNGs, and the hotbar is a separate texture set (textures/ui/hotbar_*.png, selected_hotbar_slot.png) already covered by the existing hotbar_selector packs.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_template_buttons.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/textures/ui", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredTooltipBlack": { + "verdict": "possible", + "confidence": "high", + "summary": "Straightforward port - Bedrock draws the item hover tooltip from the single nine-sliced texture textures/ui/purpleBorder.png, which a resource pack can replace with a black frame.", + "mechanism": "Ship textures/ui/purpleBorder.png (plus its purpleBorder.json nine-slice descriptor if the slice widths change) recoloured black. In the vanilla resource pack, ui/ui_common.json defines \"item_panel_image\" with \"texture\": \"textures/ui/purpleBorder\" wrapping \"item_text_label\", whose text is bound to #selected_hover_text - that control is the item tooltip. The label colour is a separate knob: override $item_hover_text_color in ui/_global_variables.json if the black background needs lighter text. This repo already ships exactly this file layout in resource_packs/files/gui/translucent_tooltips, whose only asset is textures/ui/purpleBorder.png.", + "caveats": "Bedrock draws the tooltip as one nine-sliced frame rather than Java's separate background fill plus gradient border, so a Java-identical two-tone border is an approximation. The tooltip only appears in JSON UI container screens; it does not exist on the touch/pocket hotbar in the same form. Incompatible with the existing translucent_tooltips pack, since both claim the same file.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/ui/purpleBorder.png", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/_global_variables.json", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredTooltipRed": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock's item tooltip is the nine-sliced image textures/ui/purpleBorder, so a red variant is a straight texture overwrite (or a one-line colour tint in ui_common.json).", + "mechanism": "Bedrock draws the item hover tooltip from `common.item_panel_image` in `RP/ui/ui_common.json`, which is an image control with `\"texture\": \"textures/ui/purpleBorder\"` wrapping the `#selected_hover_text` label. Ship `textures/ui/purpleBorder.png` recoloured red (keep the nine-slice sidecar `textures/ui/purpleBorder.json` alongside it) — textures overwrite by path. A cheaper route that needs no new art is a pack copy of `ui/ui_common.json` using the JSON UI `modifications` property to set `\"color\"` on `common.item_panel_image`, tinting the existing purple frame. The same control is reused by every container screen (`inventory_screen.json`, `chest_screen.json`, `trade_2_screen.json`, the `*_pocket` variants, etc.), so one change covers them all.", + "caveats": "The purpleBorder texture is also used by `chat_screen.json`, `pause_screen.json`, `trade_2_screen.json` and `gameplay_common.json`, so a texture overwrite recolours those popups too; the `modifications` route can target the item tooltip only. The HUD held-item name tip is a separate texture (`textures/ui/hud_tip_text_background`). Java's tooltip is a background sprite plus a gradient frame sprite; Bedrock has a single nine-sliced image, so any per-edge gradient must be baked into that one texture. JSON UI is deprecated in favour of Ore UI, which resource packs cannot modify.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/ui/purpleBorder.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://wiki.bedrock.dev/json-ui/json-ui-intro" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredTooltipOrange": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock's item tooltip is the nine-sliced image textures/ui/purpleBorder, so an orange variant is a straight texture overwrite (or a one-line colour tint in ui_common.json).", + "mechanism": "Bedrock draws the item hover tooltip from `common.item_panel_image` in `RP/ui/ui_common.json`, which is an image control with `\"texture\": \"textures/ui/purpleBorder\"` wrapping the `#selected_hover_text` label. Ship `textures/ui/purpleBorder.png` recoloured orange (keep the nine-slice sidecar `textures/ui/purpleBorder.json` alongside it) — textures overwrite by path. A cheaper route that needs no new art is a pack copy of `ui/ui_common.json` using the JSON UI `modifications` property to set `\"color\"` on `common.item_panel_image`, tinting the existing purple frame. The same control is reused by every container screen (`inventory_screen.json`, `chest_screen.json`, `trade_2_screen.json`, the `*_pocket` variants, etc.), so one change covers them all.", + "caveats": "The purpleBorder texture is also used by `chat_screen.json`, `pause_screen.json`, `trade_2_screen.json` and `gameplay_common.json`, so a texture overwrite recolours those popups too; the `modifications` route can target the item tooltip only. The HUD held-item name tip is a separate texture (`textures/ui/hud_tip_text_background`). Java's tooltip is a background sprite plus a gradient frame sprite; Bedrock has a single nine-sliced image, so any per-edge gradient must be baked into that one texture. JSON UI is deprecated in favour of Ore UI, which resource packs cannot modify.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/ui/purpleBorder.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://wiki.bedrock.dev/json-ui/json-ui-intro" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredTooltipLime": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock's item tooltip is the nine-sliced image textures/ui/purpleBorder, so a lime variant is a straight texture overwrite (or a one-line colour tint in ui_common.json).", + "mechanism": "Bedrock draws the item hover tooltip from `common.item_panel_image` in `RP/ui/ui_common.json`, which is an image control with `\"texture\": \"textures/ui/purpleBorder\"` wrapping the `#selected_hover_text` label. Ship `textures/ui/purpleBorder.png` recoloured lime (keep the nine-slice sidecar `textures/ui/purpleBorder.json` alongside it) — textures overwrite by path. A cheaper route that needs no new art is a pack copy of `ui/ui_common.json` using the JSON UI `modifications` property to set `\"color\"` on `common.item_panel_image`, tinting the existing purple frame. The same control is reused by every container screen (`inventory_screen.json`, `chest_screen.json`, `trade_2_screen.json`, the `*_pocket` variants, etc.), so one change covers them all.", + "caveats": "The purpleBorder texture is also used by `chat_screen.json`, `pause_screen.json`, `trade_2_screen.json` and `gameplay_common.json`, so a texture overwrite recolours those popups too; the `modifications` route can target the item tooltip only. The HUD held-item name tip is a separate texture (`textures/ui/hud_tip_text_background`). Java's tooltip is a background sprite plus a gradient frame sprite; Bedrock has a single nine-sliced image, so any per-edge gradient must be baked into that one texture. JSON UI is deprecated in favour of Ore UI, which resource packs cannot modify.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/ui/purpleBorder.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://wiki.bedrock.dev/json-ui/json-ui-intro" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredTooltipGreen": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock's item tooltip is the nine-sliced image textures/ui/purpleBorder, so a green variant is a straight texture overwrite (or a one-line colour tint in ui_common.json).", + "mechanism": "Bedrock draws the item hover tooltip from `common.item_panel_image` in `RP/ui/ui_common.json`, which is an image control with `\"texture\": \"textures/ui/purpleBorder\"` wrapping the `#selected_hover_text` label. Ship `textures/ui/purpleBorder.png` recoloured green (keep the nine-slice sidecar `textures/ui/purpleBorder.json` alongside it) — textures overwrite by path. A cheaper route that needs no new art is a pack copy of `ui/ui_common.json` using the JSON UI `modifications` property to set `\"color\"` on `common.item_panel_image`, tinting the existing purple frame. The same control is reused by every container screen (`inventory_screen.json`, `chest_screen.json`, `trade_2_screen.json`, the `*_pocket` variants, etc.), so one change covers them all.", + "caveats": "The purpleBorder texture is also used by `chat_screen.json`, `pause_screen.json`, `trade_2_screen.json` and `gameplay_common.json`, so a texture overwrite recolours those popups too; the `modifications` route can target the item tooltip only. The HUD held-item name tip is a separate texture (`textures/ui/hud_tip_text_background`). Java's tooltip is a background sprite plus a gradient frame sprite; Bedrock has a single nine-sliced image, so any per-edge gradient must be baked into that one texture. JSON UI is deprecated in favour of Ore UI, which resource packs cannot modify.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/ui/purpleBorder.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://wiki.bedrock.dev/json-ui/json-ui-intro" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredTooltipCyan": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock's item tooltip is the nine-sliced image textures/ui/purpleBorder, so a cyan variant is a straight texture overwrite (or a one-line colour tint in ui_common.json).", + "mechanism": "Bedrock draws the item hover tooltip from `common.item_panel_image` in `RP/ui/ui_common.json`, which is an image control with `\"texture\": \"textures/ui/purpleBorder\"` wrapping the `#selected_hover_text` label. Ship `textures/ui/purpleBorder.png` recoloured cyan (keep the nine-slice sidecar `textures/ui/purpleBorder.json` alongside it) — textures overwrite by path. A cheaper route that needs no new art is a pack copy of `ui/ui_common.json` using the JSON UI `modifications` property to set `\"color\"` on `common.item_panel_image`, tinting the existing purple frame. The same control is reused by every container screen (`inventory_screen.json`, `chest_screen.json`, `trade_2_screen.json`, the `*_pocket` variants, etc.), so one change covers them all.", + "caveats": "The purpleBorder texture is also used by `chat_screen.json`, `pause_screen.json`, `trade_2_screen.json` and `gameplay_common.json`, so a texture overwrite recolours those popups too; the `modifications` route can target the item tooltip only. The HUD held-item name tip is a separate texture (`textures/ui/hud_tip_text_background`). Java's tooltip is a background sprite plus a gradient frame sprite; Bedrock has a single nine-sliced image, so any per-edge gradient must be baked into that one texture. JSON UI is deprecated in favour of Ore UI, which resource packs cannot modify.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/ui/purpleBorder.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://wiki.bedrock.dev/json-ui/json-ui-intro" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredTooltipBlue": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock's item tooltip is the nine-sliced image textures/ui/purpleBorder, so a blue variant is a straight texture overwrite (or a one-line colour tint in ui_common.json).", + "mechanism": "Bedrock draws the item hover tooltip from `common.item_panel_image` in `RP/ui/ui_common.json`, which is an image control with `\"texture\": \"textures/ui/purpleBorder\"` wrapping the `#selected_hover_text` label. Ship `textures/ui/purpleBorder.png` recoloured blue (keep the nine-slice sidecar `textures/ui/purpleBorder.json` alongside it) — textures overwrite by path. A cheaper route that needs no new art is a pack copy of `ui/ui_common.json` using the JSON UI `modifications` property to set `\"color\"` on `common.item_panel_image`, tinting the existing purple frame. The same control is reused by every container screen (`inventory_screen.json`, `chest_screen.json`, `trade_2_screen.json`, the `*_pocket` variants, etc.), so one change covers them all.", + "caveats": "The purpleBorder texture is also used by `chat_screen.json`, `pause_screen.json`, `trade_2_screen.json` and `gameplay_common.json`, so a texture overwrite recolours those popups too; the `modifications` route can target the item tooltip only. The HUD held-item name tip is a separate texture (`textures/ui/hud_tip_text_background`). Java's tooltip is a background sprite plus a gradient frame sprite; Bedrock has a single nine-sliced image, so any per-edge gradient must be baked into that one texture. JSON UI is deprecated in favour of Ore UI, which resource packs cannot modify.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/ui/purpleBorder.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://wiki.bedrock.dev/json-ui/json-ui-intro" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredTooltipPink": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock's item tooltip is the nine-sliced image textures/ui/purpleBorder, so a pink variant is a straight texture overwrite (or a one-line colour tint in ui_common.json).", + "mechanism": "Bedrock draws the item hover tooltip from `common.item_panel_image` in `RP/ui/ui_common.json`, which is an image control with `\"texture\": \"textures/ui/purpleBorder\"` wrapping the `#selected_hover_text` label. Ship `textures/ui/purpleBorder.png` recoloured pink (keep the nine-slice sidecar `textures/ui/purpleBorder.json` alongside it) — textures overwrite by path. A cheaper route that needs no new art is a pack copy of `ui/ui_common.json` using the JSON UI `modifications` property to set `\"color\"` on `common.item_panel_image`, tinting the existing purple frame. The same control is reused by every container screen (`inventory_screen.json`, `chest_screen.json`, `trade_2_screen.json`, the `*_pocket` variants, etc.), so one change covers them all.", + "caveats": "The purpleBorder texture is also used by `chat_screen.json`, `pause_screen.json`, `trade_2_screen.json` and `gameplay_common.json`, so a texture overwrite recolours those popups too; the `modifications` route can target the item tooltip only. The HUD held-item name tip is a separate texture (`textures/ui/hud_tip_text_background`). Java's tooltip is a background sprite plus a gradient frame sprite; Bedrock has a single nine-sliced image, so any per-edge gradient must be baked into that one texture. JSON UI is deprecated in favour of Ore UI, which resource packs cannot modify.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/ui/purpleBorder.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://wiki.bedrock.dev/json-ui/json-ui-intro" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "DirtBG": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock already ships the classic tiled dirt background as a JSON UI control (`common.dirt_background` on `textures/ui/bg32`); the pack just has to point the Settings screen background at it.", + "mechanism": "`RP/ui/ui_common.json` defines `common.dirt_background` as `{ \"type\": \"image\", \"texture\": \"textures/ui/bg32\", \"tiled\": true }`, and vanilla already uses it in `credits_screen.json`, `disconnect_screen.json` and `progress_screen.json`. The Settings screens paint their own background in `RP/ui/settings_sections/settings_common.json` under `settings_common.settings_content` — a control named `background` that is an image on `textures/ui/White` tinted `[0.192, 0.196, 0.2]`. A resource pack ships that file (or a `modifications` patch of it) changing that control to `\"texture\": \"textures/ui/bg32\"`, `\"tiled\": true` and dropping the tint. For screens derived from `common.base_screen` the alternative hook is `\"$screen_bg_content\": \"common.dirt_background\"`, exactly as `disconnect_screen.json` does today.", + "caveats": "Bedrock's options menus never had a dirt background, so this is a Java-style restyle rather than a revert. Only the JSON UI settings screens are reachable: JSON UI is deprecated in favour of Ore UI, which the wiki states is hardcoded and cannot be modified by resource packs, so any settings surface Mojang migrates to Ore UI will stop responding to the pack. Touch/pocket and console layouts share `settings_common.json`, so verify all three.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/settings_sections/settings_common.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/ui/bg32.png", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "OldFireflies": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock's firefly is a fully data-driven particle (`minecraft:firefly_particle`), so a pack can replace its texture, size and colour gradient outright by overwriting the particle by identifier.", + "mechanism": "Ship `RP/particles/firefly_particle.json` with the identifier `minecraft:firefly_particle` — particles are overwritten by identifier, not by path, so a pack-local copy fully replaces the vanilla one. The vanilla file uses `basic_render_parameters: { \"material\": \"particles_blend\", \"texture\": \"textures/particle/pixel\" }` with `minecraft:particle_appearance_billboard.size [0.0375, 0.0375]` and a pale-yellow `minecraft:particle_appearance_tinting` gradient that fades alpha in and out. To restore the 1.19-reveal look, point `texture` at your own `textures/particle/.png`, enlarge `size`, and flatten or replace the tint gradient so the sprite's own colours show.", + "caveats": "This is not a like-for-like texture swap: Bedrock's firefly has no dedicated texture, it reuses the shared 1x1 `textures/particle/pixel` and tints it, so the whole particle definition has to be re-authored rather than a single PNG dropped in. Do NOT overwrite `textures/particle/pixel` directly — many other vanilla particles sample it. Requires a version where the Firefly Bush exists (Bedrock 1.21.50+ parity with Java 1.21.5).", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/particles/firefly_particle.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://learn.microsoft.com/minecraft/creator/reference/content/particlesreference/examples/particlecomponents/particle_effect_basic_render_parameters", + "https://minecraft.wiki/w/Firefly_Bush" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "OldRedstoneTorch": { + "verdict": "partial", + "confidence": "high", + "summary": "The texture half is a plain path overwrite, but Bedrock does not expose vanilla block geometry, so the pre-1.21.2 redstone torch model cannot be restored.", + "mechanism": "Textures: drop `textures/blocks/redstone_torch_on.png` and `textures/blocks/redstone_torch_off.png` into the pack — `RP/blocks.json` maps `redstone_torch` -> `redstone_torch_on` and `unlit_redstone_torch` -> `redstone_torch_off`, and textures are overwritten by path. Model: not reachable. The `redstone_torch` entry in `RP/blocks.json` exposes only `sound` and `textures` (no geometry field), there is no vanilla block model JSON anywhere in `bedrock-samples/resource_pack/models/` (that folder holds entity geometry only), and the Bedrock Wiki states outright that vanilla block models are not data-driven and cannot be modified.", + "caveats": "Bedrock already carries the post-1.21.2 art: the shipped `redstone_torch_on.png` has a four-pixel-wide glowing head (x=6..9, rows 5..8) that is wider than the two-pixel stick, which means the wider head element of the new model is present in Bedrock too. Reverting the texture alone leaves that geometry in place. Authoring the old texture with the extra head texels transparent may visually approximate the pre-1.21.2 torch, but that is untested and the model itself still cannot be changed. Redstone repeater and comparator torch nubs picked up the same 1.21.2 model change and are equally out of reach.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/blocks.json", + "https://wiki.bedrock.dev/blocks/vanilla-block-models", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://minecraft.wiki/w/Java_Edition_1.21.2" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlueWidgetsHighlight": { + "verdict": "partial", + "confidence": "medium", + "summary": "Bedrock's equivalent white highlight border around focused/hovered menu buttons can be recoloured blue, but only on the classic JSON UI screens - Ore UI screens are hardcoded and will keep the white border.", + "mechanism": "Bedrock does not use Java's `widgets.png`; the white outline drawn around a hovered or focus-navigated button comes from the `common.focus_border_white` control in `resource_pack/ui/ui_common.json`, which is an `image` pointing at `resource_pack/textures/ui/focus_border_white.png`. Two routes work: drop a blue-tinted `textures/ui/focus_border_white.png` into the pack (textures are overwritten by path), or merge an override of `common.focus_border_white` in `ui/ui_common.json` adding a `\"color\": [r, g, b, a]` array - vanilla already builds `focus_border_yellow` and `focus_border_black` exactly that way. Mojang even flags this as an intended extension point: `ui_common.json` carries the comment \"This copy is for the border of images that we want to be allow to be overridden separately with resource packs\".", + "caveats": "Only classic JSON UI screens are affected. The Bedrock Wiki states \"JSON UI is being deprecated in favor of Ore UI\" and \"Unlike JSON UI, Ore UI is hardcoded and cannot be modified by resource packs\", so the main menu, settings and the play/create-world flows keep the vanilla highlight. The result is an equivalent effect, not a pixel port: Bedrock draws a nine-slice border image rather than a Java button sprite with a baked-in outline.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/ui/ui_common.json", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/ui/focus_border_white.png", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "OldEnchantGlint": { + "verdict": "possible", + "confidence": "medium", + "summary": "Bedrock ships separate armour and item glint textures at overridable paths, so making the armour glint use the item glint art is a one-file texture swap.", + "mechanism": "Bedrock has two distinct glint textures in the vanilla resource pack: `resource_pack/textures/misc/enchanted_actor_glint.png` (128x128 RGBA, used on worn armour and other entity renders) and `resource_pack/textures/misc/enchanted_item_glint.png` (128x128 RGB, used on items). Both are plain path-referenced assets, so a pack that places its own `textures/misc/enchanted_actor_glint.png` fully replaces the vanilla one - the pack is simply the item glint art re-authored as the actor glint texture. This repo already ships packs that override both files (`resource_packs/files/world_of_color/enchantment_glints/*`), so the override path is proven in practice.", + "caveats": "The item glint texture has no alpha channel while the actor glint texture does, so the art has to be re-exported as RGBA rather than copied byte-for-byte. Scroll speed and UV scale of the glint are engine-side and not resource-pack controllable, so the armour glint will carry the item glint's artwork at whatever rate the actor renderer already uses - close to, but not guaranteed identical to, the item glint's motion.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_actor_glint.png", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_item_glint.png", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ClassicFog": { + "verdict": "blocked", + "confidence": "medium", + "summary": "This pack reverts Java 1.21.6 fog changes using Java core shaders; Bedrock resource packs cannot supply shaders after Render Dragon, and Bedrock's fog is a separate data-driven system that never received those changes, so there is nothing to revert and no hook to do it with.", + "mechanism": "What is missing is the shader hook. The Bedrock Wiki states that resource-pack shaders \"will not work on Windows and Console devices past 1.16.200, nor other devices past 1.18.30\", so the core-shader edits this Java pack relies on have no Bedrock counterpart on any current version. What Bedrock does expose is data-driven fog: JSON files in a resource pack's `fogs/` folder using `minecraft:fog_settings`, bound to biomes through `biomes_client.json` via `fog_identifier`. That schema only offers `fog_start`, `fog_end`, `fog_color` and `render_distance_type` per camera state (`air`, `water`, `weather`, `lava`, `lava_resistance`, `powder_snow`) plus volumetric density/coefficients - it exposes no fog curve, no atmospheric-perspective control, and no toggle for fog on first-person hands. Separately, the Java changes being reverted here (fog applied to 3D HUD elements such as first-person hands, heavier fog while raining, and a tweaked atmospheric perspective, all from Java Edition 1.21.6) were never shipped to Bedrock.", + "caveats": "A Bedrock-native fog pack is still buildable through `fogs/` + `biomes_client.json` if the maintainer wants one - clearer distances, custom fog colours, or a lighter rain fog via the `weather` entry - but that is a new pack, not a port of Classic Fog. Re-check if Mojang ever exposes Vibrant Visuals shader authoring to resource packs.", + "sources": [ + "https://wiki.bedrock.dev/concepts/shaders", + "https://learn.microsoft.com/minecraft/creator/documents/foginresourcepacks", + "https://learn.microsoft.com/minecraft/creator/reference/content/fogsreference/fogs", + "https://minecraft.wiki/w/Java_Edition_1.21.6" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredGlintWhite": { + "verdict": "possible", + "confidence": "high", + "summary": "A white enchantment glint is a two-texture recolour on Bedrock, using the exact method this repo already ships for the red, orange, yellow, blue and rainbow glints.", + "mechanism": "Override `textures/misc/enchanted_item_glint.png` and `textures/misc/enchanted_actor_glint.png` with white-recoloured copies. Both files exist in the vanilla Bedrock resource pack at those paths and are plain path-referenced assets, so a pack placing its own copies fully replaces them. The existing `resource_packs/files/world_of_color/enchantment_glints/*` packs in this repo contain exactly those two files and nothing else, so this is a copy-and-recolour job that slots straight into the existing `world_of_color/enchantment_glints` category.", + "caveats": "The actor glint texture is RGBA and the item glint texture is RGB; keep each one's channel layout when recolouring. Glint scroll speed and UV scale are engine-side, so only the colour changes.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_item_glint.png", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_actor_glint.png", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredGlintLime": { + "verdict": "possible", + "confidence": "high", + "summary": "A lime enchantment glint is a two-texture recolour on Bedrock, using the exact method this repo already ships for the red, orange, yellow, blue and rainbow glints.", + "mechanism": "Override `textures/misc/enchanted_item_glint.png` and `textures/misc/enchanted_actor_glint.png` with lime-recoloured copies. Both files exist in the vanilla Bedrock resource pack at those paths and are plain path-referenced assets, so a pack placing its own copies fully replaces them. The existing `resource_packs/files/world_of_color/enchantment_glints/*` packs in this repo contain exactly those two files and nothing else, so this is a copy-and-recolour job that slots straight into the existing `world_of_color/enchantment_glints` category.", + "caveats": "The actor glint texture is RGBA and the item glint texture is RGB; keep each one's channel layout when recolouring. Glint scroll speed and UV scale are engine-side, so only the colour changes.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_item_glint.png", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_actor_glint.png", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredGlintGreen": { + "verdict": "possible", + "confidence": "high", + "summary": "A green enchantment glint is a two-texture recolour on Bedrock, using the exact method this repo already ships for the red, orange, yellow, blue and rainbow glints.", + "mechanism": "Override `textures/misc/enchanted_item_glint.png` and `textures/misc/enchanted_actor_glint.png` with green-recoloured copies. Both files exist in the vanilla Bedrock resource pack at those paths and are plain path-referenced assets, so a pack placing its own copies fully replaces them. The existing `resource_packs/files/world_of_color/enchantment_glints/*` packs in this repo contain exactly those two files and nothing else, so this is a copy-and-recolour job that slots straight into the existing `world_of_color/enchantment_glints` category.", + "caveats": "The actor glint texture is RGBA and the item glint texture is RGB; keep each one's channel layout when recolouring. Glint scroll speed and UV scale are engine-side, so only the colour changes.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_item_glint.png", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_actor_glint.png", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredGlintCyan": { + "verdict": "possible", + "confidence": "high", + "summary": "A cyan enchantment glint is a two-texture recolour on Bedrock, using the exact method this repo already ships for the red, orange, yellow, blue and rainbow glints.", + "mechanism": "Override `textures/misc/enchanted_item_glint.png` and `textures/misc/enchanted_actor_glint.png` with cyan-recoloured copies. Both files exist in the vanilla Bedrock resource pack at those paths and are plain path-referenced assets, so a pack placing its own copies fully replaces them. The existing `resource_packs/files/world_of_color/enchantment_glints/*` packs in this repo contain exactly those two files and nothing else, so this is a copy-and-recolour job that slots straight into the existing `world_of_color/enchantment_glints` category.", + "caveats": "The actor glint texture is RGBA and the item glint texture is RGB; keep each one's channel layout when recolouring. Glint scroll speed and UV scale are engine-side, so only the colour changes.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_item_glint.png", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_actor_glint.png", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredGlintLightBlue": { + "verdict": "possible", + "confidence": "high", + "summary": "A light blue enchantment glint is a two-texture recolour on Bedrock, using the exact method this repo already ships for the red, orange, yellow, blue and rainbow glints.", + "mechanism": "Override `textures/misc/enchanted_item_glint.png` and `textures/misc/enchanted_actor_glint.png` with light-blue-recoloured copies. Both files exist in the vanilla Bedrock resource pack at those paths and are plain path-referenced assets, so a pack placing its own copies fully replaces them. The existing `resource_packs/files/world_of_color/enchantment_glints/*` packs in this repo contain exactly those two files and nothing else, so this is a copy-and-recolour job that slots straight into the existing `world_of_color/enchantment_glints` category - note the existing `blue_enchantment_glint` pack is a separate, darker shade.", + "caveats": "The actor glint texture is RGBA and the item glint texture is RGB; keep each one's channel layout when recolouring. Glint scroll speed and UV scale are engine-side, so only the colour changes.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_item_glint.png", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_actor_glint.png", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredGlintMagenta": { + "verdict": "possible", + "confidence": "high", + "summary": "A magenta enchantment glint is a two-texture recolour on Bedrock, using the exact method this repo already ships for the red, orange, yellow, blue and rainbow glints.", + "mechanism": "Override `textures/misc/enchanted_item_glint.png` and `textures/misc/enchanted_actor_glint.png` with magenta-recoloured copies. Both files exist in the vanilla Bedrock resource pack at those paths and are plain path-referenced assets, so a pack placing its own copies fully replaces them. The existing `resource_packs/files/world_of_color/enchantment_glints/*` packs in this repo contain exactly those two files and nothing else, so this is a copy-and-recolour job that slots straight into the existing `world_of_color/enchantment_glints` category.", + "caveats": "The actor glint texture is RGBA and the item glint texture is RGB; keep each one's channel layout when recolouring. Glint scroll speed and UV scale are engine-side, so only the colour changes. Magenta sits close to the vanilla purple glint, so the difference will be subtle in-game.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_item_glint.png", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_actor_glint.png", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ColoredGlintPink": { + "verdict": "possible", + "confidence": "high", + "summary": "A pink enchantment glint is a two-texture recolour on Bedrock, using the exact method this repo already ships for the red, orange, yellow, blue and rainbow glints.", + "mechanism": "Override `textures/misc/enchanted_item_glint.png` and `textures/misc/enchanted_actor_glint.png` with pink-recoloured copies. Both files exist in the vanilla Bedrock resource pack at those paths and are plain path-referenced assets, so a pack placing its own copies fully replaces them. The existing `resource_packs/files/world_of_color/enchantment_glints/*` packs in this repo contain exactly those two files and nothing else, so this is a copy-and-recolour job that slots straight into the existing `world_of_color/enchantment_glints` category.", + "caveats": "The actor glint texture is RGBA and the item glint texture is RGB; keep each one's channel layout when recolouring. Glint scroll speed and UV scale are engine-side, so only the colour changes.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_item_glint.png", + "https://github.com/Mojang/bedrock-samples/blob/main/resource_pack/textures/misc/enchanted_actor_glint.png", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineWhite": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot recolour the block selection outline, because the Java pack works by replacing a core GLSL shader and Bedrock exposes no shader or material control point for the selection box.", + "mechanism": "The Java pack overrides the vanilla core shader that draws line geometry (rendertype_lines) to tint the block outline white. Bedrock has no equivalent: Microsoft's own Java/Bedrock comparison states plainly that \"Java can create custom fonts and GLSL shaders, while Bedrock cannot\". The vanilla RP in Mojang/bedrock-samples has no `shaders/` and no `materials/` directory at all (only animation_controllers, animations, attachables, biomes, entity, fogs, models, particles, render_controllers, sounds, texts, textures, ui plus blocks.json/sounds.json/biomes_client.json), and `textures/misc/` holds only enchanted_actor_glint.png, enchanted_item_glint.png, missing_texture.png and pumpkinblur.png - there is no selection-outline texture to retexture. The Bedrock Wiki's list of overwritable vanilla assets covers textures, sounds, trade tables, RP entities, animations, models, animation/render controllers, particles, UI and language files; materials and shaders are not on it. Bedrock's documented material system applies only to entities and particles, and its `vertexShader`/`geometryShader` keys are listed as deprecated and ignored by current versions. The nearest block-side control point, the behaviour-pack component `minecraft:selection_box`, only sets the outline's origin/size or turns it off on custom blocks - it has no colour field and does not apply to vanilla blocks.", + "caveats": "Legacy resource-pack GLSL shaders stopped working under Render Dragon (Windows and console past 1.16.200, other devices past 1.18.30), so even the pre-Render Dragon workaround is dead on all current platforms.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://wiki.bedrock.dev/concepts/shaders", + "https://learn.microsoft.com/minecraft/creator/documents/material-files", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_selection_box" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineLightGray": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot recolour the block selection outline, because the Java pack works by replacing a core GLSL shader and Bedrock exposes no shader or material control point for the selection box.", + "mechanism": "The Java pack overrides the vanilla core shader that draws line geometry (rendertype_lines) to tint the block outline light gray. Bedrock has no equivalent: Microsoft's own Java/Bedrock comparison states plainly that \"Java can create custom fonts and GLSL shaders, while Bedrock cannot\". The vanilla RP in Mojang/bedrock-samples has no `shaders/` and no `materials/` directory at all (only animation_controllers, animations, attachables, biomes, entity, fogs, models, particles, render_controllers, sounds, texts, textures, ui plus blocks.json/sounds.json/biomes_client.json), and `textures/misc/` holds only enchanted_actor_glint.png, enchanted_item_glint.png, missing_texture.png and pumpkinblur.png - there is no selection-outline texture to retexture. The Bedrock Wiki's list of overwritable vanilla assets covers textures, sounds, trade tables, RP entities, animations, models, animation/render controllers, particles, UI and language files; materials and shaders are not on it. Bedrock's documented material system applies only to entities and particles, and its `vertexShader`/`geometryShader` keys are listed as deprecated and ignored by current versions. The nearest block-side control point, the behaviour-pack component `minecraft:selection_box`, only sets the outline's origin/size or turns it off on custom blocks - it has no colour field and does not apply to vanilla blocks.", + "caveats": "Legacy resource-pack GLSL shaders stopped working under Render Dragon (Windows and console past 1.16.200, other devices past 1.18.30), so even the pre-Render Dragon workaround is dead on all current platforms.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://wiki.bedrock.dev/concepts/shaders", + "https://learn.microsoft.com/minecraft/creator/documents/material-files", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_selection_box" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineGray": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot recolour the block selection outline, because the Java pack works by replacing a core GLSL shader and Bedrock exposes no shader or material control point for the selection box.", + "mechanism": "The Java pack overrides the vanilla core shader that draws line geometry (rendertype_lines) to tint the block outline gray. Bedrock has no equivalent: Microsoft's own Java/Bedrock comparison states plainly that \"Java can create custom fonts and GLSL shaders, while Bedrock cannot\". The vanilla RP in Mojang/bedrock-samples has no `shaders/` and no `materials/` directory at all (only animation_controllers, animations, attachables, biomes, entity, fogs, models, particles, render_controllers, sounds, texts, textures, ui plus blocks.json/sounds.json/biomes_client.json), and `textures/misc/` holds only enchanted_actor_glint.png, enchanted_item_glint.png, missing_texture.png and pumpkinblur.png - there is no selection-outline texture to retexture. The Bedrock Wiki's list of overwritable vanilla assets covers textures, sounds, trade tables, RP entities, animations, models, animation/render controllers, particles, UI and language files; materials and shaders are not on it. Bedrock's documented material system applies only to entities and particles, and its `vertexShader`/`geometryShader` keys are listed as deprecated and ignored by current versions. The nearest block-side control point, the behaviour-pack component `minecraft:selection_box`, only sets the outline's origin/size or turns it off on custom blocks - it has no colour field and does not apply to vanilla blocks.", + "caveats": "Legacy resource-pack GLSL shaders stopped working under Render Dragon (Windows and console past 1.16.200, other devices past 1.18.30), so even the pre-Render Dragon workaround is dead on all current platforms.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://wiki.bedrock.dev/concepts/shaders", + "https://learn.microsoft.com/minecraft/creator/documents/material-files", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_selection_box" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineBrown": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot recolour the block selection outline, because the Java pack works by replacing a core GLSL shader and Bedrock exposes no shader or material control point for the selection box.", + "mechanism": "The Java pack overrides the vanilla core shader that draws line geometry (rendertype_lines) to tint the block outline brown. Bedrock has no equivalent: Microsoft's own Java/Bedrock comparison states plainly that \"Java can create custom fonts and GLSL shaders, while Bedrock cannot\". The vanilla RP in Mojang/bedrock-samples has no `shaders/` and no `materials/` directory at all (only animation_controllers, animations, attachables, biomes, entity, fogs, models, particles, render_controllers, sounds, texts, textures, ui plus blocks.json/sounds.json/biomes_client.json), and `textures/misc/` holds only enchanted_actor_glint.png, enchanted_item_glint.png, missing_texture.png and pumpkinblur.png - there is no selection-outline texture to retexture. The Bedrock Wiki's list of overwritable vanilla assets covers textures, sounds, trade tables, RP entities, animations, models, animation/render controllers, particles, UI and language files; materials and shaders are not on it. Bedrock's documented material system applies only to entities and particles, and its `vertexShader`/`geometryShader` keys are listed as deprecated and ignored by current versions. The nearest block-side control point, the behaviour-pack component `minecraft:selection_box`, only sets the outline's origin/size or turns it off on custom blocks - it has no colour field and does not apply to vanilla blocks.", + "caveats": "Legacy resource-pack GLSL shaders stopped working under Render Dragon (Windows and console past 1.16.200, other devices past 1.18.30), so even the pre-Render Dragon workaround is dead on all current platforms.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://wiki.bedrock.dev/concepts/shaders", + "https://learn.microsoft.com/minecraft/creator/documents/material-files", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_selection_box" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineRed": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot recolour the block selection outline, because the Java pack works by replacing a core GLSL shader and Bedrock exposes no shader or material control point for the selection box.", + "mechanism": "The Java pack overrides the vanilla core shader that draws line geometry (rendertype_lines) to tint the block outline red. Bedrock has no equivalent: Microsoft's own Java/Bedrock comparison states plainly that \"Java can create custom fonts and GLSL shaders, while Bedrock cannot\". The vanilla RP in Mojang/bedrock-samples has no `shaders/` and no `materials/` directory at all (only animation_controllers, animations, attachables, biomes, entity, fogs, models, particles, render_controllers, sounds, texts, textures, ui plus blocks.json/sounds.json/biomes_client.json), and `textures/misc/` holds only enchanted_actor_glint.png, enchanted_item_glint.png, missing_texture.png and pumpkinblur.png - there is no selection-outline texture to retexture. The Bedrock Wiki's list of overwritable vanilla assets covers textures, sounds, trade tables, RP entities, animations, models, animation/render controllers, particles, UI and language files; materials and shaders are not on it. Bedrock's documented material system applies only to entities and particles, and its `vertexShader`/`geometryShader` keys are listed as deprecated and ignored by current versions. The nearest block-side control point, the behaviour-pack component `minecraft:selection_box`, only sets the outline's origin/size or turns it off on custom blocks - it has no colour field and does not apply to vanilla blocks.", + "caveats": "Legacy resource-pack GLSL shaders stopped working under Render Dragon (Windows and console past 1.16.200, other devices past 1.18.30), so even the pre-Render Dragon workaround is dead on all current platforms.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://wiki.bedrock.dev/concepts/shaders", + "https://learn.microsoft.com/minecraft/creator/documents/material-files", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_selection_box" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineOrange": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot recolour the block selection outline, because the Java pack works by replacing a core GLSL shader and Bedrock exposes no shader or material control point for the selection box.", + "mechanism": "The Java pack overrides the vanilla core shader that draws line geometry (rendertype_lines) to tint the block outline orange. Bedrock has no equivalent: Microsoft's own Java/Bedrock comparison states plainly that \"Java can create custom fonts and GLSL shaders, while Bedrock cannot\". The vanilla RP in Mojang/bedrock-samples has no `shaders/` and no `materials/` directory at all (only animation_controllers, animations, attachables, biomes, entity, fogs, models, particles, render_controllers, sounds, texts, textures, ui plus blocks.json/sounds.json/biomes_client.json), and `textures/misc/` holds only enchanted_actor_glint.png, enchanted_item_glint.png, missing_texture.png and pumpkinblur.png - there is no selection-outline texture to retexture. The Bedrock Wiki's list of overwritable vanilla assets covers textures, sounds, trade tables, RP entities, animations, models, animation/render controllers, particles, UI and language files; materials and shaders are not on it. Bedrock's documented material system applies only to entities and particles, and its `vertexShader`/`geometryShader` keys are listed as deprecated and ignored by current versions. The nearest block-side control point, the behaviour-pack component `minecraft:selection_box`, only sets the outline's origin/size or turns it off on custom blocks - it has no colour field and does not apply to vanilla blocks.", + "caveats": "Legacy resource-pack GLSL shaders stopped working under Render Dragon (Windows and console past 1.16.200, other devices past 1.18.30), so even the pre-Render Dragon workaround is dead on all current platforms.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://wiki.bedrock.dev/concepts/shaders", + "https://learn.microsoft.com/minecraft/creator/documents/material-files", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_selection_box" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineYellow": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot recolour the block selection outline, because the Java pack works by replacing a core GLSL shader and Bedrock exposes no shader or material control point for the selection box.", + "mechanism": "The Java pack overrides the vanilla core shader that draws line geometry (rendertype_lines) to tint the block outline yellow. Bedrock has no equivalent: Microsoft's own Java/Bedrock comparison states plainly that \"Java can create custom fonts and GLSL shaders, while Bedrock cannot\". The vanilla RP in Mojang/bedrock-samples has no `shaders/` and no `materials/` directory at all (only animation_controllers, animations, attachables, biomes, entity, fogs, models, particles, render_controllers, sounds, texts, textures, ui plus blocks.json/sounds.json/biomes_client.json), and `textures/misc/` holds only enchanted_actor_glint.png, enchanted_item_glint.png, missing_texture.png and pumpkinblur.png - there is no selection-outline texture to retexture. The Bedrock Wiki's list of overwritable vanilla assets covers textures, sounds, trade tables, RP entities, animations, models, animation/render controllers, particles, UI and language files; materials and shaders are not on it. Bedrock's documented material system applies only to entities and particles, and its `vertexShader`/`geometryShader` keys are listed as deprecated and ignored by current versions. The nearest block-side control point, the behaviour-pack component `minecraft:selection_box`, only sets the outline's origin/size or turns it off on custom blocks - it has no colour field and does not apply to vanilla blocks.", + "caveats": "Legacy resource-pack GLSL shaders stopped working under Render Dragon (Windows and console past 1.16.200, other devices past 1.18.30), so even the pre-Render Dragon workaround is dead on all current platforms.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://wiki.bedrock.dev/concepts/shaders", + "https://learn.microsoft.com/minecraft/creator/documents/material-files", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_selection_box" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineLime": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot recolour the block selection outline, because the Java pack works by replacing a core GLSL shader and Bedrock exposes no shader or material control point for the selection box.", + "mechanism": "The Java pack overrides the vanilla core shader that draws line geometry (rendertype_lines) to tint the block outline lime. Bedrock has no equivalent: Microsoft's own Java/Bedrock comparison states plainly that \"Java can create custom fonts and GLSL shaders, while Bedrock cannot\". The vanilla RP in Mojang/bedrock-samples has no `shaders/` and no `materials/` directory at all (only animation_controllers, animations, attachables, biomes, entity, fogs, models, particles, render_controllers, sounds, texts, textures, ui plus blocks.json/sounds.json/biomes_client.json), and `textures/misc/` holds only enchanted_actor_glint.png, enchanted_item_glint.png, missing_texture.png and pumpkinblur.png - there is no selection-outline texture to retexture. The Bedrock Wiki's list of overwritable vanilla assets covers textures, sounds, trade tables, RP entities, animations, models, animation/render controllers, particles, UI and language files; materials and shaders are not on it. Bedrock's documented material system applies only to entities and particles, and its `vertexShader`/`geometryShader` keys are listed as deprecated and ignored by current versions. The nearest block-side control point, the behaviour-pack component `minecraft:selection_box`, only sets the outline's origin/size or turns it off on custom blocks - it has no colour field and does not apply to vanilla blocks.", + "caveats": "Legacy resource-pack GLSL shaders stopped working under Render Dragon (Windows and console past 1.16.200, other devices past 1.18.30), so even the pre-Render Dragon workaround is dead on all current platforms.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://wiki.bedrock.dev/concepts/shaders", + "https://learn.microsoft.com/minecraft/creator/documents/material-files", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_selection_box" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineGreen": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot recolour the block selection outline, because the Java pack works by replacing a core GLSL shader and Bedrock exposes no shader or material control point for the selection box.", + "mechanism": "The Java pack overrides the vanilla core shader that draws line geometry (rendertype_lines) to tint the block outline green. Bedrock has no equivalent: Microsoft's own Java/Bedrock comparison states plainly that \"Java can create custom fonts and GLSL shaders, while Bedrock cannot\". The vanilla RP in Mojang/bedrock-samples has no `shaders/` and no `materials/` directory at all (only animation_controllers, animations, attachables, biomes, entity, fogs, models, particles, render_controllers, sounds, texts, textures, ui plus blocks.json/sounds.json/biomes_client.json), and `textures/misc/` holds only enchanted_actor_glint.png, enchanted_item_glint.png, missing_texture.png and pumpkinblur.png - there is no selection-outline texture to retexture. The Bedrock Wiki's list of overwritable vanilla assets covers textures, sounds, trade tables, RP entities, animations, models, animation/render controllers, particles, UI and language files; materials and shaders are not on it. Bedrock's documented material system applies only to entities and particles, and its `vertexShader`/`geometryShader` keys are listed as deprecated and ignored by current versions. The nearest block-side control point, the behaviour-pack component `minecraft:selection_box`, only sets the outline's origin/size or turns it off on custom blocks - it has no colour field and does not apply to vanilla blocks.", + "caveats": "Legacy resource-pack GLSL shaders stopped working under Render Dragon (Windows and console past 1.16.200, other devices past 1.18.30), so even the pre-Render Dragon workaround is dead on all current platforms.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://wiki.bedrock.dev/concepts/shaders", + "https://learn.microsoft.com/minecraft/creator/documents/material-files", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_selection_box" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineCyan": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot recolour the block selection outline, because the Java pack works by replacing a core GLSL shader and Bedrock exposes no shader or material control point for the selection box.", + "mechanism": "The Java pack overrides the vanilla core shader that draws line geometry (rendertype_lines) to tint the block outline cyan. Bedrock has no equivalent: Microsoft's own Java/Bedrock comparison states plainly that \"Java can create custom fonts and GLSL shaders, while Bedrock cannot\". The vanilla RP in Mojang/bedrock-samples has no `shaders/` and no `materials/` directory at all (only animation_controllers, animations, attachables, biomes, entity, fogs, models, particles, render_controllers, sounds, texts, textures, ui plus blocks.json/sounds.json/biomes_client.json), and `textures/misc/` holds only enchanted_actor_glint.png, enchanted_item_glint.png, missing_texture.png and pumpkinblur.png - there is no selection-outline texture to retexture. The Bedrock Wiki's list of overwritable vanilla assets covers textures, sounds, trade tables, RP entities, animations, models, animation/render controllers, particles, UI and language files; materials and shaders are not on it. Bedrock's documented material system applies only to entities and particles, and its `vertexShader`/`geometryShader` keys are listed as deprecated and ignored by current versions. The nearest block-side control point, the behaviour-pack component `minecraft:selection_box`, only sets the outline's origin/size or turns it off on custom blocks - it has no colour field and does not apply to vanilla blocks.", + "caveats": "Legacy resource-pack GLSL shaders stopped working under Render Dragon (Windows and console past 1.16.200, other devices past 1.18.30), so even the pre-Render Dragon workaround is dead on all current platforms.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://wiki.bedrock.dev/concepts/shaders", + "https://learn.microsoft.com/minecraft/creator/documents/material-files", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_selection_box" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineLightBlue": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot ship shaders and expose no data-driven control point for the block selection outline, so the light blue outline cannot be reproduced.", + "mechanism": "The Java pack recolours the block selection box by overriding the vanilla core shader (assets/minecraft/shaders/core/rendertype_lines.*) - the pack description says so itself. Bedrock has no equivalent hook. Microsoft's own Java-vs-Bedrock comparison states outright that 'Java can create custom fonts and GLSL shaders, while Bedrock cannot'. The official Comprehensive List of Add-On Pack Contents lists every folder a resource pack may contain (animation_controllers, animations, attachables, block_culling, entity, fogs, items, materials, models, particles, render_controllers, sounds, texts, textures, ui, biomes_client.json, blocks.json, sounds.json) and there is no shaders folder and no rendering/outline configuration file. Mojang/bedrock-samples/resource_pack/ likewise ships no shaders/ and no materials/ directory. The legacy pre-Render Dragon route (shaders/glsl + shaders/hlsl plus a materials/*.material override) that the Bedrock Wiki documents is explicitly dead: 'The shaders on this page are incompatible with Render Dragon. That means that they will not work on Windows and Console devices past 1.16.200, nor other devices past 1.18.30!'", + "caveats": "Applies identically to all six Block Outline colour variants. Re-check only if Mojang ever exposes a data-driven material/rendering layer under Vibrant Visuals - as of 1.26.10 the Vibrant Visuals surface is limited to PBR texture sets, shadows/global.json, cubemaps and local_lighting.json, none of which touch the selection outline.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/concepts/shaders", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineBlue": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot ship shaders and expose no data-driven control point for the block selection outline, so the blue outline cannot be reproduced.", + "mechanism": "The Java pack recolours the block selection box by overriding the vanilla core shader (assets/minecraft/shaders/core/rendertype_lines.*) - the pack description says so itself. Bedrock has no equivalent hook. Microsoft's own Java-vs-Bedrock comparison states outright that 'Java can create custom fonts and GLSL shaders, while Bedrock cannot'. The official Comprehensive List of Add-On Pack Contents enumerates every folder a resource pack may contain and includes no shaders folder and no rendering/outline configuration file. Mojang/bedrock-samples/resource_pack/ ships no shaders/ and no materials/ directory. The legacy pre-Render Dragon route (shaders/glsl + shaders/hlsl plus a materials/*.material override) documented on the Bedrock Wiki is explicitly dead: 'The shaders on this page are incompatible with Render Dragon. That means that they will not work on Windows and Console devices past 1.16.200, nor other devices past 1.18.30!'", + "caveats": "Applies identically to all six Block Outline colour variants. Re-check only if Mojang ever exposes a data-driven material/rendering layer under Vibrant Visuals.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/concepts/shaders", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlinePurple": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot ship shaders and expose no data-driven control point for the block selection outline, so the purple outline cannot be reproduced.", + "mechanism": "The Java pack recolours the block selection box by overriding the vanilla core shader (assets/minecraft/shaders/core/rendertype_lines.*) - the pack description says so itself. Bedrock has no equivalent hook. Microsoft's own Java-vs-Bedrock comparison states outright that 'Java can create custom fonts and GLSL shaders, while Bedrock cannot'. The official Comprehensive List of Add-On Pack Contents enumerates every folder a resource pack may contain and includes no shaders folder and no rendering/outline configuration file. Mojang/bedrock-samples/resource_pack/ ships no shaders/ and no materials/ directory. The legacy pre-Render Dragon route (shaders/glsl + shaders/hlsl plus a materials/*.material override) documented on the Bedrock Wiki is explicitly dead: 'The shaders on this page are incompatible with Render Dragon. That means that they will not work on Windows and Console devices past 1.16.200, nor other devices past 1.18.30!'", + "caveats": "Applies identically to all six Block Outline colour variants. Re-check only if Mojang ever exposes a data-driven material/rendering layer under Vibrant Visuals.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/concepts/shaders", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineMagenta": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot ship shaders and expose no data-driven control point for the block selection outline, so the magenta outline cannot be reproduced.", + "mechanism": "The Java pack recolours the block selection box by overriding the vanilla core shader (assets/minecraft/shaders/core/rendertype_lines.*) - the pack description says so itself. Bedrock has no equivalent hook. Microsoft's own Java-vs-Bedrock comparison states outright that 'Java can create custom fonts and GLSL shaders, while Bedrock cannot'. The official Comprehensive List of Add-On Pack Contents enumerates every folder a resource pack may contain and includes no shaders folder and no rendering/outline configuration file. Mojang/bedrock-samples/resource_pack/ ships no shaders/ and no materials/ directory. The legacy pre-Render Dragon route (shaders/glsl + shaders/hlsl plus a materials/*.material override) documented on the Bedrock Wiki is explicitly dead: 'The shaders on this page are incompatible with Render Dragon. That means that they will not work on Windows and Console devices past 1.16.200, nor other devices past 1.18.30!'", + "caveats": "Applies identically to all six Block Outline colour variants. Re-check only if Mojang ever exposes a data-driven material/rendering layer under Vibrant Visuals.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/concepts/shaders", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlinePink": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot ship shaders and expose no data-driven control point for the block selection outline, so the pink outline cannot be reproduced.", + "mechanism": "The Java pack recolours the block selection box by overriding the vanilla core shader (assets/minecraft/shaders/core/rendertype_lines.*) - the pack description says so itself. Bedrock has no equivalent hook. Microsoft's own Java-vs-Bedrock comparison states outright that 'Java can create custom fonts and GLSL shaders, while Bedrock cannot'. The official Comprehensive List of Add-On Pack Contents enumerates every folder a resource pack may contain and includes no shaders folder and no rendering/outline configuration file. Mojang/bedrock-samples/resource_pack/ ships no shaders/ and no materials/ directory. The legacy pre-Render Dragon route (shaders/glsl + shaders/hlsl plus a materials/*.material override) documented on the Bedrock Wiki is explicitly dead: 'The shaders on this page are incompatible with Render Dragon. That means that they will not work on Windows and Console devices past 1.16.200, nor other devices past 1.18.30!'", + "caveats": "Applies identically to all six Block Outline colour variants. Re-check only if Mojang ever exposes a data-driven material/rendering layer under Vibrant Visuals.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/concepts/shaders", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BlockOutlineRainbow": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock resource packs cannot ship shaders and expose no data-driven control point for the block selection outline, so the animated rainbow outline cannot be reproduced.", + "mechanism": "The Java pack animates the block selection box colour by overriding the vanilla core shader (assets/minecraft/shaders/core/rendertype_lines.*) - the pack description says so itself. Bedrock has no equivalent hook. Microsoft's own Java-vs-Bedrock comparison states outright that 'Java can create custom fonts and GLSL shaders, while Bedrock cannot'. The official Comprehensive List of Add-On Pack Contents enumerates every folder a resource pack may contain and includes no shaders folder and no rendering/outline configuration file. Mojang/bedrock-samples/resource_pack/ ships no shaders/ and no materials/ directory. The legacy pre-Render Dragon route (shaders/glsl + shaders/hlsl plus a materials/*.material override) documented on the Bedrock Wiki is explicitly dead: 'The shaders on this page are incompatible with Render Dragon. That means that they will not work on Windows and Console devices past 1.16.200, nor other devices past 1.18.30!'", + "caveats": "Strictly harder than the solid-colour variants: even if a static outline colour were ever exposed, this one additionally needs a per-frame animated line colour. Bedrock's flipbook_textures.json animates texture atlases only, not line geometry.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/differencesbetweenbedrockandjava?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/comprehensivepackcontents?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/concepts/shaders", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BedrockPistonArms": { + "verdict": "blocked", + "confidence": "high", + "summary": "Nothing to port - this Java pack backports Bedrock's own piston arm model, which is already the default appearance on Bedrock; recommend ignoring rather than opening a port issue.", + "mechanism": "The target look is Bedrock stock rendering. Mojang/bedrock-samples/resource_pack/blocks.json already defines piston, sticky_piston, pistonArmCollision and stickyPistonArmCollision (using piston_bottom, piston_side, piston_top, piston_top_normal and piston_top_sticky), and those PNGs ship in resource_pack/textures/blocks/. A Bedrock pack 'reproducing' this would be shipping files that are already vanilla. Worth noting for the inverse request: a Bedrock resource pack could NOT swap in Java's piston geometry, because blocks.json exposes only textures, carried_textures, sound and isotropic - there is no geometry field for vanilla blocks and bedrock-samples ships no models for them.", + "caveats": "If Bedrock Tweaks ever wants the reverse (Java-style piston arms on Bedrock) that is a separate request and would be blocked for the blocks.json reason above.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/blocks.json", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blocksjsonfilestructure?view=minecraft-bedrock-stable", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BedrockExplosion": { + "verdict": "blocked", + "confidence": "high", + "summary": "Nothing to port - the explosion particle texture this Java pack backports is Bedrock's own vanilla asset, so it is already the default on Bedrock.", + "mechanism": "Mojang/bedrock-samples/resource_pack/particles/explosion_manual.json already renders with basic_render_parameters.texture = 'textures/particle/particles' and a flipbook at base_UV [56, 0], size_UV [8, 8], step_UV [-8, 0], 8 frames - exactly the atlas region the Java pack copies - and resource_pack/textures/particle/particles.png ships in the vanilla pack. A Bedrock pack reproducing this would be shipping the file that is already there. If a different explosion look were ever wanted on Bedrock, particles are fully data-driven: particles/*.json is overridable by identifier and textures/particle/particles.png by path.", + "caveats": "None for the stated effect. Note that Bedrock splits explosions across several particle identifiers (for example minecraft:explosion_manual), so a genuine restyle would need each one edited, not a single texture swap.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/particles/explosion_manual.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BedrockMapItem": { + "verdict": "blocked", + "confidence": "high", + "summary": "Nothing to port - the map item textures this Java pack backports are Bedrock's own vanilla assets and are already the default on Bedrock.", + "mechanism": "All the variants ship in Mojang/bedrock-samples/resource_pack/textures/items/ as map_empty.png, map_filled.png, map_locked.png, map_mansion.png, map_monument.png, map_nautilus.png and map_trial_chambers.png, and resource_pack/textures/item_texture.json maps the map_empty and map_filled entries onto them. A Bedrock pack reproducing this would be shipping files that are already vanilla. Item textures on Bedrock are overridden by path, so if a variant were ever wanted it is a straight PNG drop-in at those same paths plus an item_texture.json catalog copy.", + "caveats": "Bedrock's map variant set is not identical to Java's (for example Bedrock has map_nautilus and no separate 'filled map markings' texture), so a strict one-to-one asset mapping does not exist in either direction.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/textures/item_texture.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BedrockDragonProjectile": { + "verdict": "blocked", + "confidence": "high", + "summary": "Nothing to port - the Ender Dragon projectile texture this Java pack backports is Bedrock's own vanilla asset and is already the default on Bedrock.", + "mechanism": "Mojang/bedrock-samples/resource_pack/entity/dragon_fireball.entity.json already sets textures.default to 'textures/items/dragon_fireball', geometry.default to 'geometry.fireball' and render_controllers to 'controller.render.fireball'; resource_pack/textures/items/dragon_fireball.png and resource_pack/render_controllers/fireball.render_controllers.json both ship in the vanilla pack. A Bedrock pack reproducing this would be shipping the file that is already there. Client entity files, render controllers and textures are all overridable on Bedrock (by identifier and by path respectively), so a genuine restyle would be easy - but the stock appearance already matches.", + "caveats": "None for the stated effect.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/entity/dragon_fireball.entity.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets?view=minecraft-bedrock-stable", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BedrockSlotHighlight": { + "verdict": "blocked", + "confidence": "high", + "summary": "Not applicable to Bedrock: this Java pack back-ports Bedrock's own inventory slot highlight, and Bedrock already draws that highlight natively, so a Bedrock port would be a no-op.", + "mechanism": "There is nothing to build. The vanilla Bedrock resource pack already defines this highlight in `resource_pack/ui/ui_common.json` as the `highlight_slot` control pointing at `textures/ui/highlight_slot.png` (plus `pocket_ui_highlight_slot` -> `textures/ui/pocket_ui_highlight_slot.png` for the touch UI), and `resource_pack/ui/inventory_screen.json` pulls it in through `$highlight_control`. That is exactly the texture the Java pack copies over to Java. The only meaningful Bedrock-side pack in this space is the inverse - putting Java's slot highlight on Bedrock - which is a different request.", + "caveats": "If the maintainers want the inverse pack (Java-style highlight on Bedrock), it is trivially possible: ship a replacement `textures/ui/highlight_slot.png` (textures are overridden by path). That should be raised as its own issue rather than as a port of this one.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/ui_common.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/inventory_screen.json", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "JappaStatsIcons": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock Edition has no statistics screen at all, so there are no stat icons to retexture.", + "mechanism": "The asset and the screen are both absent. `resource_pack/ui/_ui_defs.json` is the vanilla catalogue of every UI screen Bedrock ships (204 entries) and contains no statistics screen - the closest entry is `ui/achievement_screen.json`. The vanilla resource pack also ships no `textures/ui/stats_icons.png` or equivalent icon sheet. minecraft.wiki states outright that \"Statistics are present only in Java Edition. Bedrock Edition has no equivalent of statistics in-game\". There is no file to override.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/_ui_defs.json", + "https://minecraft.wiki/w/Statistics" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "JappaSpecIcons": { + "verdict": "blocked", + "confidence": "high", + "summary": "Bedrock's spectator mode has no spectator menu or ability hotbar, so the icons this pack retextures do not exist on Bedrock.", + "mechanism": "The screen these icons belong to does not exist. `resource_pack/ui/_ui_defs.json` - the vanilla list of every Bedrock UI screen - contains no spectator screen, and the vanilla resource pack ships no spectator icon textures under `textures/ui/`. minecraft.wiki records that in Bedrock Edition spectator mode \"players cannot spectate other entities\", i.e. the Java spectator menu (teleport to player / teleport to team / scroll / close world icons) has no Bedrock counterpart. There is no texture or UI file to override.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/_ui_defs.json", + "https://minecraft.wiki/w/Spectator" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ConsistentUIFix": { + "verdict": "partial", + "confidence": "medium", + "summary": "Bedrock's world and server list screens are still JSON UI and their selection border texture is overridable, but Bedrock has no blue-vs-white outline inconsistency, so the pack has to be redesigned rather than ported.", + "mechanism": "The control point exists. `resource_pack/ui/play_screen.json` (the worlds / friends / servers lists) and `resource_pack/ui/select_world_screen.json` are ordinary JSON UI files, and the list entry focus outline is a `$border_texture` variable set to `textures/ui/world_screenshot_focus_border`. A Bedrock pack would ship a recoloured `textures/ui/world_screenshot_focus_border.png` (textures are overridden by path) and/or an overriding `ui/play_screen.json` (UI files are overridden as catalog files). What it cannot do is reproduce the Java fix as-is, because Bedrock does not draw blue selection outlines on these lists - a contributor must first decide what the Bedrock equivalent of \"consistent white outlines\" should be.", + "caveats": "The Bedrock Wiki warns that \"JSON UI is being deprecated in favor of Ore UI\" and that \"Unlike JSON UI, Ore UI is hardcoded and cannot be modified by resource packs\". The Play screen is a likely migration target, so a pack built on `play_screen.json` can break in a future release.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/play_screen.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/ui/_ui_defs.json", + "https://wiki.bedrock.dev/json-ui/json-ui-intro", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "TripwireHookFix": { + "verdict": "partial", + "confidence": "high", + "summary": "The textures can be replaced, but the remodel half is impossible - vanilla Bedrock block geometry is hardcoded and not data-driven.", + "mechanism": "Retexture (possible): override `textures/blocks/trip_wire.png` and `textures/blocks/trip_wire_source.png`. Note that `resource_pack/blocks.json` maps `tripwire_hook`'s `down` face to the texture key `trip_wire_base`, which `resource_pack/textures/terrain_texture.json` currently resolves to `textures/blocks/planks_oak` - so you must also ship an overriding `terrain_texture.json` that remaps `trip_wire_base` to a dedicated file, or you will repaint every oak plank in the game. Remodel (blocked): `blocks.json` is the only per-vanilla-block control point and, across all 1213 entries in the vanilla file, exposes only `textures`, `carried_textures`, `sound`, `isotropic` and `ambient_occlusion_exponent` - there is no geometry key. The Bedrock Wiki states that vanilla block models \"are not data-driven, so cannot be modified nor found as JSON files in the vanilla resource pack\".", + "caveats": "The shippable result is retexture-only. The pixel/size mismatch that the Java pack fixes by remodelling the hook and the wire will remain.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/blocks.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/textures/terrain_texture.json", + "https://wiki.bedrock.dev/blocks/vanilla-block-models" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "SlimeParticleFix": { + "verdict": "partial", + "confidence": "medium", + "summary": "The Sulfur Cube half is fully doable because Bedrock already data-drives that particle; the Slime half can only be approximated by repainting the shared legacy particle sheet.", + "mechanism": "Sulfur Cube (possible): `resource_pack/particles/sulfur_cube_particle.json` defines `minecraft:sulfur_cube_goo` and its `basic_render_parameters.texture` is already `textures/particle/sulfur_cube_goo` - a dedicated particle texture, not an item sprite. Particles are overridden by identifier, so re-declaring `minecraft:sulfur_cube_goo` in your pack pointing at `atlas.terrain` with block UVs, or simply repainting `textures/particle/sulfur_cube_goo.png`, gets the block-texture look. Slime (degraded): the vanilla `resource_pack/particles/` folder has 189 particle files and none of them is a slime particle, and `resource_pack/entity/slime.entity.json` declares no `particle_effects`, so the slime squish emitter is engine-side with no JSON to override. The only lever left is repainting the slime cell in the shared legacy sprite sheet `textures/particle/particles.png`, which is a static approximation rather than a reference to the slime block texture.", + "caveats": "Editing `particles.png` affects every particle that samples that cell, so the slime half cannot be made surgical. Ship the Sulfur Cube half first - it is clean and low risk.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/particles/sulfur_cube_particle.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/entity/slime.entity.json", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/particles", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets", + "https://learn.microsoft.com/minecraft/creator/reference/content/particlesreference/particlesintroduction" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ProperBreakParticles": { + "verdict": "blocked", + "confidence": "medium", + "summary": "Bedrock exposes no per-block break-particle control point: the destroy particle always samples the block's own face texture and `blocks.json` has no particle field.", + "mechanism": "Java does this by changing the `particle` texture slot inside each block's model JSON. Bedrock has no equivalent. The only per-vanilla-block visual control point is `resource_pack/blocks.json`, and across all 1213 entries in the vanilla file the complete key set is `textures`, `carried_textures`, `sound`, `isotropic` and `ambient_occlusion_exponent` - there is no particle or particle-texture key. The destroy particle itself, `minecraft:block_destruct` in `resource_pack/particles/block_destruct.json`, renders from `atlas.terrain` at UVs the engine supplies via `variable.emitter_texture_coordinate`, so overriding the particle cannot pick a different texture per block. The only remaining lever - changing a block's `blocks.json` texture entry - also changes how the block itself renders, which is not what the pack does. Vanilla block models, where Java keeps the particle slot, are hardcoded on Bedrock.", + "caveats": "Global changes to break particles (count, size, motion, tint) are still possible by overriding `minecraft:block_destruct`. Only per-block texture selection is unavailable. Some of the blocks the Java pack corrects may already sample a sensible face on Bedrock - worth spot-checking before closing the issue.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/blocks.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/particles/block_destruct.json", + "https://wiki.bedrock.dev/blocks/vanilla-block-models" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "NoBowlParticles": { + "verdict": "partial", + "confidence": "medium", + "summary": "Bedrock has no per-item eating-particle control, so a pack can only switch item-sprite eating particles off for every food, not just for soups and stews.", + "mechanism": "The lever is a particle override, not an item change. Bedrock's vanilla item definitions are data-driven but expose nothing particle-related: `behavior_pack/items/mushroom_stew.json` contains only `minecraft:use_duration`, `minecraft:max_stack_size` and `minecraft:food`. The item-sprite eat/break particle is the single shared effect `minecraft:breaking_item_icon` (`resource_pack/particles/breaking_item_icon.json`, rendered from `atlas.items` with UVs supplied by the engine). Re-declaring that identifier in your pack with `minecraft:emitter_rate_manual` set to `max_particles: 0` - the Bedrock Wiki's documented \"Disabling Particles\" technique - removes it, but for every item that uses it, not only bowls.", + "caveats": "Confirm in-game which vanilla particle Bedrock actually emits on food consumption before building: `minecraft:breaking_item_terrain` covers some feeding cases and the two effects are separate files. A global kill is a materially different pack from the Java one, so the maintainers may prefer to scope the issue as \"no eating particles at all\".", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/items/mushroom_stew.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/particles/breaking_item_icon.json", + "https://wiki.bedrock.dev/particles/disabling-particles", + "https://learn.microsoft.com/minecraft/creator/documents/overwritingassets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ItemHoldFix": { + "verdict": "partial", + "confidence": "medium", + "summary": "Bedrock's display-transform field exists but cannot be pointed at a vanilla item, so repositioning a held item still means replacing its held rendering wholesale with an attachable - possible, but very high effort per item.", + "mechanism": "Java fixes this by editing `display.firstperson_righthand` / `thirdperson_righthand` in each item's model JSON. Bedrock's nearest equivalent is `item_display_transforms`, a geometry-file field added in geometry format version 1.21.0 that takes `translation`, `rotation`, `scale`, `rotation_pivot` and `scale_pivot` for the `firstperson_righthand`, `firstperson_lefthand`, `thirdperson_righthand`, `thirdperson_lefthand`, `gui`, `ground`, `fixed`, `head`, `embedded` and `shelf` contexts. It is not usable here for two independent reasons: it requires the `Upcoming Creator Features` experimental toggle, and there is no vanilla item geometry file to put it in — `Mojang/bedrock-samples` ships no `resource_pack/items/` directory and `resource_pack/models/` holds only `entity/` and `mobs.json`, so vanilla items get their held form from engine sprite extrusion, not from a geometry document a pack could override. The only real resource-pack lever remains the attachable: a file under `resource_pack/attachables/` whose `minecraft:attachable/description/identifier` matches an existing vanilla item id replaces that item's held model, with placement coming from a `resource_pack/models/entity/*.geo.json` whose root bone is bound with `\"binding\": \"query.item_slot_to_bone_name(context.item_slot)\"` plus first- and third-person hold animations selected by `context.is_first_person`. This repo's `resource_packs/files/3d/3d_mace` and `resource_packs/files/unobtrusive/smaller_utilities` are working production examples of exactly that shape, and neither uses `item_display_transforms`. The vanilla pack ships attachables only for armour, bow, crossbow, elytra, shield, trident and turtle-shell helmet (55 files, no swords, tools, food, totem or fireworks), so every affected item needs hand-authored geometry and animations.", + "caveats": "Re-checked 2026-07-25 against the maintainer's `item_display_transforms` hypothesis; verdict unchanged, mechanism prose corrected. The earlier wording \"Bedrock has no per-item display transforms\" was wrong as written — the field exists in the geometry schema, it just has no vanilla item geometry to live in and is experiment-gated. Whether an attachable's geometry honours `item_display_transforms` at all is undocumented and unverified; the documented tutorial scopes the field to custom block geometry, and animations are the proven route. You still lose the engine's automatic sprite extrusion and must rebuild each item's held model by hand, including the enchantment-glint material. It is also unverified that Bedrock reproduces the Java \"floats above the hand\" offset at all - check the affected items in-game before anyone starts work; if Bedrock places them correctly there is nothing to port.", + "sources": [ + "https://wiki.bedrock.dev/items/attachables", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/attachables", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/models", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/itemdisplaytransforms?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/visualreference/geometry.v1.21.0?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "BeaconBeamFogFix": { + "verdict": "blocked", + "confidence": "high", + "summary": "The Java pack is a vanilla core-shader edit, and Bedrock resource packs have not been able to ship shaders since Render Dragon.", + "mechanism": "Missing entirely. The Java pack replaces vanilla `shaders/core/*.fsh`. The Bedrock vanilla resource pack has no `shaders` and no `materials` directory at all - its top-level folders are `animation_controllers`, `animations`, `attachables`, `biomes`, `entity`, `fogs`, `models`, `particles`, `render_controllers`, `sounds`, `texts`, `textures` and `ui`. The Bedrock Wiki states that resource-pack shaders \"are incompatible with Render Dragon. That means that they will not work on Windows and Console devices past 1.16.200, nor other devices past 1.18.30\". Bedrock's only data-driven fog control point is `resource_pack/fogs/*_fog_setting.json`, which is scoped to biomes and dimensions; it sets atmospheric fog distance and colour and cannot exempt a specific render layer such as the beacon beam.", + "caveats": "Bedrock's beacon beam is engine-rendered with no data-driven hook for how it interacts with fog or view bobbing, so even the partial fix is unavailable.", + "sources": [ + "https://wiki.bedrock.dev/concepts/shaders", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack", + "https://github.com/Mojang/bedrock-samples/tree/main/resource_pack/fogs" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + } + }, + "addons": { + "armor statues": { + "verdict": "partial", + "confidence": "medium", + "summary": "Most of the armor-stand editing can be rebuilt with a scripted UI plus behaviour- and resource-pack overrides of the vanilla armor stand, but Java's per-instance NBT flags (locked/disabled equipment slots, Invulnerable, Marker) have no Bedrock equivalent.", + "mechanism": "Override behavior_pack/entities/armor_stand.json to add entity properties under description.properties (client_sync: true) for pose, show-arms, no-baseplate and small, plus component groups carrying minecraft:scale for the small variant. Drive the visuals from a resource_pack/entity/armor_stand.entity.json override whose animation controller reads q.property('ns:pose') - the shipped geometry.armor_stand already has discrete 'baseplate', 'leftarm' and 'rightarm' bones, so an animation can scale them to 0 to hide them. The 'book' becomes a custom item that opens an @minecraft/server-ui ActionFormData / ModalFormData menu from world.afterEvents.playerInteractWithEntity; the menu writes values with Entity.setProperty() and free rotation with Entity.setRotation(). Bedrock already ships 13 built-in armor-stand poses (variable.pose_index in the vanilla client entity file), so the pose picker is re-driving existing content rather than new geometry. What is missing: there is no Bedrock control point equivalent to Java's DisabledSlots / Invulnerable / Marker NBT, so slot locking and invulnerability toggles cannot be reproduced.", + "caveats": "Needs @minecraft/server 2.x (scripting) plus a resource pack, so this ships as a full add-on, not a data-only pack. Overriding the vanilla armor stand's BP and RP files means the add-on will conflict with any other pack that touches armor stands. Invisibility would have to be approximated with the invisibility effect rather than an NBT flag.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/entities/armor_stand.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/resource_pack/models/entity/armor_stand.geo.json", + "https://raw.githubusercontent.com/Bedrock-OSS/bedrock-wiki/refs/heads/wiki/docs/entities/entity-properties.md", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entity?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server-ui/minecraft-server-ui?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/entityreference/examples/entitycomponents/minecraftcomponent_scale?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "custom nether portals": { + "verdict": "partial", + "confidence": "low", + "summary": "The ignition hook and portal placement both exist in Bedrock scripting, but whether vanilla minecraft:portal blocks survive in a non-standard frame on Bedrock is unverified, so a contributor may have to fall back to a custom portal block with scripted teleportation.", + "mechanism": "Detect the ignition with world.afterEvents.playerInteractWithBlock (flint and steel or fire charge used on obsidian / crying obsidian), flood-fill the enclosed area in script, and place minecraft:portal via Dimension.setBlockPermutation with the portal_axis block state set to 'x' or 'z' (portal_axis is a documented intrinsic state with values unknown/x/z). The configuration menu that Java exposes as /function custom_nether_portals:config becomes a namespaced custom command registered through system.beforeEvents.startup -> customCommandRegistry.registerCommand, or an @minecraft/server-ui form. The unverified part: minecraft.wiki states portal blocks 'can stably exist only within a Nether portal structure' and are destroyed once they receive a block update outside one - I could not confirm from a Tier 1 or Tier 2 Bedrock source whether Bedrock enforces this the same way. If it does, the fallback is a custom block (minecraft:geometry + minecraft:material_instances + light emission) that looks like a portal, with cross-dimension travel done by Entity.teleport(location, { dimension }) and the 1:8 coordinate scaling computed in script.", + "caveats": "Confidence is low specifically on vanilla-portal-block stability in arbitrary frames on Bedrock; that needs an in-game test before anyone commits to the approach. The custom-block fallback loses the vanilla portal ambience/overlay and would not carry mobs, minecarts or thrown items through unless that is scripted too.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/intrinsicblockstateslist?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/playerinteractwithblockafterevent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/teleportoptions?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands?view=minecraft-bedrock-stable", + "https://minecraft.wiki/w/Nether_Portal_(block)" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "mini blocks": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock custom blocks with head-sized geometry plus stonecutter-tagged recipes reproduce this directly; the only real cost is one block file, geometry and texture per mini block.", + "mechanism": "Each mini block is a behaviour-pack block under behavior_pack/blocks/ using minecraft:geometry (an 8x8x8 model authored in Blockbench) and minecraft:material_instances pointing at the vanilla-style texture, with sound set in the resource pack's blocks.json. The Bedrock Wiki's 'custom heads' page demonstrates exactly this head-block pattern, including the extra 22.5-degree bones plus bone_visibility needed to get the 16 placement rotations a real head has. The stonecutter recipe is a minecraft:recipe_shapeless with \"tags\": [\"stonecutter\"] - the documented Bedrock way to register a stonecutter recipe - whose result is the custom block's item form.", + "caveats": "These are custom blocks, not minecraft:player_head, so unlike the Java version they cannot be worn in the helmet slot unless a separate minecraft:wearable item is also authored. Volume is the real work: Vanilla Tweaks ships well over a hundred mini blocks, each needing a block JSON, a geometry and a texture, plus creative-menu categories and en_US.lang entries.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/advancedcustomblocks?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/recipereference/examples/recipedefinitions/recipe_shapeless?view=minecraft-bedrock-stable", + "https://raw.githubusercontent.com/Bedrock-OSS/bedrock-wiki/refs/heads/wiki/docs/blocks/custom-heads.md" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "more mob heads": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock behaviour packs support the exact loot-table technique the Java pack uses, but only seven head items ship in Bedrock so every other mob's head has to be authored as a custom block.", + "mechanism": "Add behavior_pack/loot_tables/entities/.json overrides using the documented conditions killed_by_player and random_chance_with_looting (chance + looting_multiplier) - the same shape as the Java advancement/loot approach. has_variant and has_mark_variant conditions cover per-variant heads such as sheep colours, cats and axolotls. Bedrock only ships skeleton_skull, wither_skeleton_skull, zombie_head, player_head, creeper_head, dragon_head and piglin_head as items, so heads for cows, sheep, villagers and the rest must be new custom blocks built the way the Bedrock Wiki 'custom heads' page describes (minecraft:geometry + minecraft:material_instances + 16-rotation bones).", + "caveats": "Overriding a vanilla mob's loot table replaces the whole file, so the vanilla drops must be copied verbatim from Mojang/bedrock-samples first or the mob loses its normal loot. Custom head blocks are not wearable and will not stack with the seven vanilla skulls.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/loottableconditions?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/introductiontoloottables?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/vanillalistingsreference/items?view=minecraft-bedrock-stable", + "https://raw.githubusercontent.com/Bedrock-OSS/bedrock-wiki/refs/heads/wiki/docs/blocks/custom-heads.md" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "name colors": { + "verdict": "partial", + "confidence": "medium", + "summary": "Colouring the floating nameplate is straightforward with the Script API, but colouring the name in chat needs the still-experimental chatSend event.", + "mechanism": "Register a namespaced command (system.beforeEvents.startup -> customCommandRegistry.registerCommand, e.g. /bedrocktweaks:color) or show an @minecraft/server-ui form, then set player.nameTag to the player's name prefixed with a section-sign formatting code - Entity.nameTag is a writable string property on the stable @minecraft/server surface and Player extends Entity. Persist the choice with player.setDynamicProperty so it survives relog and reapply it on world.afterEvents.playerSpawn. What is degraded: player.nameTag only drives the name above the player's head and selector/scoreboard display; the chat line still uses the client gamertag. To colour chat you would have to cancel world.beforeEvents.chatSend and re-broadcast the message yourself, and ChatSendBeforeEvent is documented as pre-release/experimental, so that half needs the Beta APIs toggle.", + "caveats": "Java's version colours the name everywhere via team colour, including chat and the player list; on Bedrock the player list is client-side and cannot be recoloured by a pack at all. Requires the Script API, so behaviour pack + scripts, not a data-only pack.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entity?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/rawmessagejson?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/chatsendbeforeevent?view=minecraft-bedrock-experimental" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "silence mobs": { + "verdict": "possible", + "confidence": "medium", + "summary": "Bedrock already ships the exact mechanism - a name-triggered entity event that swaps in a component group - so silencing a named mob is a pure behaviour-pack job with no scripting required.", + "mechanism": "For each vanilla mob, override behavior_pack/entities/.json and extend its minecraft:nameable component with name_actions entries whose name_filter matches each accepted spelling ('Silence me', 'silence me', 'silence_me') and whose on_named fires a custom event; that event adds a component group containing minecraft:sound_volume with \"value\": 0. This is the same pattern Mojang ships on the vindicator, where name_filter 'Johnny' fires minecraft:start_johnny to add the minecraft:vindicator_johnny group, with a default_trigger restoring the normal state when the mob is renamed to anything else - so an un-silence path comes for free.", + "caveats": "name_filter is exact-string matching, so every accepted spelling needs its own entry, and it needs one override file per mob type, which will conflict with other packs that modify the same entities. minecraft:sound_volume scales the entity's own sound emission; sounds triggered from resource-pack animation timelines are a separate channel and may not be covered. I found no source stating explicitly that value 0 is fully silent rather than merely inaudible at range, which is why this is medium and not high.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/reference/content/entityreference/examples/entitycomponents/minecraftcomponent_nameable?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/entityreference/examples/entitycomponents/minecraftcomponent_sound_volume?view=minecraft-bedrock-stable", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/entities/vindicator.json" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "wandering trades": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock trade tables are plain behaviour-pack JSON and accept any item id, so adding mini blocks to the wandering trader is a single file override - it just depends on the Mini Blocks pack existing first.", + "mechanism": "Override behavior_pack/trading/economy_trades/wandering_trader_trades.json. The file is a tiers array, each tier holding groups with num_to_select and a trades list; every trade is a wants/gives pair with quantity, price_multiplier, max_uses and optional loot-table-style functions. Custom mini-block ids drop straight into the gives entries, since Bedrock item ids in trade tables are not restricted to the minecraft namespace.", + "caveats": "Overriding the file replaces Mojang's whole wandering trader trade set, so the vanilla tiers must be copied from Mojang/bedrock-samples and the new group appended. num_to_select controls how many of the added trades actually appear per trader. Blocked on the Mini Blocks port landing first, since there is nothing to trade otherwise.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/trading/economy_trades/wandering_trader_trades.json", + "https://learn.microsoft.com/minecraft/creator/documents/introductiontoloottables?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/advancedcustomblocks?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "wandering trades hermit edition": { + "verdict": "partial", + "confidence": "medium", + "summary": "The trade table half is trivial, but Bedrock has no pack-side way to put a custom skin on a vanilla player head, so every Hermit head has to be authored as its own custom block.", + "mechanism": "Same trade-table override as the plain Wandering Trades pack (behavior_pack/trading/economy_trades/wandering_trader_trades.json, tiers > groups > trades, wants/gives). The heads themselves cannot be minecraft:player_head with a profile texture the way Java does it - I found no pack-facing control point for the vanilla player-head texture on Bedrock. The documented Bedrock route is a custom head block per Hermit: minecraft:geometry with the head model, minecraft:material_instances pointing at that Hermit's face texture, and the extra 22.5-degree bones plus bone_visibility described on the Bedrock Wiki 'custom heads' page.", + "caveats": "Roughly fifty custom blocks, each with geometry, texture, blocks.json sound entry, creative category and lang string - this is the bulk of the work, not the trades. The heads will not be wearable and will not render a live skin. Verdict is partial rather than blocked because the absence of a custom player-head texture hook is my inference from the docs, not an explicit statement of the limitation.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/trading/economy_trades/wandering_trader_trades.json", + "https://raw.githubusercontent.com/Bedrock-OSS/bedrock-wiki/refs/heads/wiki/docs/blocks/custom-heads.md", + "https://learn.microsoft.com/minecraft/creator/documents/advancedcustomblocks?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "cauldron concrete": { + "verdict": "possible", + "confidence": "medium", + "summary": "Every piece this needs - reading a dropped item stack, reading the cauldron's water state, and rewriting both - is available on the stable Script API, so it is a small scripted behaviour pack.", + "mechanism": "Watch item entities either through world.afterEvents.entitySpawn or a system.runInterval sweep of dimension.getEntities({ type: 'minecraft:item' }), read the stack via the minecraft:item entity component (EntityItemComponent.itemStack) and check it is a concrete powder. Read the block at the entity's position with Dimension.getBlock and test its permutation states: minecraft:cauldron exposes cauldron_liquid ('water' | 'lava') and fill_level (0-6). If it is a water cauldron with fill_level > 0, remove the item entity, spawn the matching hardened concrete stack with Dimension.spawnItem, and set the cauldron's fill_level back to 0 with Block.setPermutation.", + "caveats": "Behaviour pack with scripts, so it needs @minecraft/server; no resource pack required. Medium rather than high because the technique is assembled from individually documented primitives - I did not find a single doc or sample demonstrating the cauldron-item interaction end to end. Whether dropping the powder should drain the cauldron is a design call the Java pack makes; Bedrock imposes nothing here.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entityitemcomponent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockstateandtraitlistings?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/dimension?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/scripting/events?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "cauldron mud": { + "verdict": "possible", + "confidence": "medium", + "summary": "Identical scripted mechanism to Cauldron Concrete, and minecraft:mud exists as a normal Bedrock block, so the conversion target is available.", + "mechanism": "Same approach as Cauldron Concrete: detect item entities (world.afterEvents.entitySpawn or a system.runInterval sweep of dimension.getEntities({ type: 'minecraft:item' })), read the stack through the minecraft:item entity component, confirm it is minecraft:dirt, then check the block at that position is minecraft:cauldron with cauldron_liquid 'water' and fill_level > 0. Replace the item entity with a minecraft:mud stack via Dimension.spawnItem and drop the cauldron's fill_level with Block.setPermutation. minecraft:mud is a stock Bedrock block, listed in the default block listings, so no custom block is needed.", + "caveats": "Behaviour pack with scripts. Medium confidence for the same reason as Cauldron Concrete - the individual APIs are all Tier 1 documented but the combined interaction is not demonstrated anywhere I found. Note Bedrock already lets a water bottle on dirt make mud in vanilla, so the pack should be positioned as a bulk-conversion convenience rather than the only route to mud.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entityitemcomponent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockstateandtraitlistings?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/vanillalistingsreference/blocks?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/dimension?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "chunk loaders": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock has first-class chunk-keeping via ticking areas, so a behaviour pack with scripts can build a lodestone-based chunk loader, subject to a per-pack chunk budget.", + "mechanism": "Behaviour pack + `@minecraft/server`. Detect the trigger with `world.afterEvents.entitySpawn` (or `entityItemDrop`), filter for an item entity whose `minecraft:item` component holds `minecraft:nether_star`, and check `dimension.getBlock()` one block below for `minecraft:lodestone`. Then call `world.tickingAreaManager.createTickingArea(id, { dimension, from, to })` (TickingAreaOptions) to keep that chunk ticking; `/tickingarea add` via `dimension.runCommand()` is the pre-2.6.0 fallback. Persist the loader positions with `world.setDynamicProperty()` and re-create the areas on world load, because manager-created areas are described as temporary. Remove with `removeTickingArea()` from a `world.afterEvents.playerBreakBlock` handler on the lodestone.", + "caveats": "`TickingAreaManager` was added in @minecraft/server 2.6.0 (Bedrock 1.26.x); its `createTickingArea` signature changed during that release, so pin a script version. The manager enforces `maxChunkCount` per pack and throws `TickingAreaErrorReason.OverChunkLimit`, so the number of simultaneous chunk loaders is capped — the add-on should surface that limit to players rather than failing silently. Ticking areas are per-dimension.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/tickingareamanager?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/tickingareaoptions?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/tickingareaerrorreason?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/tickingareacommand?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entityspawnafterevent?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "double shulker shells": { + "verdict": "possible", + "confidence": "high", + "summary": "A one-file behaviour pack: Bedrock ships a real shulker loot table and behaviour packs override loot tables by path.", + "mechanism": "Behaviour pack only, no scripts. Copy `behavior_pack/loot_tables/entities/shulker.json` from bedrock-samples into your pack at the same path and change the `set_count` function from `{\"min\": 0, \"max\": 1}` to a flat 2 (keeping or dropping the `looting_enchant` function as desired). The shulker entity already references this table through its `minecraft:loot` component, and loot tables are one of the asset types a behaviour pack overwrites simply by placing a file at the identical path.", + "caveats": "Removing the `looting_enchant` function would also remove Looting scaling; keep it if you want Java-like behaviour on top of the guaranteed 2. Re-check the vanilla table after major Bedrock releases since the pack pins a copy of it.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/loot_tables/entities/shulker.json", + "https://learn.microsoft.com/minecraft/creator/documents/introductiontoloottables?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/entityreference/examples/entitycomponents/minecraftcomponent_loot?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "dragon drops": { + "verdict": "possible", + "confidence": "medium", + "summary": "Doable as a scripted behaviour pack — the Ender Dragon has no loot table in Bedrock, so the drop has to be spawned from an `entityDie` handler instead.", + "mechanism": "Behaviour pack + `@minecraft/server`. `behavior_pack/entities/ender_dragon.json` in bedrock-samples carries no `minecraft:loot` component (death runs through `minecraft:on_death` -> `minecraft:behavior.dragondeath`), so the loot-table route that works for mobs is not wired up here. Subscribe to `world.afterEvents.entityDie`, test `event.deadEntity.typeId === 'minecraft:ender_dragon'`, and call `dimension.spawnItem(new ItemStack('minecraft:elytra'), location)` and the same for `minecraft:dragon_egg` at the dragon's death position (or on the exit portal). Worth testing first whether overriding `entities/ender_dragon.json` with an added `minecraft:loot` component works, since behaviour packs do override vanilla entity files by identifier — if it does, that is the tidier build.", + "caveats": "Entity files do not merge, so an override means copying the whole vanilla `ender_dragon.json` and re-syncing it on Bedrock updates; the script route avoids that. Bedrock already places a dragon egg on the exit portal after the first kill, so guard against duplicating it on kill one if you want Java parity.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/entities/ender_dragon.json", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entitydieafterevent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/dimension?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/concepts/overwriting-assets" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "elevators": { + "verdict": "possible", + "confidence": "medium", + "summary": "Every piece this needs — item-drop detection, jump/sneak input events, and teleport — exists in the Script API, so it is a normal scripted add-on.", + "mechanism": "Behaviour pack + `@minecraft/server`. Registration: `world.afterEvents.entitySpawn` (or `entityItemDrop`) filtered to item entities holding `minecraft:ender_pearl`, then read the block below with `dimension.getBlock()` and require a `*_wool`; store the elevator position and wool colour in `world.setDynamicProperty()` so it survives restarts. Activation: `world.afterEvents.playerButtonInput` with `InputButton.Jump` and `InputButton.Sneak` (or poll `Player.isJumping` / `Entity.isSneaking`), confirm the player is standing on a registered elevator, scan up/down for the next registered wool of the same colour, and move the player with `player.teleport()` / `tryTeleport()`.", + "caveats": "`InputButton.Sneak` is documented as being held for one tick or less on touch interfaces, so treat it as an edge trigger rather than a hold. `Player.isJumping` / `playerButtonInput` need @minecraft/server 1.x (1.20.40+) for the `is*` properties and a newer version for `InputButton`; pin a floor. Storing elevators in dynamic properties has a byte budget, so key them compactly.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/inputbutton?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/worldafterevents?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/player?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.20.40?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entityspawnafterevent?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "ender chest always drops": { + "verdict": "possible", + "confidence": "medium", + "summary": "Achievable only as a scripted behaviour pack — Bedrock has no vanilla block loot tables to edit, so the drop must be replaced in a break event.", + "mechanism": "Behaviour pack + `@minecraft/server`. There is no loot-table route: bedrock-samples' `behavior_pack/loot_tables/` contains only `chests`, `dispensers`, `entities`, `equipment`, `gameplay`, `pots` and `spawners` — there is no `blocks` folder — and vanilla block definitions cannot be overwritten. Instead use `world.beforeEvents.playerBreakBlock`: if `block.typeId === 'minecraft:ender_chest'` and the held item has no Silk Touch (check via the `minecraft:enchantable` component on `itemStack`), set `event.cancel = true`, then in a `system.run()` callback clear the block with `block.setType('minecraft:air')`, `dimension.spawnItem(new ItemStack('minecraft:ender_chest'), location)` and apply tool durability yourself. The simpler after-event variant works too but must additionally delete the 8 obsidian item entities vanilla drops.", + "caveats": "Only covers player-mined ender chests; explosions or other destruction paths keep vanilla behaviour, whereas the Java datapack changes the loot table so every break path is covered. Cancelling the break means re-implementing durability loss and break particles/sound if you want them exact.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/behavior_pack/loot_tables", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/playerbreakblockafterevent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/dimension?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "fast leaf decay": { + "verdict": "partial", + "confidence": "medium", + "summary": "Reproducible as a scripted imitation of decay, but Bedrock exposes no way to change the vanilla leaf-decay rate itself, so the whole check has to be re-implemented.", + "mechanism": "Behaviour pack + `@minecraft/server`. Vanilla blocks cannot be overwritten by a behaviour pack, and there is no gamerule or component for leaf decay speed, so the pack has to drive it: subscribe to `world.afterEvents.playerBreakBlock`, and when the broken block is a log, flood-fill outward with `dimension.getBlock()` for `*_leaves` permutations whose `persistent_bit` state is false, then remove them over the next few ticks with `system.runInterval()` — either `block.setType('minecraft:air')` plus a manual `dimension.spawnItem()` for saplings/sticks/apples, or `dimension.runCommand('setblock x y z air destroy')` which drops the block's normal items.", + "caveats": "The distance-to-log rule that vanilla uses has to be re-implemented in script, so edge cases (overlapping canopies, leaves near a surviving trunk, player-placed leaves) can diverge from Java. Large canopies mean a bounded per-tick budget or the watchdog will complain. Decay from causes other than a player mining a log is unaffected.", + "sources": [ + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/playerbreakblockafterevent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/dimension?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/commands/commands/setblock?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "glass always drops": { + "verdict": "possible", + "confidence": "medium", + "summary": "Needs a scripted behaviour pack rather than a loot-table edit, because Bedrock has no vanilla block loot tables — but the break-event route is straightforward.", + "mechanism": "Behaviour pack + `@minecraft/server`. bedrock-samples' `behavior_pack/loot_tables/` has no `blocks` folder and vanilla block definitions cannot be overwritten, so there is nothing to override. Subscribe to `world.afterEvents.playerBreakBlock`, test `event.brokenBlockPermutation` against the glass family (`minecraft:glass`, `minecraft:*_stained_glass`, `minecraft:tinted_glass`, `minecraft:glass_pane`, `minecraft:*_stained_glass_pane`), check the tool in `itemStackBeforeBreak` for Silk Touch via its `minecraft:enchantable` component, and if absent call `dimension.spawnItem(permutation.getItemStack(1), block.location)`. Because glass normally drops nothing there is no vanilla drop to clean up.", + "caveats": "Only player-mined glass is covered; glass broken by explosions or pistons still drops nothing, whereas the Java datapack rewrites the loot table and covers every path. Keep the block list in sync as Mojang adds glass variants.", + "sources": [ + "https://github.com/Mojang/bedrock-samples/tree/main/behavior_pack/loot_tables", + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/playerbreakblockafterevent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/dimension?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "more effective tools": { + "verdict": "blocked", + "confidence": "medium", + "summary": "Bedrock exposes no control point for changing which vanilla tool is effective on a vanilla block: neither vanilla blocks nor vanilla tools ship as editable JSON.", + "mechanism": "The two components that could do this are `minecraft:destructible_by_mining` with `item_specific_speeds` (a block component) and `minecraft:digger` with `destroy_speeds` (an item component). Both live on definitions Bedrock does not expose for vanilla content: bedrock-samples' `behavior_pack/` has no `blocks/` directory at all, and its `behavior_pack/items/` contains only foods, bundles, spears and a few specials — no pickaxe, axe, shovel or sword — so there is nothing to override for either half. The Bedrock Wiki lists vanilla blocks explicitly under 'Things that Cannot be Overwritten'. The Script API has no mining-speed or effective-tool API either; the closest approximation is granting a temporary Haste effect while a player swings at a chosen block, which speeds up everything they mine and is not a faithful port.", + "caveats": "One source pulls the other way and is worth a contributor re-testing before this is treated as final: the block definition reference says an identifier 'must not use the Minecraft namespace unless overriding a Vanilla block', implying vanilla block override is intended to exist. Even if it does work, no vanilla block JSON is shipped to copy, so each block would have to be redefined from scratch. Re-check after any release that adds vanilla blocks or vanilla tools to bedrock-samples.", + "sources": [ + "https://wiki.bedrock.dev/concepts/overwriting-assets", + "https://github.com/Mojang/bedrock-samples/tree/main/behavior_pack", + "https://github.com/Mojang/bedrock-samples/tree/main/behavior_pack/items", + "https://learn.microsoft.com/minecraft/creator/reference/content/itemreference/examples/itemcomponents/minecraft_digger?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/blockcomponents/minecraftblock_destructible_by_mining?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/blockreference/examples/definitions/blockdefinitionproperties?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "multiplayer sleep": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock already has a `playersSleepingPercentage` gamerule, so the add-on is mostly a script that sets it plus a UI for configuration.", + "mechanism": "Behaviour pack + `@minecraft/server`. `playersSleepingPercentage` exists both as an integer `/gamerule` and as a writable property on the `GameRules` class, so the pack sets `world.gameRules.playersSleepingPercentage = ` on world load and Bedrock itself handles the night/rain skip. Replace the Java `/trigger mpSleep` and `/function multiplayer_sleep:config` entry points with either a `@minecraft/server-ui` `ModalFormData` opened from a config item, or a custom command registered through the Script API custom-command registry. Progress messages ('2/5 players sleeping') can be driven by polling `Entity.isSleeping` across `world.getAllPlayers()` and calling `player.sendMessage()`.", + "caveats": "Vanilla Bedrock only exposes the percentage; the Java pack's extra behaviours (per-player opt-out, announcement wording, counting only overworld players) all have to be re-implemented in script. `world.gameRules` requires @minecraft/server 1.11.0 or later.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/gamerules?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/gamerule?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/commands/commands/gamerule?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.21?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "painting picker": { + "verdict": "blocked", + "confidence": "high", + "summary": "Microsoft's own documentation states there is no way to control which painting variant gets placed on Bedrock, so the core of this pack cannot be built.", + "mechanism": "The stonecutter half is fine — Bedrock recipes support `\"tags\": [\"stonecutter\"]` on shaped and shapeless recipes, so a behaviour pack can add stonecutter entries. The painting half is not: the 'Create a Custom Painting' article states 'Paintings are randomly called based on their size and the amount of space available on the wall you're placing them on. There's currently no way to guarantee the painting you place will show your custom image.' Bedrock backs this up structurally — there is no `behavior_pack/entities/painting.json` and no `behavior_pack/items/painting.json` in bedrock-samples (the vanilla entity listing shows `painting` with no linked definition file), so the motive is engine-side only, and `@minecraft/server` exposes no painting/motive entity component to read or set it.", + "caveats": "Re-check if Mojang ever ships a `painting.json` behaviour definition or adds a painting variant component to `EntityComponentTypes`. A partial substitute would be a resource pack that replaces the painting textures, but that changes every painting globally rather than letting a player pick one.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/overwritingpaintings?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/vanillalistingsreference/entities?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/recipereference/examples/recipedefinitions/recipe_shapeless?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entitycomponenttypes?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "redstone rotation wrench": { + "verdict": "possible", + "confidence": "high", + "summary": "Buildable as a Bedrock add-on: a custom wrench item whose script custom component rewrites the direction block state of the redstone component it is used on.", + "mechanism": "Behaviour pack `items/wrench.json` (plus a resource pack `textures/item_texture.json` entry and icon) declaring a namespaced custom component, registered in script with `ItemComponentRegistry.registerCustomComponent` and an `onUseOn` handler (`ItemCustomComponent.onUseOn`, stable since 1.21.20). In the handler, read `event.block.permutation` and write the next rotation with `BlockPermutation.withState(...)` + `Block.setPermutation(...)`. The vanilla block listing confirms every redstone component Bedrock exposes a rotation state for: `minecraft:unpowered_repeater`/`powered_repeater` use `minecraft:cardinal_direction` (+ `repeater_delay`), `unpowered_comparator`/`powered_comparator` use `minecraft:cardinal_direction`, and `minecraft:dropper`/dispenser/observer/piston/hopper use `facing_direction`. A shaped recipe in `behavior_pack/recipes/` gives the wrench a craft.", + "caveats": "Needs a behaviour pack with scripts plus a paired resource pack for the item texture, so it is an `addons` entry, not a resource pack. Requires Minecraft Bedrock 1.21.20+ for item custom components (Scripting V2 recommended). `Block.setPermutation` writes the state directly and does not re-run vanilla placement validation, so observers/pistons may need a neighbour nudge to re-evaluate; and unlike Java the wrench cannot be given a bespoke right-click sound/animation without extra work.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/itemcustomcomponent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.21.20?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/block?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/blockpermutation?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/vanillalistingsreference/blocks?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "spectator conduit power": { + "verdict": "possible", + "confidence": "medium", + "summary": "A scripted add-on can grant Conduit Power to players in spectator mode and expose a per-player toggle, using GameMode.Spectator plus Entity.addEffect.", + "mechanism": "Behaviour pack script: a `system.runInterval` loop over `world.getPlayers()`, testing `Player.getGameMode() === GameMode.Spectator` and a per-player opt-in stored with `Player.setDynamicProperty`, then calling `Player.addEffect('minecraft:conduit_power', duration, { showParticles: false })` — `conduit_power` is a documented Bedrock effect id. Java's `/trigger` toggle has no Bedrock equivalent, but `StartupEvent.customCommandRegistry.registerCommand` (Custom Commands, 1.21.100+) with `CustomCommandPermissionLevel.Any` gives non-operator players a real `/namespace:conduittoggle`; a `@minecraft/server-ui` ActionFormData menu is an alternative.", + "caveats": "Version floor 1.21.100 for a player-runnable custom command toggle (without it, fall back to a chat-command listener or a UI form). Not verified in-game that Bedrock applies and renders status effects to a player in spectator mode — that is the one assumption a contributor should test first before building anything else.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/gamemode?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entity?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/commandsreference/examples/commands/effect?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.21.100?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "spectator night vision": { + "verdict": "possible", + "confidence": "medium", + "summary": "Same build as Spectator Conduit Power — a script loop that applies Night Vision while a player is in spectator mode, with a player-runnable toggle command.", + "mechanism": "Behaviour pack script: `system.runInterval` over `world.getPlayers()`, gated on `Player.getGameMode() === GameMode.Spectator` and a `Player.getDynamicProperty` opt-in flag, calling `Player.addEffect('minecraft:night_vision', duration, { showParticles: false })` and refreshing before it lapses so there is no screen flicker. `night_vision` is a documented Bedrock effect id. The toggle is a script custom command registered via `StartupEvent.customCommandRegistry.registerCommand` with `CustomCommandPermissionLevel.Any` (1.21.100+), standing in for Java's `/trigger`.", + "caveats": "Version floor 1.21.100 for a player-runnable custom command. Not verified in-game that Bedrock renders the night vision screen effect for a player in spectator mode; confirm that before investing in the toggle UI. Note also that Bedrock spectator mode itself has a rougher history than Java's (it was `/gamemode 6` and buggy when first exposed), so test on the current release.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/gamemode?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entity?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/commandsreference/examples/commands/effect?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands?view=minecraft-bedrock-stable", + "https://minecraft.wiki/w/Spectator" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "storm channeling": { + "verdict": "partial", + "confidence": "medium", + "summary": "The trigger and the thunderstorm are fully supported by the Script API; only the exact 150-durability cost on the specific thrown trident is awkward to reproduce.", + "mechanism": "Behaviour pack script: poll `Dimension.getEntities({ type: 'minecraft:thrown_trident' })` on a `system.runInterval` and test `entity.location.y` against the overworld build height; recover the thrower from `EntityProjectileComponent.owner` (the same component exposes `lightningStrikeOnHit`, which is how Bedrock models a Channeling trident). Then call `Dimension.setWeather(WeatherType.Thunder, duration)` (available since 1.20.40). `world.afterEvents.itemReleaseUse` is an alternative trigger since the trident is a chargeable item, giving you `source` and `itemStack` directly. Durability is applied through `ItemDurabilityComponent.damage` on the trident found in the thrower's inventory via `EntityInventoryComponent`/`Container.find`.", + "caveats": "Degraded versus Java: the 150 durability has to be charged to a matching trident located by inventory search after the throw (Loyalty returns it immediately; without Loyalty you must wait for the pickup), not to the exact thrown item instance, so an edge case with two tridents can charge the wrong one. Needs 1.20.40+ for `Dimension.setWeather`. Whether `itemReleaseUse` fires for a trident throw on Bedrock is unverified — the entity-polling path is the safe one.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/dimension?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/weathertype?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.20.40?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entityprojectilecomponent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/itemdurabilitycomponent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/itemreleaseuseafterevent?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "terracotta rotation wrench": { + "verdict": "possible", + "confidence": "high", + "summary": "Buildable as a Bedrock add-on: glazed terracotta carries a `facing_direction` block state that a scripted custom item can cycle on use.", + "mechanism": "Same shape as the redstone wrench — behaviour pack `items/wrench.json` with a namespaced custom component, a resource pack texture entry, and an `onUseOn` handler registered through `ItemComponentRegistry.registerCustomComponent` (stable since 1.21.20). In the handler, check the block id against the 16 `minecraft:*_glazed_terracotta` blocks and call `Block.setPermutation(block.permutation.withState('facing_direction', next))`. The vanilla block listing confirms the state exists on every colour (for example `minecraft:pink_glazed_terracotta | facing_direction`).", + "caveats": "Requires 1.21.20+ for item custom components and a paired resource pack for the wrench texture, so it belongs in `addons`, not resource packs. `facing_direction` on glazed terracotta accepts up/down values that vanilla placement never produces; the script should restrict the cycle to the four horizontal values to avoid unreachable-looking orientations.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/reference/content/vanillalistingsreference/blocks?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/itemcustomcomponent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/block?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/blockpermutation?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.21.20?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "timber": { + "verdict": "possible", + "confidence": "medium", + "summary": "A scripted behaviour pack can fell a whole tree on the first log break, charge the axe durability and expose a per-player toggle command.", + "mechanism": "Subscribe to `world.afterEvents.playerBreakBlock`; the event supplies `brokenBlockPermutation`, `player` and `itemStackBeforeBreak`/`itemStackAfterBreak`, so you can test for an axe and a log. Flood-fill the connected logs with `Block.offset`/`Block.above` and remove them with `Block.setType('minecraft:air')`, dropping the items with `Dimension.spawnItem` (or `BlockPermutation.getItemStack`). Charge the axe by bumping `ItemDurabilityComponent.damage` on the mainhand stack obtained through `EntityEquippableComponent.getEquipmentSlot(EquipmentSlot.Mainhand)` and writing it back. Java's `/trigger TimberToggle` maps to a script custom command registered with `StartupEvent.customCommandRegistry.registerCommand` at `CustomCommandPermissionLevel.Any` (1.21.100+), with the per-player flag in a dynamic property.", + "caveats": "Version floor 1.21.100 for a player-runnable toggle command; `/function timber:help` becomes a second custom command or a `@minecraft/server-ui` form. Drops are re-spawned by script rather than by the vanilla loot pipeline, so Fortune/Silk Touch and any loot-table overrides have to be handled explicitly. Very large custom trees need the flood-fill capped and spread over ticks to avoid a watchdog hang, and blocks in unloaded chunks throw.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/playerbreakblockafterevent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/block?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/itemdurabilitycomponent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.21.100?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "wood stripper": { + "verdict": "possible", + "confidence": "high", + "summary": "Pure data: Bedrock stonecutter recipes are ordinary shapeless recipes tagged `stonecutter`, so a behaviour pack can add log/wood to stripped-log/wood conversions with no scripting.", + "mechanism": "One `minecraft:recipe_shapeless` file per wood type in `behavior_pack/recipes/`, with `\"tags\": [ \"stonecutter\" ]`, a single `ingredients` entry (for example `minecraft:oak_log`) and a `result` of the stripped variant. The shapeless recipe reference documents `tags` as \"Item that can create the shapeless recipe such as 'stonecutter'\", and the shipped vanilla `behavior_pack/recipes/stonecutter_andesite_wall.json` is exactly this shape. Add an `unlock` entry so the recipe appears in the recipe book when the `recipesunlock` game rule is on. No resource pack and no script module are needed.", + "caveats": "Bedrock's stonecutter shows outputs once the input is inserted, so the UX differs slightly from Java's recipe list. Cover all the modern wood sets (oak through pale oak, plus crimson/warped stems and hyphae, and the `*_wood` full-bark variants) or the pack will look half-finished. Recipes are additive, so this does not conflict with vanilla stonecutting.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/reference/content/recipereference/examples/recipedefinitions/minecraftrecipe_shapeless?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/recipereference/examples/recipedefinitions/recipe_shapeless?view=minecraft-bedrock-stable", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/recipes/stonecutter_andesite_wall.json" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "anti creeper grief": { + "verdict": "possible", + "confidence": "high", + "summary": "Pure data: a behaviour pack override of the vanilla creeper sets `breaks_blocks: false` and `damage_scaling: 0` on its explosion, no scripting required.", + "mechanism": "Copy `behavior_pack/entities/creeper.json` from bedrock-samples into the pack and edit every `minecraft:explode` instance — vanilla has four, in the `minecraft:exploding`, `minecraft:charged_exploding`, `minecraft:forced_exploding` and `minecraft:forced_charged_exploding` component groups — adding `\"breaks_blocks\": false` and `\"damage_scaling\": 0`. The component reference documents `breaks_blocks` (\"If true, the explosion will destroy blocks in the explosion radius\", default true) and `damage_scaling` (\"A value of 0 prevents the explosion from dealing any damage\"). Modifying vanilla entities this way is the documented first use of entity JSON files in a behaviour pack.", + "caveats": "`damage_scaling` requires `format_version` 1.21.40 or later (vanilla creeper.json already ships at 1.26.0). `damage_scaling: 0` zeroes the explosion's damage to every entity, not just players, so mobs caught in a creeper blast also survive — a small divergence from the Java pack's wording. Overriding a vanilla entity replaces the whole file, so the pack has to be re-synced against bedrock-samples whenever Mojang changes the creeper.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/reference/content/entityreference/examples/entitycomponents/minecraftcomponent_explode?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.21.40?view=minecraft-bedrock-stable", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/entities/creeper.json", + "https://learn.microsoft.com/minecraft/creator/documents/entitybehaviorintroduction?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "anti enderman grief": { + "verdict": "possible", + "confidence": "high", + "summary": "Pure data: a behaviour pack override of the vanilla enderman drops the two AI goals that let it pick blocks up and put them down.", + "mechanism": "Copy `behavior_pack/entities/enderman.json` from bedrock-samples and delete `minecraft:behavior.take_block` (vanilla: priority 11, with the full `blocks` allowlist of dirt, sand, flowers, TNT and so on) and `minecraft:behavior.place_block` (vanilla: priority 10). Both are documented AI goals — `take_block` is described as \"AI goal that makes entities pick up blocks from the world, like Endermen grabbing blocks to carry\". If you would rather keep the goal registered, `take_block` also exposes `chance` and a `blocks` allowlist you can narrow, and `affected_by_griefing_rule`. Modifying vanilla entities is the documented first use of behaviour pack entity JSON.", + "caveats": "Overriding a vanilla entity replaces the whole file, so the pack must be re-synced against bedrock-samples on Mojang updates or the enderman will silently lose unrelated new behaviour. Note the vanilla file is currently `format_version` 1.26.10 and `minecraft:behavior.take_block`/`place_block` themselves need at least 1.21.100. The `mobgriefing` game rule is the blunt built-in alternative, but it also disables creeper, ghast and villager farming behaviour.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/entities/enderman.json", + "https://learn.microsoft.com/minecraft/creator/reference/content/entityreference/examples/entitygoals/minecraftbehavior_take_block?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/entityreference/examples/entitygoals/minecraftbehavior_place_block?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/entitybehaviorintroduction?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "anti ghast grief": { + "verdict": "possible", + "confidence": "high", + "summary": "Pure data: a behaviour pack override of the ghast's fireball entity sets `breaks_blocks: false` on its explosion, no scripting required.", + "mechanism": "Copy `behavior_pack/entities/fireball.json` from bedrock-samples and edit the `minecraft:explode` component inside the `minecraft:exploding` component group — vanilla is `{ \"causes_fire\": true, \"fire_affected_by_griefing\": true, \"fuse_lit\": true, \"power\": 1, \"destroy_affected_by_griefing\": true, \"fuse_length\": 0 }` — adding `\"breaks_blocks\": false`. `breaks_blocks` is documented as \"If true, the explosion will destroy blocks in the explosion radius\" with a default of true, so it has to be set explicitly. Optionally also set `\"causes_fire\": false` if the pack should stop the fire as well as the crater; leave `damage_scaling` alone so ghasts still hurt players.", + "caveats": "The override applies to every `minecraft:fireball` entity, not only ghast-launched ones. Overriding a vanilla entity replaces the whole file, so it needs re-syncing against bedrock-samples on Mojang updates. Blaze projectiles are a different entity (`minecraft:small_fireball`) and are unaffected.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/reference/content/entityreference/examples/entitycomponents/minecraftcomponent_explode?view=minecraft-bedrock-stable", + "https://github.com/Mojang/bedrock-samples/tree/preview/behavior_pack/entities/fireball.json", + "https://learn.microsoft.com/minecraft/creator/documents/entitybehaviorintroduction?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "armored elytra": { + "verdict": "blocked", + "confidence": "medium", + "summary": "Bedrock has no item component that grants elytra gliding, so a merged chestplate+elytra item cannot exist; the anvil/grindstone merge logic itself would be scriptable, but the resulting item could never fly.", + "mechanism": "The merge/split half is buildable: a script can watch item entities near an anvil or grindstone (world.afterEvents.entitySpawn plus dimension.getEntities with type 'minecraft:item', reading EntityItemComponent.itemStack) and swap them for a custom item, carrying enchantments across with ItemEnchantableComponent.getEnchantments/addEnchantments. What is missing is the item itself. The complete Bedrock item component list contains no glider/elytra component - the only chest-slot mechanism is 'minecraft:wearable' with slot 'slot.armor.chest' and a 'protection' value, which grants armour but not flight. Gliding is hardcoded to the vanilla minecraft:elytra item (see SimulatedPlayer.glide: 'Elytra must be equipped'), and there is no API to force or grant gliding on another item. A custom 'armored elytra' item would therefore be a chestplate that cannot fly.", + "caveats": "Approximations exist but all lose the point of the pack: keep the real vanilla elytra and script a damage-reduction effect to fake the chestplate, or override the vanilla minecraft:elytra item definition to add wearable protection (which would apply to every elytra in the world and is not documented to preserve the engine's glide behaviour). Re-check if Mojang ever ships a glider item component.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/reference/content/itemreference/examples/itemcomponentlist", + "https://learn.microsoft.com/minecraft/creator/reference/content/itemreference/examples/itemcomponents/minecraft_item_v1_26_0", + "https://raw.githubusercontent.com/Bedrock-OSS/bedrock-wiki/refs/heads/wiki/docs/items/item-components.md", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/itemenchantablecomponent" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "bat membranes": { + "verdict": "possible", + "confidence": "high", + "summary": "Both halves are straightforward behaviour-pack work: the doInsomnia gamerule already turns phantoms off on Bedrock, and the vanilla bat has no loot component, so a pack can simply add one.", + "mechanism": "Phantoms: set the doInsomnia gamerule to false ('/gamerule doinsomnia false', or world.gameRules.doInsomnia = false from @minecraft/server on world load) - the Bedrock GameRule enum documents DoInsomnia as controlling phantom spawning. Optionally also ship a spawn_rules/phantom.json override. Membranes: bedrock-samples' behavior_pack/entities/bat.json has no 'minecraft:loot' component at all, so the pack overrides entities/bat.json to add \"minecraft:loot\": { \"table\": \"loot_tables/entities/bat.json\" } and ships that loot table with a phantom_membrane entry (set_count plus looting_enchant, and a killed_by_player condition if you want to match Java).", + "caveats": "doInsomnia is a world setting, so the pack changes a gamerule rather than removing the mob - phantoms can still be summoned by command or spawn egg. Overriding entities/bat.json conflicts with any other add-on that also overrides the bat.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/gamerule", + "https://learn.microsoft.com/minecraft/creator/reference/content/commandsreference/examples/commands/gamerule", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/entities/bat.json", + "https://learn.microsoft.com/minecraft/creator/reference/content/entityreference/examples/entitycomponents/minecraftcomponent_loot", + "https://learn.microsoft.com/minecraft/creator/documents/lootandtradetablefunctions" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "classic fishing loot": { + "verdict": "possible", + "confidence": "high", + "summary": "Pure loot-table override - Bedrock ships the fishing tables as editable JSON in the vanilla behaviour pack, so a behaviour pack can replace them with the pre-1.16 values.", + "mechanism": "bedrock-samples has behavior_pack/loot_tables/gameplay/fishing.json (a weighted roll across junk/treasure/fish) plus loot_tables/gameplay/fishing/junk.json, treasure.json and fish.json. A behaviour pack that ships files at the same paths replaces them, so restoring the pre-1.16 pools and weights is a matter of editing entries, weights and quality values in those four files. No scripting needed.", + "caveats": "Bedrock's fishing tables are not byte-identical to Java's, so 'pre-1.16 Java' has to be translated to Bedrock item ids and Bedrock's quality/luck handling. Conflicts with any other pack that overrides the same loot tables.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/loot_tables/gameplay/fishing.json", + "https://learn.microsoft.com/minecraft/creator/documents/introductiontoloottables", + "https://learn.microsoft.com/minecraft/creator/documents/createloottable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "confetti creepers": { + "verdict": "possible", + "confidence": "medium", + "summary": "Reproducible with a behaviour pack plus a small script: tag a random share of creepers on spawn, then strip the block damage from their explosion and play a custom confetti particle instead.", + "mechanism": "Roll the chance on world.afterEvents.entitySpawn (or with a randomize entity event in an entities/creeper.json override) and Entity.addTag the chosen creepers. Subscribe to world.beforeEvents.explosion and, when event.source carries the tag, call setImpactedBlocks([]) so no blocks are destroyed (or set cancel = true and re-create the effect yourself). Confetti is a normal resource-pack particle effect JSON played with dimension.spawnParticle / Player.spawnParticle. The '/trigger cftCreep' config screen maps onto either a scripted custom command (system.beforeEvents.startup -> customCommandRegistry.registerCommand) or a @minecraft/server-ui form.", + "caveats": "Bedrock has no /trigger command, so the config UI has to be rebuilt; scripted custom commands need Minecraft 1.21.100 or later. Cancelling the explosion also removes its sound, knockback and entity damage, so those have to be re-added by hand if you want them. minecraft:explode on the entity itself only exposes destroy_affected_by_griefing (tied to the mobGriefing gamerule), not a per-creeper block-damage switch, which is why the script hook is the right control point.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/explosionbeforeevent", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/worldbeforeevents", + "https://learn.microsoft.com/minecraft/creator/reference/content/entityreference/examples/entitycomponents/minecraftcomponent_explode", + "https://learn.microsoft.com/minecraft/creator/documents/particleeffects", + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "husks drop sand": { + "verdict": "possible", + "confidence": "high", + "summary": "Loot-table work only - the husk currently shares the zombie's loot table, so point it at its own table and add a sand pool with a looting bonus.", + "mechanism": "bedrock-samples' behavior_pack/entities/husk.json declares \"minecraft:loot\": { \"table\": \"loot_tables/entities/zombie.json\" }. Override entities/husk.json so the loot component points at a new loot_tables/entities/husk.json, which reproduces the zombie pools (or references them with a type 'loot_table' entry) and adds a sand pool using the set_count function for 0-2 and the looting_enchant function for the Looting bonus. Microsoft's loot table docs confirm looting_enchant works on loot tables invoked by an entity's death, which is exactly this case.", + "caveats": "The husk's loot component appears inside component groups, so the override has to keep those groups intact (baby/jockey/rider variants). Conflicts with any other pack overriding entities/husk.json.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/entities/husk.json", + "https://learn.microsoft.com/minecraft/creator/documents/lootandtradetablefunctions", + "https://learn.microsoft.com/minecraft/creator/reference/content/entityreference/examples/entitycomponents/minecraftcomponent_loot", + "https://learn.microsoft.com/minecraft/creator/documents/createloottable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "silk touch budding amethyst": { + "verdict": "possible", + "confidence": "medium", + "summary": "Bedrock has no vanilla block loot tables to override, but the Script API can watch the break event, check for Silk Touch and spawn the block - and budding amethyst is a giveable item on Bedrock.", + "mechanism": "Bedrock's vanilla behaviour pack has no loot_tables/blocks folder (bedrock-samples' loot_tables contains only chests, dispensers, entities, equipment, gameplay, pots and spawners), so vanilla block drops cannot be redefined by JSON. Instead subscribe to world.afterEvents.playerBreakBlock, test brokenBlockPermutation.type.id === 'minecraft:budding_amethyst', read the tool from itemStackBeforeBreak and call getComponent(ItemComponentTypes.Enchantable).hasEnchantment('silk_touch'), then dimension.spawnItem(new ItemStack('minecraft:budding_amethyst'), block.location). minecraft.wiki confirms budding amethyst exists as a giveable item on Bedrock and normally drops nothing, so there is no double-drop to suppress.", + "caveats": "Script-driven, so it only fires for player breaks - explosions, pistons and other destruction paths would need separate handling, and it ignores the doTileDrops gamerule unless you check it yourself. Requires a behaviour pack with the scripts module rather than a data-only pack.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/playerbreakblockafterevent", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/itemenchantablecomponent", + "https://github.com/Mojang/bedrock-samples/tree/main/behavior_pack/loot_tables", + "https://minecraft.wiki/w/Budding_Amethyst" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "xp bottling": { + "verdict": "partial", + "confidence": "medium", + "summary": "Bottling XP at an enchanting table is fully scriptable, but the 'smelt the bottle to get your XP back' half cannot be done - Bedrock furnace recipes have no way to award experience.", + "mechanism": "Bottling: subscribe to world.afterEvents.playerInteractWithBlock, check block.typeId === 'minecraft:enchanting_table' and itemStack is a glass bottle, then use Player.getTotalXp / xpEarnedAtCurrentLevel and Player.addExperience with a negative amount, consume the bottle and hand back a custom item (behaviour-pack item with minecraft:icon and minecraft:max_stack_size) storing the exact XP in an ItemStack dynamic property. Refund: Bedrock's minecraft:recipe_furnace schema only accepts description, tags, input and output - there is no experience field and no scripting hook on smelting completion, so the lossless return has to move onto the item instead, via an ItemCustomComponent onUse handler calling Player.addExperience(storedAmount).", + "caveats": "The furnace interaction is the part that is lost; contributors should decide whether to refund on item use or accept vanilla minecraft:experience_bottle behaviour (thrown, random 3-11 XP, not lossless). Item custom components need Minecraft 1.21.20 or later.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/playerinteractwithblockafterevent", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/player", + "https://learn.microsoft.com/minecraft/creator/reference/content/recipereference/examples/recipedefinitions/recipe_furnace", + "https://learn.microsoft.com/minecraft/creator/documents/scripting/components-tutorial" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "afk display": { + "verdict": "partial", + "confidence": "medium", + "summary": "The floating name above an idle player can be greyed out with the Script API, but Bedrock's pause-menu player list is not scriptable, so the effect is narrower than Java's team-colour version.", + "mechanism": "Run a system.runInterval loop that stores each player's last location and rotation; after 6000 ticks without movement set player.nameTag = '\\u00a77' + player.name (Entity.nameTag is a writable string on Bedrock and section-sign colour codes apply), and restore player.nameTag = player.name on the first movement. player.isSneaking / getRotation help avoid false positives.", + "caveats": "Only the nametag rendered above the player's head changes. Bedrock exposes no API for the in-game player list or for chat name colour, so an AFK player looks normal in the pause menu - that is the main loss versus Java, which greys the tab list too. Nametag visibility also depends on nameplateRenderDistance and line of sight.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entity", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/system", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/player" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "coordinates hud": { + "verdict": "possible", + "confidence": "high", + "summary": "Straight Script API work - an interval loop writing XYZ and a formatted clock into the action bar with player.onScreenDisplay.setActionBar().", + "mechanism": "system.runInterval over world.getAllPlayers(), reading Player.location for the coordinates and world.getTimeOfDay() (documented as 0-24000 ticks) to derive a 24-hour clock, then calling player.onScreenDisplay.setActionBar() with the formatted string. If a fixed on-screen panel is preferred over the action bar, the same data can be pushed into a resource-pack hud_screen.json element instead, per the Bedrock Wiki's HUD guide.", + "caveats": "The action bar is shared with vanilla messages (item names, /title actionbar), so it will flicker if something else writes to it. Bedrock also already has a built-in showcoordinates gamerule, which covers the XYZ half without any pack.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/screendisplay", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/world", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/system", + "https://raw.githubusercontent.com/Bedrock-OSS/bedrock-wiki/refs/heads/wiki/docs/json-ui/add-hud-elements.md" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "durability ping": { + "verdict": "possible", + "confidence": "medium", + "summary": "The Script API exposes item damage and max durability on vanilla tools, so the low-durability warning is buildable; only the '/trigger duraPing' config UI needs redesigning.", + "mechanism": "Watch world.afterEvents.playerInventoryItemChange (or poll with system.runInterval over EntityEquippableComponent / EntityInventoryComponent), read ItemStack.getComponent(ItemComponentTypes.Durability) and compare damage against maxDurability - Microsoft's own ItemDurabilityComponent sample does exactly this on a vanilla diamond sword. When remaining durability drops to 10% or less, warn with player.onScreenDisplay.setActionBar() (or setTitle) plus player.playSound(). Per-player settings replace /trigger with either a scripted custom command (system.beforeEvents.startup -> customCommandRegistry.registerCommand) or a @minecraft/server-ui form, persisted with Entity.setDynamicProperty.", + "caveats": "playerInventoryItemChange needs Minecraft 1.21.100 or later; scripted custom commands need the same version. The ItemDurabilityComponent reference carries a note that the component 'only applies to data-driven items' even though its own sample uses a vanilla diamond sword, so confirm behaviour on vanilla tools in-game before committing to the event-driven version rather than polling.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/itemdurabilitycomponent", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/screendisplay", + "https://learn.microsoft.com/minecraft/creator/documents/update1.21.100", + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "nether portal coords": { + "verdict": "possible", + "confidence": "high", + "summary": "A behaviour pack with a small @minecraft/server script can compute and print the matching portal coordinates in the other dimension; everything it needs (player position, dimension id, a player-runnable command) is stable Script API.", + "mechanism": "Behaviour pack with a scripts entry in manifest.json. Register a namespaced slash command through `system.beforeEvents.startup` → `StartupEvent.customCommandRegistry.registerCommand()` with `CustomCommandPermissionLevel.Any` so non-operators can run it. In the callback read `player.location` and `player.dimension.id` ('minecraft:overworld' / 'minecraft:nether'), apply the 1:8 ratio, and report with `player.sendMessage()` or `player.onScreenDisplay.setActionBar()`. Defer any world-state work with `system.run()` because the command callback runs in a before/read-only context.", + "caveats": "Custom slash commands require Bedrock 1.21.100 with `@minecraft/server` 2.1.0 and `min_engine_version` [1,21,100]; commands must be namespaced (e.g. `/bt:portalcoords`, not `/portalcoords`), and there is a hard limit of 8 command parameters. On older versions the same script can be triggered from a custom item plus an `@minecraft/server-ui` ActionFormData menu instead.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/customcommandregistry?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.21.100?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/screendisplay?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/scripting/custom-commands" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "real time clock": { + "verdict": "possible", + "confidence": "high", + "summary": "Bedrock exposes both halves of this — a tick-driven interval to accumulate elapsed time and a persisted world value to survive reloads — so a behaviour pack can reproduce it directly.", + "mechanism": "Behaviour pack script: `system.runInterval(callback, 20)` (or read `system.currentTick`) increments a counter, which is persisted with `world.setDynamicProperty('bt:worldRuntimeTicks', n)` and read back with `world.getDynamicProperty()` on load, so the total survives world reloads. Convert to minutes/hours and surface it with `player.onScreenDisplay.setActionBar()` or `player.sendMessage()`, triggered by a namespaced custom command registered via `CustomCommandRegistry.registerCommand()`.", + "caveats": "Measures elapsed game ticks, not wall-clock time, so it drifts under server lag and stops while the world is closed — the same limitation the Java datapack has. Dynamic properties are per-behaviour-pack and are cleared by `world.clearDynamicProperties()`. The `/`-command trigger needs 1.21.100 / `@minecraft/server` 2.1.0.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/system?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/scripting/system-run-guide?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/world?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.20.50?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "spawning spheres": { + "verdict": "partial", + "confidence": "medium", + "summary": "The sphere visualisation is buildable with a custom particle plus a script loop, but Bedrock has no `glowing` status effect and its mob-spawn/despawn geometry differs from Java, so the radii and presentation have to be re-derived rather than ported.", + "mechanism": "Resource pack: a custom particle effect JSON under `particles/` (identifier + `basic_render_parameters`, `particles_add` material for a glow look). Behaviour pack: `system.runInterval()` plots points on the sphere shell around a stored centre and calls `player.spawnParticle(id, pos)` (per-player) or `dimension.spawnParticle()`, with `MolangVariableMap.setColorRGBA()` to colour shells differently. Spawn-eligibility shading can use `Block.getLightLevel()` / `Dimension.getLightLevel()` / `getSkyLightLevel()`. Centre point stored in `world.setDynamicProperty()`, toggled by a namespaced custom command.", + "caveats": "Bedrock's `/effect` enum has no `glowing` value, so there is no through-walls outline — the shell must be drawn with particles and is occluded by blocks. Light-level APIs require 1.21.120. Bedrock's mob spawning and despawn rules are not Java's (simulation-distance driven), so the 24/128-block shells the Java pack draws are the wrong numbers on Bedrock and the pack needs its own spawn-rule research before it is useful for farm proofing. Drawing a dense sphere every tick is a real performance cost on consoles/mobile; use `system.runJob()` or a low interval.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/reference/content/particlesreference/particlesintroduction?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/particleeffects?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/dimension?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.21.120?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/commands/commands/effect?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "track raw statistics": { + "verdict": "partial", + "confidence": "high", + "summary": "Bedrock scoreboards only accept the `dummy` criteria — there is no equivalent of Java's `minecraft.custom:*` / `minecraft.mined:*` stat-backed objectives — so every one of the 100+ statistics would have to be hand-tracked from Script API events, and several have no Bedrock hook at all.", + "mechanism": "Bedrock's `/scoreboard objectives add dummy [displayName]` syntax hardcodes `dummy` as the only criteria, and the Objective Criteria reference lists `dummy` as the sole value; Java's statistic criteria simply do not exist. A port would create dummy objectives via `world.scoreboard.addObjective()` and increment them from `@minecraft/server` events: `world.afterEvents.playerBreakBlock`, `playerPlaceBlock`, `entityDie` (with `damageSource`), `entityHurt`, `entityItemPickup`, `itemUse`, `playerInteractWithBlock`, `playerInventoryItemChange`, plus per-tick sampling in `system.runInterval()` for anything positional. Persist totals in scoreboards and/or `player.setDynamicProperty()`.", + "caveats": "Expect meaningful loss of coverage: statistics with no Bedrock event or query (jumps, times a specific container was opened, per-item crafting counts, time-since-last-death style counters) cannot be tracked faithfully, and every stat is a separate hand-written listener rather than a one-line objective. Per-tick sampling for 100+ counters across all players is a real performance concern on console/mobile. Existing Java worlds' stat history cannot be imported.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/commands/commands/scoreboard?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/commandsreference/examples/commandtypes/type_objectivecriteria?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/scoreboardintroduction?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/worldafterevents?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "track statistics": { + "verdict": "partial", + "confidence": "high", + "summary": "Derived stats like km swum and km flown can be computed on Bedrock, but only by sampling player state every tick and accumulating it yourself — Bedrock has no vanilla statistics system for the pack to post-process.", + "mechanism": "Behaviour pack script running `system.runInterval(fn, 1)` over `world.getAllPlayers()`, computing the delta of `player.location` each tick and bucketing it by movement state: `Entity.isSwimming`, `Entity.isInWater`, `Entity.isSprinting`, `Entity.isClimbing`, `Entity.isOnGround`, `Entity.isFalling`, `Player.isGliding`, `Player.isFlying`. Accumulate into `player.setDynamicProperty()` (or dummy objectives via `world.scoreboard.addObjective()`), then divide to km and display with `player.onScreenDisplay.setActionBar()` or a `@minecraft/server-ui` form.", + "caveats": "Bedrock exposes no statistics store to derive from — the Molang `query.walk_distance` and `query.modified_distance_moved` queries are Molang-only and `modified_distance_moved` resets when the entity is unloaded, so they are not a substitute. Accuracy depends on tick sampling, so teleports and lag spikes must be filtered out. Because tracking only runs while the script is loaded, totals start from zero on install.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entity?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/player?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.20.40?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/molangreference/examples/molangconcepts/queryfunctions/query_modified_distance_moved?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/commandsreference/examples/commandtypes/type_objectivecriteria?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "villager death messages": { + "verdict": "possible", + "confidence": "high", + "summary": "A behaviour pack can reproduce this almost exactly — `world.afterEvents.entityDie` gives the dead villager, its coordinates, its dimension and its killer.", + "mechanism": "Behaviour pack script subscribing to `world.afterEvents.entityDie`. In the handler check `event.deadEntity.typeId === 'minecraft:villager_v2'` (also `'minecraft:villager'` for the legacy type), read `deadEntity.location` and `deadEntity.dimension.id`, inspect `event.damageSource.cause` / `damagingEntity` for the killer, and broadcast with `world.sendMessage()` using a `RawMessage` so the text localises.", + "caveats": "Fires only for villagers in ticking/loaded chunks, the same as the Java datapack. Bedrock uses `minecraft:villager_v2` for modern villagers; `minecraft:villager` still exists as a legacy entity and should be matched too. Message spam control (an on/off toggle) needs its own dynamic property since Bedrock has no `/function :config` equivalent — use an `@minecraft/server-ui` form or a custom command.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entitydieafterevent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/worldafterevents?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/world?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/vanillalistingsreference/entities?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "villager workstation highlights": { + "verdict": "partial", + "confidence": "medium", + "summary": "Bedrock exposes no way to read which block a specific villager has actually claimed as its job site, and has no glowing outline effect — so the best a port can do is guess the nearest matching workstation for the villager's profession and mark it with particles.", + "mechanism": "What is missing: the complete `EntityComponentTypes` enum (the set of components readable via `Entity.getComponent`) contains no job-site, POI or `minecraft:behavior.work` accessor, so the villager→workstation link that the Java datapack reads out of `Brain.memories.\"minecraft:job_site\"` has no Script API equivalent. The `/effect` enum likewise has no `glowing` value, so Java's through-walls outline is unavailable. What can be built: read the villager's profession from the `minecraft:variant` (or `minecraft:skin_id`) component, then scan a `BlockVolume` around it with `Dimension.getBlocks()` / `containsBlock()` for the matching workstation block type and mark the nearest hit with a custom particle from the resource pack's `particles/` folder via `player.spawnParticle()`.", + "caveats": "The result is an approximation, not the claimed job site — it will pick the wrong block where several villagers share a cluster of workstations, and it cannot tell an unemployed villager's 'no job site' from 'job site out of scan range'. Highlight is particle-based and occluded by blocks rather than an X-ray outline. Scanning block volumes per villager is expensive; throttle it to an explicit player request.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entitycomponenttypes?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/commands/commands/effect?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/dimension?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/entities/village-mechanic", + "https://learn.microsoft.com/minecraft/creator/reference/content/particlesreference/particlesintroduction?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "wandering trader announcements": { + "verdict": "possible", + "confidence": "high", + "summary": "Straightforward behaviour pack port — `world.afterEvents.entitySpawn` fires with both the entity and its spawn cause, which is exactly what is needed to announce a trader arrival to nearby players.", + "mechanism": "Behaviour pack script subscribing to `world.afterEvents.entitySpawn`. Check `event.entity.typeId === 'minecraft:wandering_trader'` and `event.cause === EntityInitializationCause.Spawned` (so loading a chunk containing an existing trader does not re-announce). Then find nearby players with `dimension.getPlayers({ location, maxDistance })` and message each with `player.sendMessage()`, or use `player.onScreenDisplay.setActionBar()`.", + "caveats": "Filter on `EntityInitializationCause` or the announcement will also fire for `Loaded` and for the trader's llamas (`Event` cause). Only fires in ticking chunks. The Java pack's `/function :config` toggle has no direct equivalent — expose settings through an `@minecraft/server-ui` form or a namespaced custom command (1.21.100+).", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entityspawnafterevent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entityinitializationcause?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/dimension?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/vanillalistingsreference/entities?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "back": { + "verdict": "possible", + "confidence": "high", + "summary": "Fully buildable as a behaviour pack on 1.21.100+: a namespaced custom command, a per-player dynamic property holding the previous location, and a cross-dimension teleport.", + "mechanism": "Behaviour pack script. Register `/:back` via `system.beforeEvents.startup` → `StartupEvent.customCommandRegistry.registerCommand()` with `CustomCommandPermissionLevel.Any`. Before any teleport performed by this add-on (homes/spawn/tpa), stash the origin with `player.setDynamicProperty('bt:back', JSON.stringify({x,y,z,dim}))`; hook `world.afterEvents.entityDie` filtered to players to stash the death location as well. The command callback runs in a read-only context, so wrap the teleport in `system.run(() => player.teleport(loc, { dimension: world.getDimension(dim) }))` — `TeleportOptions.dimension` supports cross-dimension moves, and `tryTeleport()` returns false rather than throwing when the destination is blocked or unloaded.", + "caveats": "Requires Bedrock 1.21.100 / `@minecraft/server` 2.1.0 and `min_engine_version` [1,21,100]; the command must be namespaced, so it is `/bt:back`, not Java's `/trigger back`. Java's `/function back:config` maps to an `@minecraft/server-ui` settings form or a second custom command. Dynamic properties hold `boolean | number | string | Vector3`, so a location plus dimension must be JSON-stringified into one string property.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/customcommandregistry?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/teleportoptions?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entity?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entitydieafterevent?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/scripting/custom-commands" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "homes": { + "verdict": "possible", + "confidence": "high", + "summary": "Fully buildable as a behaviour pack on 1.21.100+: named homes persist in per-player dynamic properties and are set/recalled through namespaced custom commands or a server-UI form.", + "mechanism": "Behaviour pack script. Register `/:sethome` and `/:home` (with a `CustomCommandParamType.String` name parameter) via `StartupEvent.customCommandRegistry.registerCommand()` at `CustomCommandPermissionLevel.Any`. Store the home table as JSON in `player.setDynamicProperty('bt:homes', ...)`, checking size against `player.getDynamicPropertyTotalByteCount()`. Recall with `system.run(() => player.teleport(loc, { dimension: world.getDimension(dim) }))` — the command callback is read-only, so the teleport must be deferred. `@minecraft/server-ui` `ActionFormData` / `ModalFormData` gives a home-picker and a config screen in place of Java's `/function homes:config`.", + "caveats": "Requires Bedrock 1.21.100 / `@minecraft/server` 2.1.0; commands are namespaced (`/bt:home`), not bare `/trigger home`. Command parameters are limited to 8 and their shapes cannot be redefined on script reload, so use a free-text String parameter rather than `registerEnum()` for home names — enums are registered once at startup and cannot vary per player. Dynamic property storage is byte-capped, so cap home count and name length.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/customcommandregistry?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/customcommanderrorreason?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entity?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/teleportoptions?view=minecraft-bedrock-stable", + "https://wiki.bedrock.dev/scripting/custom-commands" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "spawn": { + "verdict": "possible", + "confidence": "high", + "summary": "A Script API add-on can register a player-usable `/spawn`-style command that teleports the caller to the world spawn; Bedrock exposes both the command hook and the spawn location.", + "mechanism": "Behaviour pack with a `scripts/` module against `@minecraft/server`. Register the command in `system.beforeEvents.startup` via `init.customCommandRegistry.registerCommand({ name: \"vt:spawn\", permissionLevel: CustomCommandPermissionLevel.Any })`, then in the callback defer with `system.run(...)` and call `player.teleport(world.getDefaultSpawnLocation(), { dimension: world.getDimension(\"overworld\") })`. `getDefaultSpawnLocation()` returns Y = 32767 when the world spawn height is not fixed, so resolve the landing Y with `dimension.getTopmostBlock({ x, z })` before teleporting. Vanilla Tweaks' `/function spawn:config` options (cooldown, warmup, cross-dimension toggle) map onto world dynamic properties plus `system.runTimeout`.", + "caveats": "Version floor Bedrock 1.21.100 (@minecraft/server 2.1.0) — that is the release where Custom Commands shipped stable. Custom command names must be namespaced, so it is `/vt:spawn`, not `/spawn`, and there is no `/trigger` equivalent on Bedrock. On earlier versions the only script entry point is `/scriptevent`, which requires cheats and Game Directors permission, so ordinary players could not use it.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.21.100?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/world?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/teleportoptions?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/commands/commands/scriptevent?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "tpa": { + "verdict": "possible", + "confidence": "high", + "summary": "A Script API add-on can implement the full request/accept teleport flow, and Bedrock's player-selector command parameter makes the Java PID workaround unnecessary.", + "mechanism": "Behaviour pack with `@minecraft/server` scripts. Register `vt:tpa`, `vt:tpaccept` and `vt:tpdeny` in `system.beforeEvents.startup` through `customCommandRegistry.registerCommand` at `CustomCommandPermissionLevel.Any`, giving `vt:tpa` a mandatory `CustomCommandParamType.PlayerSelector` parameter — the callback receives a `Player[]`, so the requester types the target's name directly instead of a numeric PID. Hold pending requests in a module-level `Map` (or `world.setDynamicProperty`) keyed by player id, expire them with `system.runTimeout`, notify the target with `player.sendMessage()` and/or an `@minecraft/server-ui` `ActionFormData`/`MessageFormData` accept-deny prompt, and complete with `requester.teleport(target.location, { dimension: target.dimension })`.", + "caveats": "Version floor Bedrock 1.21.100 (@minecraft/server 2.1.0) for Custom Commands. Names are namespaced (`/vt:tpa`), unlike Java's `/trigger tpa set `. Bedrock has no `/trigger` and no tab-list PID column, so the PID mechanic should be dropped rather than emulated; a form-based player picker is the friendlier route for touch and console players.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/customcommandregistry?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server-ui/actionformdata?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/teleportoptions?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/documents/update1.21.100?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "kill empty boats": { + "verdict": "possible", + "confidence": "high", + "summary": "A Script API add-on can list boats and check their passengers, so an operator-only command that removes riderless boats is straightforward.", + "mechanism": "Behaviour pack with `@minecraft/server` scripts. Register an admin command (`customCommandRegistry.registerCommand` at `CustomCommandPermissionLevel.Admin` or `GameDirectors`), then for each dimension call `dimension.getEntities({ type: \"minecraft:boat\" })` and `{ type: \"minecraft:chest_boat\" }` (`EntityQueryOptions.type`), read `entity.getComponent(\"minecraft:rideable\").getRiders()`, and call `entity.remove()` where the array is empty. `bedrock-samples` confirms `minecraft:boat` (seat_count 2) and `minecraft:chest_boat` both carry `minecraft:rideable`, and there is no separate raft entity file, so bamboo rafts are covered by the `minecraft:boat` query.", + "caveats": "Version floor Bedrock 1.21.100 for Custom Commands; on older versions the same script can be driven by `/scriptevent`, which is operator-only anyway and therefore fine for an admin tool. Entity queries only reach entities in loaded/ticking chunks, so boats in unloaded chunks survive the sweep. Consider also skipping boats that contain items (chest boats) to avoid destroying storage.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entityrideablecomponent?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/entityqueryoptions?view=minecraft-bedrock-stable", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/entities/boat.json", + "https://learn.microsoft.com/minecraft/creator/documents/scripting/custom-commands?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/commands/commands/scriptevent?view=minecraft-bedrock-stable" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + } + }, + "crafting_tweaks": { + "craftable bundles rabbit hide": { + "verdict": "possible", + "confidence": "high", + "summary": "A behaviour pack can add a Rabbit Hide bundle recipe with `minecraft:recipe_shaped`, but note that Bedrock has shipped a craftable bundle (String + Leather) since 1.21.40, so this pack is a recipe preference rather than a missing feature.", + "mechanism": "Behaviour pack file under `behavior_packs//recipes/`, e.g. `{ \"format_version\": \"1.21.30\", \"minecraft:recipe_shaped\": { \"description\": { \"identifier\": \"vt:bundle_from_rabbit_hide\" }, \"tags\": [\"crafting_table\"], \"pattern\": [...], \"key\": { \"X\": { \"item\": \"minecraft:string\" }, \"#\": { \"item\": \"minecraft:rabbit_hide\" } }, \"result\": { \"item\": \"minecraft:bundle\" }, \"priority\": 0 }`. `minecraft:rabbit_hide` exists on Bedrock (it is the first entry in vanilla `loot_tables/entities/rabbit.json`), `minecraft:bundle` exists, and the shaped-recipe schema supports up to a 3x3 `pattern`/`key`, `tags`, `priority` and `unlock`, which is everything the Java recipe needs.", + "caveats": "This must ship as a behaviour pack applied per world, not as a global resource pack, so it cannot be enabled from the global Bedrock resource-pack list the way texture tweaks are. Vanilla Bedrock already unlocks Bundle from String + Leather (see `behavior_pack/recipes/bundle.json`), so adding this recipe makes bundles cheaper rather than newly obtainable; the vanilla recipe stays active unless it is also overridden by an identically-identified recipe.", + "sources": [ + "https://learn.microsoft.com/minecraft/creator/reference/content/recipereference/examples/recipedefinitions/minecraftrecipe_shaped?view=minecraft-bedrock-stable", + "https://learn.microsoft.com/minecraft/creator/reference/content/recipereference/examples/recipedefinitionlist?view=minecraft-bedrock-stable", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/recipes/bundle.json", + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/loot_tables/entities/rabbit.json", + "https://minecraft.wiki/w/Bundle" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + }, + "craftable bundles leather": { + "verdict": "possible", + "confidence": "high", + "summary": "Already vanilla on Bedrock — `behavior_pack/recipes/bundle.json` ships exactly this recipe (String above Leather) and bundles have been craftable in Bedrock survival since 1.21.40, so a port would add nothing.", + "mechanism": "Nothing to build: the shipped vanilla recipe is `minecraft:recipe_shaped` with pattern `[\"X\",\"#\"]`, `X = minecraft:string`, `# = minecraft:leather`, result `minecraft:bundle`, tagged `crafting_table`. If the maintainer still wants a pack (for example to change the yield or the crafting-book unlock conditions), it is a single file under `behavior_packs//recipes/` using the same `minecraft:recipe_shaped` schema.", + "caveats": "Recommend closing this as unnecessary rather than porting it. If it is kept, remember behaviour-pack recipes apply per world, not globally, and a second recipe producing the same result coexists with the vanilla one unless it reuses the vanilla identifier.", + "sources": [ + "https://raw.githubusercontent.com/Mojang/bedrock-samples/main/behavior_pack/recipes/bundle.json", + "https://learn.microsoft.com/minecraft/creator/reference/content/recipereference/examples/recipedefinitions/minecraftrecipe_shaped?view=minecraft-bedrock-stable", + "https://minecraft.wiki/w/Bundle" + ], + "checkedAt": "2026-07-25", + "checkedBy": "agent" + } + } } diff --git a/tools/vt-diff/ignore.json b/tools/vt-diff/ignore.json index d14d503a6..694fcde11 100644 --- a/tools/vt-diff/ignore.json +++ b/tools/vt-diff/ignore.json @@ -28,7 +28,35 @@ "OldAlexSteve": "Closed as not planned in BedrockTweaks/Files#56", "HardcoreDarkness": "Closed as not planned in BedrockTweaks/Files#57", "SpinningBurningSkullPainting": "Closed as not planned in BedrockTweaks/Files#58", - "DungeonsAlexSteve": "Closed as not planned in BedrockTweaks/Files#161" + "DungeonsAlexSteve": "Closed as not planned in BedrockTweaks/Files#161", + "ColoredInvGray": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsGray": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvBlack": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsBlack": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvBrown": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsBrown": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvRed": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsRed": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvOrange": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsOrange": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvYellow": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsYellow": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvLime": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsLime": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvGreen": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsGreen": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvCyan": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsCyan": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvLightBlue": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsLightBlue": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvBlue": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsBlue": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvPurple": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsPurple": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvMagenta": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsMagenta": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "ColoredInvPink": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", + "ColoredWidgetsPink": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked." }, "addons": { "player head drops": "Closed as not planned in BedrockTweaks/Files#442", From 56492f0d864270239643f03ff0163cc430e8e97d Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sat, 25 Jul 2026 10:33:45 +0200 Subject: [PATCH 4/7] feat(vt-diff): Enhance issue tracking for grouped color variants and improve feasibility reporting --- tools/vt-diff/AGENTS.md | 8 +- tools/vt-diff/README.md | 33 +++++ tools/vt-diff/config.json | 28 +++- tools/vt-diff/ignore.json | 3 +- tools/vt-diff/issues.mjs | 289 ++++++++++++++++++++++++++++++++++++-- 5 files changed, 347 insertions(+), 14 deletions(-) diff --git a/tools/vt-diff/AGENTS.md b/tools/vt-diff/AGENTS.md index 9f11a6332..d529ea268 100644 --- a/tools/vt-diff/AGENTS.md +++ b/tools/vt-diff/AGENTS.md @@ -261,8 +261,14 @@ Read `out/issue-plan.md`, then verify before presenting it: shipped pack. The filters in `config.json` (`closeRequiresLabels`, `closeExcludesLabels`) already exclude bugs; verify the survivors anyway. 4. **`create`** — check the generated titles match the repo convention, `[Category > Sub] Pack Name`. -5. **Feasibility coverage** — the plan prints how many planned packs still have no verdict. Applying + A Vanilla Tweaks category whose own name contains brackets will produce a nested-bracket title; + that is a signal the category needs a group or an `ignore.json` entry, not a title patch. +5. **`groupConflicts`** — a pack collapsed into a grouped issue that already has its own open issue. + Non-empty means something would be tracked twice. Either fold the existing issue into the group + and close it, or drop the group from `config.json`. Never apply with this bucket populated. +6. **Feasibility coverage** — the plan prints how many planned packs still have no verdict. Applying with a large unresearched count publishes issues that say "not researched yet". Say so plainly. + Coverage counts packs, not issues, so a grouped family cannot flatter the number. Then stop. Present counts, the verified `reopenCandidates`, and anything that looks wrong. Ask the developer to approve. Do not apply. diff --git a/tools/vt-diff/README.md b/tools/vt-diff/README.md index 65724e85a..4294746ff 100644 --- a/tools/vt-diff/README.md +++ b/tools/vt-diff/README.md @@ -108,6 +108,39 @@ packs still get a documented issue explaining why. | `skipped` | Not created, because its verdict is in `skipCreateVerdicts` | | `reopenCandidates` | **Report only** — closed as completed, yet still absent from `packs.json` | | `rejected` | **Report only** — closed as not planned; feed into `ignore.json` | +| `groupConflicts` | **Report only** — a grouped pack that also has its own open issue | + +## Grouped colour families + +Some Vanilla Tweaks categories ship the same pack once per colour. One issue per colour is noise, so +`issues.groups` in `config.json` collapses a whole category into a single issue carrying a checklist +of members — ticked once each one ships. + +```json +{ + "id": "gui/tooltips", + "section": "resource_packs", + "category": "gui/tooltips", + "title": "[GUI > Tooltips] Colored Tooltips", + "note": "Shown above the checklist, explaining why the family is one issue.", + "groupSummary": "Optional. Replaces the sampled per-pack summary, which names its own colour." +} +``` + +`category` is the slugged Vanilla Tweaks category trail — matched against `targetCategory` on missing +packs and `vanillaCategory` on matched ones, so shipped members appear ticked rather than vanishing. + +Group only families where every member is the same pack in a different palette: same verdict, same +mechanism. Packs that merely share a *root cause* — the 3D block remodels, the Parity no-ops — still +get one issue each, because each names different work. Grouping is deliberate config, never inferred: +a "these look similar" heuristic misfires exactly where it costs most. + +A group closes only when every member has shipped. Feasibility coverage is counted in packs, not +issues, so grouping never inflates it. + +**Add a group before `--apply`, not after.** Once per-colour issues exist, grouping means closing and +reopening them; `groupConflicts` reports any member that already has its own issue rather than +silently opening a duplicate. Managed issue bodies carry a block delimited by `` and `` containing a `` marker. The marker is what makes reruns idempotent — diff --git a/tools/vt-diff/config.json b/tools/vt-diff/config.json index e68393caa..e6259238b 100644 --- a/tools/vt-diff/config.json +++ b/tools/vt-diff/config.json @@ -38,7 +38,33 @@ "closeRequiresLabels": ["enhancement"], "closeExcludesLabels": ["bug", "not_possible"], "markerStart": "", - "markerEnd": "" + "markerEnd": "", + "$groupsComment": "Colour-variant families tracked as one issue instead of one per colour. `category` is the slugged Vanilla Tweaks category trail, matched against `targetCategory` on missing packs and `vanillaCategory` on matched ones. Group only families where every member is the same pack in a different palette — same verdict, same mechanism. Packs that merely share a root cause (3D block remodels, Parity no-ops) still get one issue each, because each names different work.", + "groups": [ + { + "id": "world_of_color/block_outlines", + "section": "resource_packs", + "category": "world_of_color/block_outlines", + "title": "[World of Color > Block Outlines] Colored Block Outlines", + "note": "Vanilla Tweaks ships one pack per colour. They are one implementation with a different palette, so they are tracked here as a single issue." + }, + { + "id": "world_of_color/enchantment_glints", + "section": "resource_packs", + "category": "world_of_color/enchantment_glints", + "title": "[World of Color > Enchantment Glints] Colored Enchantment Glints", + "note": "Vanilla Tweaks ships one pack per colour. They are one implementation with a different palette, so they are tracked here as a single issue.", + "groupSummary": "Recolouring the enchantment glint is a two-texture swap on Bedrock, using the exact method this repo already ships for the red, orange, yellow, blue and rainbow glints." + }, + { + "id": "gui/tooltips", + "section": "resource_packs", + "category": "gui/tooltips", + "title": "[GUI > Tooltips] Colored Tooltips", + "note": "Vanilla Tweaks ships one pack per colour. They are one implementation with a different palette, so they are tracked here as a single issue.", + "groupSummary": "Straightforward port — Bedrock draws the item hover tooltip from the single nine-sliced texture `textures/ui/purpleBorder.png`, which a resource pack can replace with a recoloured frame." + } + ] }, "suggestionMaxDistance": 4, "feasibility": { diff --git a/tools/vt-diff/ignore.json b/tools/vt-diff/ignore.json index 694fcde11..69e778b10 100644 --- a/tools/vt-diff/ignore.json +++ b/tools/vt-diff/ignore.json @@ -56,7 +56,8 @@ "ColoredInvMagenta": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", "ColoredWidgetsMagenta": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", "ColoredInvPink": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", - "ColoredWidgetsPink": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked." + "ColoredWidgetsPink": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", + "BlueWidgetsHighlight": "Bedrock's UI is different by default — we are not porting widget packs. The highlighted-button outline is a menu widget, same rationale as the ColoredWidgets family." }, "addons": { "player head drops": "Closed as not planned in BedrockTweaks/Files#442", diff --git a/tools/vt-diff/issues.mjs b/tools/vt-diff/issues.mjs index a30db6584..5ad1ace02 100644 --- a/tools/vt-diff/issues.mjs +++ b/tools/vt-diff/issues.mjs @@ -68,6 +68,18 @@ if (apply && !authenticated) */ const run = (args) => execFileSync(gh, args, { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 }); +/** + * Reports whether a gh failure is GitHub refusing the write rather than the call being malformed. + * + * Retrying a malformed call as a comment would post nonsense, so only genuine permission and + * lock failures fall back. + * + * @param {any} error - The error thrown by `run`. + * @returns {boolean} True when the write was refused. + */ +const isPermissionFailure = (error) => /403|404|not authorized|must have admin|permission|read-only|locked|HTTP 401/i + .test(`${error?.stderr ?? ''}${error?.stdout ?? ''}${error?.message ?? ''}`); + /** * Reads every issue, preferring gh and falling back to the public REST API for dry runs. * @@ -131,6 +143,110 @@ const parseTitle = (title) => { */ const packMarker = (section, pack) => ``; +/** + * Builds the marker for a grouped colour-variant family. + * + * Groups carry one marker for the whole family rather than one per member, so the regex in the + * issue scan resolves a group issue to its group id and never to a member pack. + * + * @param {any} section - A section entry from `config.json`. + * @param {any} group - A group entry from `config.issues.groups`. + * @returns {string} The marker comment. + */ +const groupMarker = (section, group) => ``; + +/** + * Resolves the group a pack belongs to, if any. + * + * @param {any} section - A section entry from `config.json`. + * @param {any} pack - A missing Vanilla Tweaks pack. + * @returns {any | undefined} The matching group entry. + */ +const groupFor = (section, pack) => (config.issues.groups ?? []).find( + (group) => group.section === section.id && group.category === pack.targetCategory, +); + +/** + * Renders the managed block for a grouped family: one checklist plus one shared verdict. + * + * Shipped members are ticked, so the issue doubles as a progress tracker for the family. + * + * @param {any} section - A section entry from `config.json`. + * @param {any} group - A group entry from `config.issues.groups`. + * @param {any[]} missing - Member packs still absent from packs.json. + * @param {any[]} shipped - Member packs already matched. + * @returns {string} The block, including its markers. + */ +const renderGroupBlock = (section, group, missing, shipped) => { + const sample = missing[0]; + const verdict = verdictFor(section.id, sample.name); + const verdicts = [...new Set(missing.map((pack) => verdictFor(section.id, pack.name)?.verdict ?? 'unknown'))]; + + const lines = [ + config.issues.markerStart, + '### Vanilla Tweaks reference', + '', + '| | |', + '| --- | --- |', + `| Family | **${missing.length + shipped.length} packs** in one issue |`, + `| Section | ${section.name} |`, + `| Vanilla Tweaks category | ${sample.categoryPath.join(' > ')} |`, + `| Bedrock Tweaks category | \`${sample.targetCategory}\`${sample.targetCategoryExists ? '' : ' — **does not exist yet**'} |`, + `| Picker | ${sample.picker} |`, + `| Version | \`${config.vanillaTweaks.version}\` |`, + '', + `> ${group.note}`, + '', + `### Packs (${shipped.length}/${missing.length + shipped.length} shipped)`, + '', + ]; + + for (const pack of shipped) lines.push(`- [x] **${pack.display}** — shipped as \`${pack.bedrockId}\``); + for (const pack of missing) lines.push(`- [ ] **${pack.display}** (\`${pack.name}\`)`); + + lines.push('', `${sample.display}`); + + if (verdicts.length > 1) + lines.push('', `> [!WARNING]`, `> Members of this group do not share one verdict (\`${verdicts.join('`, `')}\`). Consider splitting it in \`config.json\`.`); + + if (verdict) { + lines.push( + '', + '### Bedrock feasibility', + '', + '| | |', + '| --- | --- |', + `| Verdict | **${verdict.verdict}** (${verdict.confidence} confidence) |`, + `| Checked | ${verdict.checkedAt} by ${verdict.checkedBy} |`, + '', + '_The whole family shares one implementation, so one verdict covers every colour._', + '', + // Recorded summaries are written per pack and name their own colour, which reads wrong on a + // family issue. `groupSummary` lets the family speak for itself without editing the research. + group.groupSummary ?? verdict.summary, + '', + `**How it would work on Bedrock.** ${verdict.mechanism}`, + ); + + if (verdict.caveats) lines.push('', `**Caveats.** ${verdict.caveats}`); + + lines.push('', '
Sources', ''); + for (const source of verdict.sources ?? []) lines.push(`- ${source}`); + lines.push('', '
'); + } else { + lines.push('', '### Bedrock feasibility', '', '_Not researched yet._'); + } + + lines.push( + '', + 'Maintained by `tools/vt-diff`. Edits inside this block are overwritten on the next run.', + groupMarker(section, group), + config.issues.markerEnd, + ); + + return lines.join('\n'); +}; + /** * Renders the managed block appended to (or refreshed inside) an issue body. * @@ -246,14 +362,92 @@ for (const issue of issues) { byName.get(key).push(issue); }; -const plan = { create: [], update: [], close: [], skipped: [], reopenCandidates: [], rejected: [], upToDate: [] }; +const plan = { create: [], update: [], close: [], skipped: [], reopenCandidates: [], rejected: [], upToDate: [], groupConflicts: [] }; for (const section of config.sections) { const entry = report.sections[section.id]; if (!entry) continue; + const groups = (config.issues.groups ?? []).filter((group) => group.section === section.id); + const grouped = new Set(); + + for (const group of groups) { + const missing = entry.missing.filter((pack) => pack.targetCategory === group.category); + + if (!missing.length) continue; + + const shipped = entry.matched.filter((match) => match.vanillaCategory === group.category); + const marker = `${section.vtKind}/group:${group.id}`; + const issue = byMarker.get(marker); + const block = renderGroupBlock(section, group, missing, shipped); + const packs = missing.map((pack) => pack.name); + const verdict = verdictFor(section.id, missing[0].name)?.verdict ?? 'unknown'; + const labels = [...new Set(missing.flatMap((pack) => labelsFor(section, pack)))]; + + // A member with its own pre-existing issue would be tracked twice. Report it instead of + // silently opening a duplicate — the maintainer decides whether to fold it in or ungroup. + for (const pack of missing) { + const own = (byName.get(norm(pack.display)) ?? byName.get(norm(pack.name)) ?? []) + .filter((candidate) => candidate.state === 'OPEN'); + + for (const candidate of own) + plan.groupConflicts.push({ + section: section.id, + group: group.id, + pack: pack.name, + display: pack.display, + number: candidate.number, + title: candidate.title, + url: candidate.url, + }); + } + + for (const pack of missing) grouped.add(pack.name); + + if (!issue) { + plan.create.push({ section: section.id, group: group.id, pack: group.id, packs, title: group.title, labels, verdict, body: block }); + continue; + } + + if (issue.state !== 'OPEN') { + plan.reopenCandidates.push({ + section: section.id, + group: group.id, + pack: group.id, + display: group.title, + number: issue.number, + title: issue.title, + url: issue.url, + stateReason: issue.stateReason ?? null, + }); + continue; + } + + const body = applyBlock(issue.body ?? '', block); + const addLabels = labels.filter((label) => !issue.labels.map((entry) => entry.name).includes(label)); + const bodyChanged = body.trim() !== (issue.body ?? '').trim(); + + if (!bodyChanged && !addLabels.length) plan.upToDate.push({ number: issue.number, title: issue.title }); + else plan.update.push({ section: section.id, group: group.id, pack: group.id, packs, number: issue.number, title: issue.title, url: issue.url, verdict, addLabels, bodyChanged, body }); + } + + // A group whose members have all shipped leaves nothing in `missing`, so it is handled here + // rather than in the loop above: close it once, when the last member lands. + for (const group of groups) { + if (entry.missing.some((pack) => pack.targetCategory === group.category)) continue; + + const issue = byMarker.get(`${section.vtKind}/group:${group.id}`); + + if (!issue || issue.state !== 'OPEN') continue; + if (!entry.matched.some((match) => match.vanillaCategory === group.category)) continue; + + plan.close.push({ section: section.id, group: group.id, number: issue.number, title: issue.title, url: issue.url, labels: issue.labels.map((label) => label.name) }); + } + for (const pack of entry.missing) { + if (grouped.has(pack.name)) continue; + const marker = `${section.vtKind}/${pack.name}`; const candidates = byMarker.has(marker) ? [byMarker.get(marker)] @@ -273,6 +467,7 @@ for (const section of config.sections) { plan.create.push({ section: section.id, pack: pack.name, + packs: [pack.name], title: `[${pack.categoryPath.join(' > ')}] ${pack.display}`, labels: labelsFor(section, pack), verdict, @@ -314,6 +509,7 @@ for (const section of config.sections) { plan.update.push({ section: section.id, pack: pack.name, + packs: [pack.name], number: issue.number, title: issue.title, url: issue.url, @@ -334,6 +530,8 @@ for (const section of config.sections) { const labels = issue.labels.map((label) => label.name); + // Group issues close only when every member has shipped, which is decided above. + if (/", "markerEnd": "", - "$groupsComment": "Colour-variant families tracked as one issue instead of one per colour. `category` is the slugged Vanilla Tweaks category trail, matched against `targetCategory` on missing packs and `vanillaCategory` on matched ones. Group only families where every member is the same pack in a different palette — same verdict, same mechanism. Packs that merely share a root cause (3D block remodels, Parity no-ops) still get one issue each, because each names different work.", + "$groupsComment": "Families tracked as one issue instead of one per pack. `category` is the slugged Vanilla Tweaks category trail, matched against `targetCategory` on missing packs and `vanillaCategory` on matched ones. Optional `issue` adopts an issue that already tracks the family by hand, instead of opening a new one. Group colour variants (one pack, many palettes) and families the repo has already decided to track as a unit.", "groups": [ + { + "id": "3d", + "section": "resource_packs", + "category": "3d", + "issue": 47, + "title": "[3D] 3D Packs", + "note": "The repo already tracks every 3D pack in one issue. Vanilla block geometry is not data-driven on Bedrock, so the whole family stands or falls on one engine limitation.", + "groupSummary": "Bedrock resource packs cannot remodel vanilla blocks — `blocks.json` exposes only textures, carried textures, sound and isotropic, and the vanilla pack ships no block geometry — so every 3D block pack in this family is blocked on the same limitation. 3D Items is the exception: held-in-hand geometry works through attachables, as this repo already ships for the Mace." + }, { "id": "world_of_color/block_outlines", "section": "resource_packs", diff --git a/tools/vt-diff/ignore.json b/tools/vt-diff/ignore.json index 69e778b10..8041503f3 100644 --- a/tools/vt-diff/ignore.json +++ b/tools/vt-diff/ignore.json @@ -57,7 +57,18 @@ "ColoredWidgetsMagenta": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", "ColoredInvPink": "Vanilla Tweaks ships this under GUI > Inventories & Containers [WIP/EXPERIMENTAL]; we do not track experimental Vanilla Tweaks packs.", "ColoredWidgetsPink": "Bedrock's UI is different by default — Java widget recolouring does not translate. Menu buttons on the screens that matter have migrated to Ore UI, which resource packs cannot modify, and the hotbar selector is already shipped separately as gui/hotbar_selector. Colored Tooltips are still wanted and remain tracked.", - "BlueWidgetsHighlight": "Bedrock's UI is different by default — we are not porting widget packs. The highlighted-button outline is a menu widget, same rationale as the ColoredWidgets family." + "BlueWidgetsHighlight": "Bedrock's UI is different by default — we are not porting widget packs. The highlighted-button outline is a menu widget, same rationale as the ColoredWidgets family.", + "BedrockPistonArms": "Inverse parity pack: it back-ports a Bedrock asset into Java, so it is already the default on Bedrock. We ship the mirror image instead. See java_boom / java_map / java_ender_dragon_ball / java_inventory_slot_highlight.", + "BedrockExplosion": "Inverse parity pack: it back-ports a Bedrock asset into Java, so it is already the default on Bedrock. We ship the mirror image instead. We ship java_boom, the same change inverted.", + "BedrockMapItem": "Inverse parity pack: it back-ports a Bedrock asset into Java, so it is already the default on Bedrock. We ship the mirror image instead. We ship java_map, the same change inverted.", + "BedrockDragonProjectile": "Inverse parity pack: it back-ports a Bedrock asset into Java, so it is already the default on Bedrock. We ship the mirror image instead. We ship java_ender_dragon_ball, the same change inverted.", + "BedrockSlotHighlight": "Inverse parity pack: it back-ports a Bedrock asset into Java, so it is already the default on Bedrock. We ship the mirror image instead. We ship java_inventory_slot_highlight, the same change inverted.", + "DirtBG": "Does not apply to Bedrock — the Java options-menu dirt background has no Bedrock counterpart worth shipping. The main-menu variant is already covered by our dirt_background pack.", + "JappaStatsIcons": "Bedrock has no statistics screen, so there are no stat icons to retexture.", + "JappaSpecIcons": "Bedrock has no spectator menu, so there are no spectator icons to retexture.", + "NoJavaEditionTitle": "Does not apply to Bedrock — there is no \"Java Edition\" subtitle to remove. We ship bedrock_edition_title, the counterpart that adds a Bedrock Edition logo.", + "PingColorIndicator": "Already native on Bedrock — the play screen selects Ping_Green/Yellow/Red at runtime via the #info_ping_texture_name binding. Nothing to port.", + "LiteralGameruleNames": "Does not apply to Bedrock — the Java gamerule menu this renames does not exist here." }, "addons": { "player head drops": "Closed as not planned in BedrockTweaks/Files#442", diff --git a/tools/vt-diff/issues.mjs b/tools/vt-diff/issues.mjs index 5ad1ace02..c08feca52 100644 --- a/tools/vt-diff/issues.mjs +++ b/tools/vt-diff/issues.mjs @@ -102,6 +102,17 @@ const loadIssues = async () => { const url = `https://api.github.com/repos/${config.repository}/issues?state=all&per_page=100&page=${page}`; const response = await fetch(url, { headers: { Accept: 'application/vnd.github+json' } }); + if (response.status === 403 || response.status === 429) { + const reset = Number(response.headers.get('x-ratelimit-reset')); + const minutes = reset ? Math.max(1, Math.ceil((reset * 1000 - Date.now()) / 60000)) : null; + + throw new Error([ + 'GitHub rejected the request: the unauthenticated API allows only 60 requests an hour.', + minutes ? `The limit resets in about ${minutes} minute(s).` : null, + 'Run `gh auth login` to lift it — authenticated runs get 5000 an hour and never hit this.', + ].filter(Boolean).join('\n ')); + } + if (!response.ok) throw new Error(`${url} responded ${response.status}`); const batch = await response.json(); @@ -379,7 +390,9 @@ for (const section of config.sections) { const shipped = entry.matched.filter((match) => match.vanillaCategory === group.category); const marker = `${section.vtKind}/group:${group.id}`; - const issue = byMarker.get(marker); + // `group.issue` adopts an issue that already tracks the family by hand. It only matters on the + // first run: once the block lands, the marker resolves it like any other managed issue. + const issue = byMarker.get(marker) ?? (group.issue ? issues.find((candidate) => candidate.number === group.issue) : undefined); const block = renderGroupBlock(section, group, missing, shipped); const packs = missing.map((pack) => pack.name); const verdict = verdictFor(section.id, missing[0].name)?.verdict ?? 'unknown'; @@ -389,7 +402,7 @@ for (const section of config.sections) { // silently opening a duplicate — the maintainer decides whether to fold it in or ungroup. for (const pack of missing) { const own = (byName.get(norm(pack.display)) ?? byName.get(norm(pack.name)) ?? []) - .filter((candidate) => candidate.state === 'OPEN'); + .filter((candidate) => candidate.state === 'OPEN' && candidate.number !== issue?.number); for (const candidate of own) plan.groupConflicts.push({ From b6ac5bfb0598756368b9302f7c1dd6d714c86ce1 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sat, 25 Jul 2026 10:40:51 +0200 Subject: [PATCH 6/7] feat(vt-diff): Add GlowierGlow entry to ignore.json for clarity on shader limitations --- tools/vt-diff/ignore.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/vt-diff/ignore.json b/tools/vt-diff/ignore.json index 8041503f3..07303d607 100644 --- a/tools/vt-diff/ignore.json +++ b/tools/vt-diff/ignore.json @@ -68,7 +68,8 @@ "JappaSpecIcons": "Bedrock has no spectator menu, so there are no spectator icons to retexture.", "NoJavaEditionTitle": "Does not apply to Bedrock — there is no \"Java Edition\" subtitle to remove. We ship bedrock_edition_title, the counterpart that adds a Bedrock Edition logo.", "PingColorIndicator": "Already native on Bedrock — the play screen selects Ping_Green/Yellow/Red at runtime via the #info_ping_texture_name binding. Nothing to port.", - "LiteralGameruleNames": "Does not apply to Bedrock — the Java gamerule menu this renames does not exist here." + "LiteralGameruleNames": "Does not apply to Bedrock — the Java gamerule menu this renames does not exist here.", + "GlowierGlow": "Closed as not planned in BedrockTweaks/Files#927. The Java pack works by editing core shaders; Bedrock resource packs expose no shader or material control point under Render Dragon." }, "addons": { "player head drops": "Closed as not planned in BedrockTweaks/Files#442", From 96c9e47589e66ef91d2087dbdf9e949de2620b32 Mon Sep 17 00:00:00 2001 From: DrAv0011 Date: Sat, 25 Jul 2026 10:43:51 +0200 Subject: [PATCH 7/7] feat(vt-diff): Clear stale files in OUT_DIR before generating new issue bodies --- tools/vt-diff/issues.mjs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/vt-diff/issues.mjs b/tools/vt-diff/issues.mjs index c08feca52..ac180698b 100644 --- a/tools/vt-diff/issues.mjs +++ b/tools/vt-diff/issues.mjs @@ -1,5 +1,5 @@ import { execFileSync } from 'node:child_process'; -import { existsSync } from 'node:fs'; +import { existsSync, rmSync } from 'node:fs'; import { join } from 'node:path'; import { OUT_DIR, TOOL_DIR, config, norm, readJson, writeJson, writeText } from './lib.mjs'; @@ -637,6 +637,10 @@ writeJson(join(OUT_DIR, 'issue-plan.json'), plan); writeText(join(OUT_DIR, 'issue-plan.md'), `${lines.join('\n')}\n`); // Written on the dry run too, so every body can be read as Markdown before anything is sent. +// Cleared first: a pack that has since been ignored or folded into a group would otherwise leave a +// stale file behind, and the directory is what a human reviews before approving the plan. +rmSync(join(OUT_DIR, 'bodies'), { recursive: true, force: true }); + for (const item of plan.create) writeText(join(OUT_DIR, 'bodies', `create-${item.section}-${norm(item.pack)}.md`), item.body); for (const item of plan.update) writeText(join(OUT_DIR, 'bodies', `update-${item.number}.md`), item.body);