Three mid-session fixes to the hemp progression mechanics:
- Trader buyback now operates on the held stack only. Earlier code
walked the entire inventory to count and consume hemp items, so
right-clicking with a stack of 64 buds while having more in other
slots traded everything. Reproduced by user holding 64, ended up
losing all stacks. Fixed: count = stack.amount, consume modifies
only the selected hotbar slot. Other stacks of the same item stay
intact.
- Chest loot handler removed the `if (stack) return` guard. It was
meant to skip placement events but blocked nearly every legitimate
chest open (players almost always hold an item). Now every fresh
chest open rolls; per-chest seeded set still prevents repeats.
Added a chat ping when seeds drop so players notice.
- Added a script-side wild hemp scatter on a 60s tick to bridge the
worldgen gap. Bedrock features only fire on FRESH chunk generation,
so legacy worlds where players have already explored never see the
feature_rule patches. Scatter picks a random online overworld
player every minute (40% chance), finds a grass surface within 32
blocks, places 2-4 mature hemp_crop in a small cluster. Runs in
parallel with the worldgen feature_rule for new chunks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three frame-count attempts (256×16 / 512×16 / 16×16) all caused the
same diagonal-line GPU corruption on the compass icon and a strip on
screen. Bedrock's recovery_compass renderer needs metadata beyond the
PNG itself — likely a flipbook_textures.json entry, an animation key
in item_texture.json, or an attachable definition — that this RP
doesn't provide. Without a verified working reference pack to copy
the structure from, every guess corrupts client GPU state.
The directional info already lives on the title-slot HUD (rotating
arrow + distance + label refreshed every 5 ticks), so the icon's
job is just "I'm a compass". Vanilla blue triangle does that fine.
RP bumped 1.0.2 → 1.0.5 across the previous failed attempts to force
client cache flush each time; now pinned at 1.0.5 with an empty
textures/ tree. The pack scaffold stays so future hub-return assets
have a place to land.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- naturalist-lite: add stub item definitions for silverlabs_nat:frog_leg,
cooked_frog_leg, snake_egg_block. Owl + snake behaviour files
reference these but they were never defined, so BDS logged "Unknown
item during Deferred ItemDescriptor resolution" on every boot. Stubs
are functional — frog_leg restores 2 hunger, cooked 4, snake egg is
a placeable nature-tab item. RP texture entries + lang strings added
for completeness; icons fall back to candy-cane until art lands.
- dynamite: drop the broken spawn_aoe_cloud component on thrown_banger
(its particle id "minecraft:explosion_manual" doesn't exist in BDS;
every replacement I tried also failed schema validation). The
random.fuse hit_sound + impact_damage still fire, the entity is
destroyed on hit — just no lingering AOE puff.
Also: add *.bak.local to .gitignore so docker-compose.yml.bak.local and
similar local backup files stop showing up in git status.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two new ways to find hemp seeds without already having any:
1. Worldgen: minecraft:scatter_feature spawns 1-3 mature
silverlabs:hemp_crop blocks on grass/dirt in plains/forest/birch/
flower_forest biomes (~14% scatter chance per chunk surface pass).
2. Chest injection: 8% chance per chest first-open to plant 1-3 seeds
in a random empty slot. Tracked per-chest via world dynamic property
(rolling cap of 500 entries) so each chest only contributes once.
Bedrock has no loot-table merge mechanism so we can't add seeds to
vanilla village chests without losing their vanilla loot — script
injection sidesteps that and stays version-independent.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces vanilla blue right-pointing-triangle with a red/white compass
needle on a lodestone face, rotating through 32 angular positions
(11.25° per frame). RP bumped 1.0.1 → 1.0.2.
Earlier 16-frame attempt caused GPU sampling beyond the texture buffer
(flashing diagonal-line corruption); Bedrock's recovery_compass_atlas
expects 32 frames at 16×16 each = 512×16 total.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Single Python utility that catches the silent failure modes responsible
for today's debug session:
--audit-only walk every BP→RP manifest dependency, flag drift
(default) dry-run pin diff per world (resolves the active world
from server.properties so we never write to a stale dir)
--apply write corrected world_behavior_packs.json /
world_resource_packs.json over SSH
--restart after --apply, restart only containers whose pins
actually changed
Reads docker-compose.yml to discover what's mounted on each service,
preserves any pin whose pack_id isn't in our managed addon set
(vanilla packs, Security_Sandbox), and never hardcodes credentials —
takes --ssh-pass or env MC_SSH_PASS.
Drop into the deploy muscle memory:
python3 scripts/sync-world-pins.py --audit-only # CI-friendly
MC_SSH_PASS=… python3 scripts/sync-world-pins.py --apply --restart
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two silent failure modes hit eight addons today:
1. BP→RP dep drift. When an RP version was bumped, dependent BPs kept
naming the old version. Bedrock loaded both packs but disconnected
the texture pipeline, so blocks rendered as map_color cubes in the
inventory. Aligned spark_pet, heyhe_pet, camping_supplies, dynamite,
home_sign, postal_service, private_chest BP deps to actual RP
versions. Bumped postal/private_chest RP versions to 1.0.1 to bust
client RP caches.
2. Missing minecraft:geometry. Bedrock 1.21+ silently fails to render
custom blocks in inventory unless geometry is declared — even for
plain full cubes, no warning logged. Added
minecraft:geometry.full_block to post_office, mailbox, and
private_chest. Same fix already applied to sun_lamp and the wild
cherry tree blocks in their respective addon commits.
Saved both failure modes to project memory so they're easy to recognise
next time someone sees "all my custom blocks show as solid coloured
cubes in the inventory".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entity definitions and projectile textures for the three throwables
(thrown_banger, thrown_bundle, thrown_dynamite). RP version bumped to
1.0.2 and BP→RP dependency aligned in lockstep.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the directional waypoint HUD off the action bar (which fights mount
saddle/jump UI for screen space) into the title/subtitle slot — large
rotating arrow + distance up top, label underneath, refreshed every 5
ticks so it stays pinned. Active waypoint now persists across container
restarts via per-player dynamic property instead of an in-memory Map.
New:
- !share command + 📤 button on the compass form: pick a waypoint, pick
a recipient, send them an Accept/Decline prompt; copies into their
list as "Label (from sender)" with capacity check.
- !nav chat fallback: list waypoints with distances, switch active
with !nav <n>, !nav off to clear.
- hub_return_transfer_RP scaffold for future asset overrides.
docker-compose: mount the new RP on jamie/lyla/mya.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New basic/improved/advanced detectors (8/16/32 block range). Aim and
right-click to ping the nearest ore on the view ray; pitch-coded sound
and action-bar text show distance and ore type. Any ore within 4 blocks
of a silverlabs:private_chest is hidden — chests act as faraday cages
so claimed bases stay private from neighbours' detectors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch sleep transitions from day_light_level (broken indoors) to
time_of_day, and fix the mood_needy particle reference from the
non-existent minecraft:large_smoke to minecraft:basic_smoke_particle.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bedrock mirrors the panel geometry across the block's local X axis
relative to the .geo.json, so the player's column needs panel_r and
the adjacent column needs panel_l for the roof seam to peak correctly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Host (Docker2, 8 GB RAM) has been seeing one Bedrock balloon and trigger
the kernel OOM-killer, which picks the next-largest RSS process and kills
that — i.e. one runaway world takes a healthy world down with it. dmesg
captured this happening to mc-lobby (cgroup 8f5bb1bc...) right after Jamie
threw a Watchdog 'Hang' from the Vehicles Pro pack.
mem_limit: 1500m / memswap_limit: 2500m on each of lobby/jamie/lyla/mya
keeps the blast radius inside the offending container — it OOMs itself
(recoverable via restart: unless-stopped) instead of nuking a sibling.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- camping: replace cube tent with A-frame slope panels (tent_panel_l/r) +
cardinal_direction permutations; vote-skip sleep that mixes
player.isSleeping bed sleepers with tent occupants and respects the
playersSleepingPercentage gamerule; new weathered-canvas texture.
- lobby: walk-through silverlabs:portal_field block (no collision,
translucent swirl, cross-plane geo) auto-placed above each portal frame;
invisible silverlabs:portal_label entity floats above each portal with
the destination world name; transfer detection now scans down through
the field to find the destination frame.
- postal: regenerate post_office and mailbox block textures so they fill
the full block face (brick + POST plaque, full red panel with slot/latch
/flag/rivets) instead of small sprites floating on transparent.
- dynamite + tow-boat: ship the addons (volumes wired into all four
worlds; enabled_packs registers them into Mya's world).
- art: build-textures.py extended; build-art-catalog.py added to project.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bedrock 1.21+ rejects minecraft:icon as a *block* component (it's an
*item* component), failing block registration with "child 'minecraft:icon'
not valid here". The post_office and mailbox blocks never registered, so
their recipes failed (silverlabs:post_office / silverlabs:mailbox missing)
and the items didn't appear in the in-game inventory despite the addon
being marked active in the world settings.
Reverts the additions made in f126eeb to those two block JSONs only;
the rest of the multi-mailbox script logic from that commit is unchanged.
Inventory icons now fall back to the material_instances texture (same
visual as before f126eeb).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Players can now place up to 5 mailboxes, each labelled like a lodestone
waypoint. Sending mail picks recipient then mailbox; redirect collapses
one of your own mailboxes into another and removes the source.
- v1 -> v2 schema migration runs once on boot; existing claims default to
label "Mailbox".
- Two-step send picker (skipped when recipient has only one mailbox).
- Post office root menu adds Redirect option.
- Per-entry break handling so removing one mailbox keeps the others claimed.
- minecraft:icon component + 16x16 inventory icons for both blocks.
- Refreshed pack_icon.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The tent's scan-down-for-ground loop still used b.isSolid (undefined
in BDS), so it always fell through the break conditions and
decremented feetY by 3 blocks before checking ground. That's why
clicking grass reported "dirt" and stone reported "dirt/stone from
underneath the surface". Replaced both solid checks with
!isAir && !isLiquid like the main ground check.
Also added a cinematic third-person camera when climbing into the
hammock (ease 0.8s out_sine), cleared on exit. Gives the player a
"lying back, can see myself" view while resting.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two live-testing regressions:
- block.isSolid is not a reliable member of the @minecraft/server Block
API in BDS 1.26 — it returned undefined, so !b.isSolid was always
true and every ground cell failed. Replaced with !b.isAir &&
!b.isLiquid (same predicate the clear-space check below already
uses), which correctly accepts grass/dirt/stone and only rejects air
or water/lava.
- The half-slab hammock geometry was silently rejected and rendered
invisible. The block-model parser wants the legacy 1.12.0 format
with simple "uv": [0, 0], not 1.21.0 with per-face UV objects.
Rewritten hammock_slab.geo.json to match the working
addon/spark_pet_RP/models/blocks/dragon_basket.geo.json format.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Hammock now uses a custom geometry.silverlabs.hammock_slab (8-voxel
tall half-slab instead of a full cube), matching its thin collision
box so the block reads visually as a hammock cradle, not a brick.
- Tent placement now projects the player's feet down to the nearest
solid block (up to 3 blocks) before picking the base Y, so mid-jump
fractional positions or standing-on-slab cases don't mis-place the
footprint one block too high.
- Failure messages now include the exact failing cell coordinates and
the block type that's in the way, so we can diagnose live pitch
attempts without guesswork.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three fixes for feedback from live testing:
1) Tent pitch check required 3 blocks of air above the footprint but
the tent is only 2 blocks tall. Relaxed clearance to match the
actual structure height (h <= 1).
2) Hammock block had a 4px-tall collision box which pushed the player
on TOP of the cloth. Reduced collision to 1px so the player stands
inside the hammock cell. Selection box stays at 4px for easy click.
3) Climbing in now actually locks the player: applies slowness 255,
weakness, mining_fatigue for the duration, saves the anchor point
in a dynamic property, and the upkeep loop re-teleports them if
they drift off. Sneak-exit nudges them ~1.2 blocks forward of the
cradle so they don't immediately re-enter.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The nested {"texture": "..."} form for minecraft:icon is rejected by the
1.21.0 item schema (BDS warned: "this member was found in the input,
but is not present in the Schema"), so tent and hammock had no inventory
icons at all. Switched to the plain-string form used by every other
addon in the repo.
While here, replaced the placeholder PNGs (a flat green triangle and a
red squiggle) with proper 16x16 pixel art:
- tent: A-frame canvas silhouette with doorway slit and ground line
- hammock: side-view sling with rope ends rising off-screen and a
sagging red-and-white striped fabric
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Original 5x2 pattern (T T / TWWWT) exceeded the vanilla crafting grid
and BDS rejected it with "Adding a recipe larger than 3x3". Replaced
with a 3x3 layout: strings on the four corners as suspension points,
wool row across the middle as the cloth.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The camping-supplies addon was added to docker-compose.yml as a bind
mount but never added to the workflow's path filter or PATHS checkout
list, so the directory on the server stayed empty and the pack was
invisible to all four worlds.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The @minecraft/server-admin beta transferPlayer API takes
(player, { hostname, port }) — passing host/port positionally raised
"incorrect arguments, expected 2 received 3" at runtime. Matches the
working call site in hub_return_transfer_BP.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Commit 81f84b5 misdiagnosed the mc-lobby crash loop and stripped the
@minecraft/server-admin@1.0.0-beta dependency, swapping in
player.transfer({hostname,port}). At runtime that throws
"player.transfer is not a function" the first time anyone steps on a
portal — the stable @minecraft/server API never exposed transfer() on
Player in BDS 1.26.14.
The real root cause of the original crash loop was unrelated: the
mc-lobby Docker volume had lost its vanilla behavior-pack collection
(vanilla_*, chemistry*, editor, server_library, …). Copying those back
from a healthy sibling volume fixed the boot crash; nothing in the
lobby_transfer pack needed to change. Restoring the beta transferPlayer
here brings lobby back in line with hub-return-addon, which has always
used this pattern successfully on jamie/lyla/mya.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bedrock 1.26 rejects the @minecraft/server-admin 1.0.0-beta dependency at
pack load, which was crashing mc-lobby on boot (exit 1 right after pack
stack + block-version logging). The transferPlayer helper has been part of
the stable @minecraft/server API as Player.transfer since 1.21, so we can
drop the server-admin import and dependency entirely.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bedrock 1.26 rejects { context } variants as "malformed unlocking context"
and [] as "empty unlocking ingredient array". The unlock field must contain
at least one ingredient item; players who have that item unlock the recipe.
Using minecraft:crafting_table as the unlock ingredient makes semantic sense
(all 26 recipes already require the crafting_table tag) and effectively means
"visible once the player has any crafting table".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Follow-up to 4324882. The { "context": "always_unlocked" } form triggered
"malformed unlocking context" on 1.26-series Bedrock (AlwaysUnlocked pascal
form fared no better). Empty-array form is the universally accepted "recipe
always known" shape. This unblocks mc-lobby which was crashing on boot.
Also reverts block format_version on mailbox.json + smart_crafting_table.json
to 1.21.0 — every other working block in the repo uses that, so the prior
1.21.60 choice was unnecessary.
- 19 dragon + portal recipes (spark_pet_BP, lobby_transfer_BP): unlock -> []
- 7 other recipes touching unlock { context: ... }: same
- 2 block files: format_version 1.21.60 -> 1.21.0
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- recipes: add unlock { context: always_unlocked } to all spark_pet and lobby_transfer recipes (1.20+ requirement) — fixes mc-lobby crash loop
- spark_dragon entity_sensor: wrap in subsensors[] and convert sensor_range → range [a,b] per 1.21 schema
- anthrax_cat interact: wrap event/filters in on_interact to match Bedrock 1.21 interact schema
- block format_version: bump mailbox and smart_crafting_table to 1.21.60
- item icons: replace { texture: X } with shorthand string form
- heyhe_egg description: replace bare category with menu_category block
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tent pitches over a 2x3 flat footprint and lets players skip to dawn
without touching their spawn point. Hammock strings between two posts
3-6 blocks apart (straight or diagonal, +/-1 block height) and keeps
hostile mobs at bay while occupied. Both are craftable (wool/sticks and
wool/string) and mounted in all four worlds.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Right-clicking the recovery compass now opens an ActionForm menu with
"Return to Hub" plus any lodestone waypoints the player has placed in
the current dimension. Placing a lodestone prompts for a label and
saves it under the waypoints_v1 world dynamic property (max 10 per
player). Selected waypoints drive an on-screen actionbar HUD with
distance and an 8-direction arrow, clearing on arrival within 3 blocks.
Lodestone breaks are ownership-gated and drop the block back.
Bumps pack to 1.0.5 and declares the @minecraft/server-ui dependency
required by the new ActionForm/Modal/MessageForm flows.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The itzg/minecraft-bedrock-server entrypoint rewrites server.properties
from env vars on every start. Any property edited via mc-manager's UI was
being clobbered because those env vars were set here. Remove them so
/data/server.properties (on the named volume) is the real source of truth:
- SERVER_NAME, GAMEMODE, DIFFICULTY, ALLOW_CHEATS, ONLINE_MODE,
MAX_PLAYERS, DEFAULT_PLAYER_PERMISSION_LEVEL
- LEVEL_SEED (jamie) — world already generated
- LEVEL_NAME — moved to docker-compose.override.yml, managed by
mc-manager so UI Set Active survives future deploys
Kept: EULA, SERVER_PORT (deploy-time wiring), OP_PERMISSION_LEVEL
(not a server.properties key).
Override file is gitignored so mc-manager's writes don't leak into git.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds an upgraded crafting block that scans the player's owned private chests
and aggregates their contents with the personal inventory when deciding which
recipes are craftable. Ingredients are consumed from the player first then
from chests; the result goes to the player (or drops at their feet).
Also redraws the post_office and mailbox block textures via a new
scripts/build-textures.py generator.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lobby portal zones and signs moved to the rebuilt portal area at
~(436..488, 65..74, -322..-281), including a second Lyla's-World
"Super Kitties" portal. Signs now use per-portal facing_direction
so they face the hub walkway correctly.
Easter-egg placeAllEggs validation now samples the far-ring eggs
(indices 45-49) before falling back to the near ring — avoids false
"blocks missing" reports when only close-ring eggs have been picked up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New silverlabs:cheeky_monkey mob that wanders the lobby watching players
and throwing harmless (knockback-only) silverlabs:banana_projectile at
them. Drops 1-2 silverlabs:banana (food) on death. Spawn rules target
jungle biomes for future deployment to survival worlds; for now the pack
is bind-mounted into the lobby service only.
Also bundles a stray docker-compose tidy from earlier local work
(Jamie's world seed pinned, pet addons dropped from Jamie).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
BDS reads pack activation from LevelDB, not world_behavior_packs.json.
The enabled_packs.json in config/default/ is the correct mechanism to
activate new packs in existing worlds. Bind-mounted so it survives
container recreates via CI/CD.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Villages now evolve organically as villager populations grow. The addon
scans every 5 minutes, clusters villagers by proximity, and places new
buildings (well, lamp post, houses, farm, blacksmith) adjacent to
existing villages as population thresholds are reached. State is
persisted across restarts via world dynamic properties.
Deploys to jamie, lyla, mya survival worlds only.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Custom item silverlabs:anthrax_cat with entity_placer — place cat by right-clicking ground
- Shaped recipe: 4 gold ingots + 1 red dye (cross pattern) at crafting table
- Recipe unlocks when player has a gold ingot
- Item appears in creative inventory under Items > Misc
- Item icon: 16x16 Maneki-neko pixel art
- Set is_spawnable: false on entity (use crafted item instead of spawn egg)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bedrock clients cache resource packs by version — unchanged version means
the client never re-downloads the updated textures/model.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- heyhe_egg: rebuild spawn mechanism with component groups (spawn_entity/die
can't live in event sequences — follow dragon_egg pattern exactly)
- heyhe_chicken: move interact to base components so taming always works
regardless of spawn method; add persistent to stop vanishing
- Geometry: skinny tall body, thin neck, proper UV coordinates throughout
- Texture: fill whole atlas white first (no dark gaps), matched UV regions,
wonky asymmetric eyes (one big+high, one small+low)
- Animation: neck peck 3x per cycle at 22deg, body sway on walk, wing flutter
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tameable white chicken modelled on Hey Hey from Moana — custom plump
geometry, waddly walk/peck animations, hatching egg item, and vanilla
chicken sounds. Mounted on all 4 servers via docker-compose.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Block state syntax ["facing_direction":N] in setblock silently failed, so no
egg blocks were placed and nothing could be collected. Revert to plain single
block setblock with no states.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rebuildTagsAndBasket was wrongly treating any missing egg block as "collected"
— but blocks were missing because setblock silently failed on unloaded chunks,
not because the player found them. This caused StinkyRoger's score to jump to
21+ when only 3 eggs had been found.
Fix: remove rebuildTagsAndBasket entirely. The block-existence check inside
collectEgg() already prevents re-collection of a gone block. Tags remain as
a per-session fast-path only; the basket is the cross-server truth.
Also allow /scriptevent eggs:cmd reseteggsworld to work without a player
source so MCP/console can trigger a world egg reset remotely.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Player tags are server-local and wiped on transfer, breaking lobby scores.
Switch to an Egg Basket (nether_star, custom nameTag "[j:N,l:N,m:N]") that
travels with the player's inventory so the lobby can always read accurate counts.
Child worlds rebuild lost tags from block-state on each player join (missing
egg block = previously collected), keeping within-world deduplication intact.
Basket is updated on every collection and after every tag rebuild.
Lobby reads basket counts directly instead of tags.
Also make eggs visually egg-shaped: 2 glazed-terracotta blocks tall with
opposing facing_direction (2 bottom, 3 top) to create an oval silhouette.
collectEgg() now clears both Y and Y+1; detection dy extended to 3.0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use joining player's position as egg centre instead of world default
spawn, so eggs appear where players actually play
- Store centre in dynamic property so all players find the same eggs
- Validate that egg blocks actually exist before trusting eggs_placed flag,
auto-recovering if setblock commands silently failed (e.g. unloaded chunks)
- Trigger placement on first playerSpawn not server startup timeout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docker restart does not re-read docker-compose.yml, so new bind mounts
added to the compose file are ignored until containers are recreated.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>