Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
node_modules/
package-lock.json
.yarn/install-state.gz
tools/vt-diff/.cache
tools/vt-diff/out
68 changes: 26 additions & 42 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ If there is need to scale the template use closest neighbor instead of other sam

JSON, JS and TS files should be formatted using 1 tab with size 4 for indentation.

An addon may override this for its own JS/TS as long as its ESLint config is configured to match, so the linter and the editor agree.

### Addons (Yarn Monorepo Packages)

Addons are managed as Yarn workspace packages. To start working in addons you will need to have the following:
Expand All @@ -126,19 +128,21 @@ right of the IDE.

**Creating a new addon:**

1. Copy the template from `templates/addon/` to `addons/<category>/<addon_name>/`
2. Update `addons/<category>/package.json` to include the new addon in workspaces
3. Update `addons/<category>/<addon_name>/package.json` using the graves example as reference:
4. Update UUIDs, pack name, and descriptions in BP/RP manifest.json and config.json
5. Update module versions in config.json and package.json as needed
Addons are built on the [bedrock-core](https://bedrock-core.drav.dev/) stack. Scaffold them with the repo wrapper around its CLI:

1. Run `yarn create-addon <category> <addon_name> [--author <name>] [description...]` from the repo root (example: `yarn create-addon gameplay_changes graves When you die, a grave saves all your drops.`)
2. It scaffolds `addons/files/<category>/<addon_name>/` with creator `bt` and namespace `bt_<category_initials>_<addon_name>` (example: `bt_gc_graves`), credits you as the author (your git user.name, or `--author`) in `config.json`, the manifests and the bedrock-core addon list (`<author>, Bedrock Tweaks`), adapts the package to the monorepo (`@bedrock-tweaks/<addon_name>`, private, no addon-local yarn files) and registers it in the category workspaces
3. Run `yarn install` at the root, then build the addon from its directory
4. Add the pack entry to `addons/packs.json` with id `<addon_name>` under its category (the `bt_<category_initials>_<addon_name>` namespace is only for commands, tags and identifiers inside the addon)
5. Use the latest stable Minecraft module versions and `min_engine_version`; experimental/beta APIs are not accepted

**Development workflow:**

After installing the monorepo with `yarn install`, run `yarn regolith-install` once to set up Regolith filters and dependencies.

Then, **open each addon as a standalone VSCode instance** and run commands from that directory:

- **Watch mode** (live recompilation): `yarn run dev` (runs `regolith watch`)
- **Watch mode** (live recompilation): `yarn run watch` (runs `regolith watch`)
- **Build once**: `yarn run build` (runs `regolith run build`)
- **Lint addon**: `yarn run lint` (runs `eslint .`)

Expand All @@ -152,7 +156,7 @@ From the root directory, use these commands to manage the entire monorepo:
**Before submitting PR:**

- Lint the addon from its directory: `yarn run lint`
- Bump versions in addon `package.json` and `addons/packs.json`
- Bump the addon version in its `package.json` and BP/RP `manifest.json` (addons do not set versions in `addons/packs.json` — the version is inferred from the pack itself)
- Test the addon in-game on at least 1 device

**Monorepo structure:**
Expand All @@ -163,34 +167,11 @@ From the root directory, use these commands to manage the entire monorepo:

Regarding regolith filters, currently it is only accepted filters which run on node.

Resource Pack JSON UI modifications for addons are not accepted at this moment.

#### Technical Details

- Addons should not have functions
- Addons should not have functions, prefer custom commands
- All settings and interactions should be in-game or in server forms
- Addons should have a basic `/bt:<addon_name> config` (TBD specifics discuss in discord) base command which should open a config server form
- Addon could have extra commands for quick access if necessary for commodity (for example tpa) but prefer server forms, easier for normal users
- The code in the template is an example it could be removed and changed as long as it follows the structure
- Prefer interfaces to types.
- Prefer functional programming over object-oriented programming.
- Prefer `const` and `let` over `var`.

#### Keys to change

When making an addon from the template you should look for these keys and replace them

```md
<pack_name>
<pack_category>
<description>
<author name/username>
<bp_uuid>
<data_module_uuid>
<scripting_uuid>
<rp_uuid>
<resources_module_uuid>
```
- Addon could have extra commands for quick access if necessary for commodity (for example tpa) but prefer ui, easier for normal users

If you notice any files not following the Style Guide feel free to open a PR.

Expand Down Expand Up @@ -333,7 +314,9 @@ export interface PacksJSON {
section: Section;
// Global pack version, this will be the header.min_engine_version in the manifest.json
// example: [1, 21, 0]
version: number[];
// * Not set for Addons: the server adds it when generating, as the min of the
// minimum engine versions of all addons
version?: number[];
categories: Category[];
combinations: Combination[];
deepMergeFiles: DeepMergeFile[];
Expand Down Expand Up @@ -364,22 +347,23 @@ export interface Pack {
name: string;
description: string;
message?: Message;
version?: string; // * only Addons and CT
version?: string; // * only CT — addons do not carry a version here: it is inferred from the pack itself and added by the server, which builds the dependency tree and downloads all selected packs
priority?: number; // Higher number, higher priority
disabled?: boolean;
}

/**
* Pack Version is a string as follows: "<minecraft_version> - <pack_version>" for addons
* and just "<pack_version>" for crafting tweaks
* minecraft_version is the minimum version of the game the pack is compatible with
* Pack Version is a string as follows: "<pack_version>" for crafting tweaks
* pack_version is the version of the pack for that minecraft update, each mc update it resets
* example:
* (version update) "1.21.50 - 1.0.0"
* (bug fix) "1.21.50 - 1.0.1"
* (pack major revamp) "1.21.50 - 2.0.0"
* (pack improvements) "1.21.50 - 2.1.0"
* (version update) "1.22.0 - 1.0.0"
* (version update) "1.0.0"
* (bug fix) "1.0.1"
* (pack major revamp) "2.0.0"
* (pack improvements) "2.1.0"
*
* Addons never author versions in packs.json: each addon is its own pack, its
* version and minimum engine version come from the pack manifest, and the
* server adds pack versions and the root version when generating.
*/

export interface Combination {
Expand Down
18 changes: 18 additions & 0 deletions addons/files/gameplay_changes/graves/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.{ts,tsx,js,jsx,mjs,cjs}]
indent_style = space
indent_size = 2

[*.{json,jsonc,mcstructure}]
indent_style = tab
indent_size = 4

[*.md]
trim_trailing_whitespace = false
71 changes: 70 additions & 1 deletion addons/files/gameplay_changes/graves/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,71 @@
# Dependencies
node_modules
**/node_modules
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# Build outputs
/build
/.regolith
/.regolith
dist
**/dist
*.tsbuildinfo
**/*.tsbuildinfo

# Testing
coverage
**/coverage
.nyc_output

# Environment
.env
.env.local
.env.*.local

# IDE
.vscode/*
!.vscode/launch.json
!.vscode/settings.json
!.vscode/extensions.json
!.vscode/mcp.json
.idea
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db
desktop.ini

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

# Temporary files
*.tmp
*.temp
.cache
**/.regolith/

TODO
.claude
# Filter-generated artifacts (rebuilt by regolith)
**/*.generated.json
**/*.generated.d.ts

# Render pack (downloaded by the bedrock-core CLI, not committed)
core-ui-*.mcpack

# Minecraft schema types (regenerated by the generator filter on build)
/packs/data/generated/
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"recommendations": [
"aaron-bond.better-comments",
"blockceptionltd.blockceptionvscodeminecraftbedrockdevelopmentextension",
"dbaeumer.vscode-eslint",
"mojang-studios.minecraft-debugger",
Expand Down
8 changes: 4 additions & 4 deletions addons/files/gameplay_changes/graves/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"version": "0.3.0",
"version": "0.2.0",
"configurations": [
{
"type": "minecraft-js",
"request": "attach",
"sourceMapRoot": "${env:LOCALAPPDATA}/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/development_behavior_packs/bedrock-tweaks/graves/scripts/",
"generatedSourceRoot": "${env:LOCALAPPDATA}/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/development_behavior_packs/bedrock-tweaks/graves/scripts/",
"sourceMapRoot": "${env:APPDATA}/Minecraft Bedrock/Users/Shared/games/com.mojang/development_behavior_packs/gc_graves/scripts/",
"generatedSourceRoot": "${env:APPDATA}/Minecraft Bedrock/Users/Shared/games/com.mojang/development_behavior_packs/gc_graves/scripts/",
"localRoot": "${workspaceFolder}/packs/BP/scripts/",
"name": "Debug with Minecraft",
"mode": "listen",
"port": 19144,
"targetModuleUuid": "da5802ff-6c19-46d8-a27a-1f717580968b"
"targetModuleUuid": "8ec2e94f-b226-4d04-b966-69f89812700e"
}
]
}
22 changes: 14 additions & 8 deletions addons/files/gameplay_changes/graves/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
"source.fixAll.eslint": "explicit"
},
"editor.detectIndentation": false,
"editor.insertSpaces": false,
"editor.insertSpaces": true,
"editor.tabSize": 2,
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.insertSpaces": false,
"editor.tabSize": 4
"editor.insertSpaces": true,
"editor.tabSize": 2
},
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.insertSpaces": false,
"editor.tabSize": 4
"editor.insertSpaces": true,
"editor.tabSize": 2
Comment thread
drav0011 marked this conversation as resolved.
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features",
Expand All @@ -26,9 +26,10 @@
"editor.insertSpaces": false,
"editor.tabSize": 4
},
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"js/ts.tsdk.path": "node_modules/typescript/lib",
"js/ts.tsdk.promptToUseWorkspaceVersion": true,
"eslint.validate": [
"javascript",
"typescript",
"json",
"jsonc"
Expand All @@ -37,5 +38,10 @@
"*.json": "jsonc"
},
"eslint.enable": true,
"eslint.format.enable": true
"eslint.format.enable": true,
"eslint.workingDirectories": [
{
"mode": "auto"
}
]
}
39 changes: 39 additions & 0 deletions addons/files/gameplay_changes/graves/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Graves

When you die, a grave keeps everything — inventory, armor, offhand and XP. It
never burns, never explodes, floats on lava, and gets rescued from the void.

- **Interact** — opens the grave like a chest; it disappears once emptied.
- **Sneak + interact** — everything straight back into its original slots.
- **Hit it twice** — scatters the contents on the ground.

Only the owner can open a grave, unless grave robbing is enabled or the opener
holds a grave key (consumed on use).

Your own graves show as waypoints on the locator bar (owner only, both a
server-wide and a per-player toggle).

## Commands

| Command | Who | What |
| --- | --- | --- |
| `/bt_gc_graves:graves` | anyone | your grave list |
| `/bt_gc_graves:config` | anyone | settings |
| `/bt_gc_graves:guide` | anyone | in-game guide |
| `/bt_gc_graves:gravekey [player] [amount]` | operator | hand out grave keys |
| `/bt_gc_graves:gravesadmin <action>` | operator | panel, purge, enable/disable |

## Development

```bash
yarn run watch # live recompilation
yarn run build
yarn run lint
```

- Run a build once after cloning so the generated i18n/guides modules exist.
- Install the `core-ui-*.mcpack` in your test world to see the custom UI.
- The grave entity is unkillable by design; the only removal path is
`entity.remove()` — never `/kill`, never `runCommand('kill ...')`.
- The grave index (world dynamic properties) is the source of truth; grave
entities in unloaded chunks do not exist to `getEntities()`.
Loading