Files
minecraft-aiworld/redstone-link-addon
sysadminandClaude Opus 5 db8931784e feat(redstone-link): real block textures via build-textures.py, add build.sh
The first textures were a motif floating on a flat slab. That hits the
lesson already documented on mailbox_block(): an icon-like sprite "reads
as a placeholder when applied to all 6 faces of a cube". Replaced with
machine faces whose traces run out to the edges, so they connect across
tile boundaries and a wall of them reads as continuous circuitry --
transmitter radiating out, receiver feeding in.

Generated through scripts/build-textures.py using the existing palette and
rect/px/save helpers rather than an ad-hoc script, so they regenerate with
everything else. Running the pipeline also rewrites the other five
textures, but pixel-identically -- that churn is only a newer Pillow
re-encoding, so those files are left alone.

RP header bumped to 1.0.1 (with the BP dependency to match) because clients
cache packs by uuid+version and would otherwise keep serving the old art.
The lobby world pin was updated to match; a mismatch silently drops the
pack from the stack.

Adds build.sh to package the .mcaddon, mirroring addon/build.sh. It omits
that script's `-x` exclude: these packs have no dotfiles, and dropping it
keeps the script working with the 7-Zip `zip` shim on the workstation as
well as Info-ZIP on the CI runner.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Gf1kZypRDfPL1YiWUS1LC
2026-08-28 11:40:16 +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.