Files
minecraft-aiworld/redstone-link-addon
sysadminandClaude Opus 5 1e82825f8f fix(redstone-link): add minecraft:geometry so material_instances applies
The blocks rendered as an untextured default. Root cause: with no
minecraft:geometry component, Bedrock renders the block through the legacy
blocks.json texture path instead of material_instances. blocks.json here
only sets "sound", with no "textures", so the client substituted a default.

This produces no error in the content log -- both paths are valid, they just
resolve differently -- which is why the pack looked correct everywhere:
files installed byte-perfect, pack activated, terrain_texture.json valid,
and a clean world with only this addon still showed the wrong texture.

Adding "minecraft:geometry": "minecraft:geometry.full_block" fixes it,
verified in-game.

BP bumped to 1.0.1 so clients cannot reuse the cached copy. The lobby world
pin is updated to match; a mismatch silently drops the pack from the stack.

Note: 7 of the repo's other custom blocks have the same defect -- home_sign,
smart_crafting_table, tent_canvas, and all four lobby portal blocks. Most
blocks here DO set geometry, so those seven look like oversights rather than
intent. Not fixed in this commit; they touch every live world.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Gf1kZypRDfPL1YiWUS1LC
2026-08-28 12:22:22 +01:00
..

Redstone Link

Wireless redstone. Vanilla dust needs a solid block under it and gets cut off by terrain; this replaces the wire entirely with a transmitter/receiver pair bound by a channel name.

Block What it does
silverlabs:redstone_link_tx — Redstone Link Transmitter Reads redstone power from any of its six neighbours. While powered, its channel is live.
silverlabs:redstone_link_rx — Redstone Link Receiver While its channel is live, emits full-strength (15) power in every direction.

Craft either from a redstone block + ender pearl (+ copper for the transmitter, iron for the receiver). Both give 2.

Setting a channel: right-click a block and type a name, e.g. front-door. Every transmitter and receiver sharing that name is linked — many-to-many, any distance, through any terrain, in any direction. Newly placed blocks start on channel default.

How it works, and why

Bedrock custom blocks can read redstone power but cannot emit it — there is no script API for that. So a live receiver is physically swapped for a vanilla minecraft:redstone_block (strength 15, omnidirectional, needs no support) and swapped back when the channel goes quiet.

That swap is why scripts/registry.js exists: while a receiver is powered the block itself no longer says it is a receiver, so the positions are kept in a world dynamic property. It survives container restarts, and a reconcile pass at boot repairs anything left inconsistent by a crash.

Breaking a powered receiver is intercepted so it returns the receiver block rather than a free redstone block.

Limits

These are inherent to the approach, not bugs:

  • Both ends must be in loaded chunks. A link whose receiver sits in unloaded terrain simply does not fire. Cover it with a ticking area if it must always work.
  • ~2 tick latency. Fine for doors, lamps and farms; not for sub-tick clocks.
  • Binary, not graded. Output is always 15, never a decayed signal.
  • Same dimension only.
  • 256 nodes per world.

A transmitter ignores power coming from its own channel's receivers, so putting a matched pair side by side will not latch itself on.

Console / bridge control

Blocks placed by /setblock, /fill, or the mc-ai-bridge MCP build tools never fire playerPlaceBlock, so they are not registered and stay inert. Register them explicitly (sourceEntity is null over RCON/the bridge, so no player is needed):

/scriptevent rlink:register <x> <y> <z> <channel>
/scriptevent rlink:unregister <x> <y> <z>
/scriptevent rlink:status

rlink:status reports node counts and active channels — the quickest way to confirm the pack is alive on a headless server.

Deployment

Bind-mount both packs into the target service in docker-compose.yml, then pin the pack UUIDs into that world's world_behavior_packs.json / world_resource_packs.json. The version arrays must match the manifest header versions exactly or the pack is silently dropped from the stack.

Pack UUID Version
BP header e4f1a7c2-6b95-4d38-a7e0-3c81d5f2b001 [1, 0, 0]
RP header e4f1a7c2-6b95-4d38-a7e0-3c81d5f2b004 [1, 0, 0]

Currently deployed to lobby (Hub World) only.