From db8931784e838f91d3fbc72517fdc0f8a35d7dd2 Mon Sep 17 00:00:00 2001 From: sysadmin Date: Fri, 28 Aug 2026 11:40:16 +0100 Subject: [PATCH] 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) Claude-Session: https://claude.ai/code/session_015Gf1kZypRDfPL1YiWUS1LC --- redstone-link-addon/build.sh | 38 ++++++++ .../redstone_link_BP/manifest.json | 30 +++++- .../redstone_link_RP/manifest.json | 2 +- .../textures/blocks/redstone_link_rx.png | Bin 586 -> 291 bytes .../textures/blocks/redstone_link_tx.png | Bin 595 -> 275 bytes scripts/build-textures.py | 87 ++++++++++++++++++ 6 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 redstone-link-addon/build.sh diff --git a/redstone-link-addon/build.sh b/redstone-link-addon/build.sh new file mode 100644 index 0000000..56830b5 --- /dev/null +++ b/redstone-link-addon/build.sh @@ -0,0 +1,38 @@ +#!/bin/bash +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BUILD_DIR="$SCRIPT_DIR/build" + +rm -rf "$BUILD_DIR" +mkdir -p "$BUILD_DIR" + +# Each pack is zipped from INSIDE its own directory so that manifest.json sits +# at the archive root. An extra nesting level makes Minecraft reject the import. + +# No -x exclude here, unlike addon/build.sh: these pack dirs contain no +# dotfiles, and dropping it keeps the script working with the 7-Zip `zip` +# shim on the Windows workstation as well as Info-ZIP on the CI runner. + +echo "Packaging Behavior Pack..." +cd "$SCRIPT_DIR/redstone_link_BP" +zip -rq "$BUILD_DIR/redstone_link_BP.mcpack" . + +echo "Packaging Resource Pack..." +cd "$SCRIPT_DIR/redstone_link_RP" +zip -rq "$BUILD_DIR/redstone_link_RP.mcpack" . + +echo "Creating .mcaddon bundle..." +cd "$BUILD_DIR" +zip -rq "$BUILD_DIR/redstone_link.mcaddon" redstone_link_BP.mcpack redstone_link_RP.mcpack + +echo "" +echo "Build complete!" +echo " Output: $BUILD_DIR/redstone_link.mcaddon" +echo "" +echo "To install:" +echo " - Double-click the .mcaddon file on Windows to auto-import" +echo " - Or copy packs to com.mojang/development_behavior_packs/ and development_resource_packs/" +echo "" +echo "Note: import BOTH packs. The behavior pack alone gives you working" +echo "logic with missing textures and untranslated block names." diff --git a/redstone-link-addon/redstone_link_BP/manifest.json b/redstone-link-addon/redstone_link_BP/manifest.json index cf8795d..3d067cc 100644 --- a/redstone-link-addon/redstone_link_BP/manifest.json +++ b/redstone-link-addon/redstone_link_BP/manifest.json @@ -4,20 +4,36 @@ "name": "Redstone Link", "description": "Wireless redstone: pair a transmitter and a receiver by channel name, no wire in between", "uuid": "e4f1a7c2-6b95-4d38-a7e0-3c81d5f2b001", - "version": [1, 0, 0], - "min_engine_version": [1, 21, 0] + "version": [ + 1, + 0, + 0 + ], + "min_engine_version": [ + 1, + 21, + 0 + ] }, "modules": [ { "type": "data", "uuid": "e4f1a7c2-6b95-4d38-a7e0-3c81d5f2b002", - "version": [1, 0, 0] + "version": [ + 1, + 0, + 0 + ] }, { "type": "script", "language": "javascript", "uuid": "e4f1a7c2-6b95-4d38-a7e0-3c81d5f2b003", - "version": [1, 0, 0], + "version": [ + 1, + 0, + 0 + ], "entry": "scripts/main.js" } ], @@ -32,7 +48,11 @@ }, { "uuid": "e4f1a7c2-6b95-4d38-a7e0-3c81d5f2b004", - "version": [1, 0, 0] + "version": [ + 1, + 0, + 1 + ] } ] } diff --git a/redstone-link-addon/redstone_link_RP/manifest.json b/redstone-link-addon/redstone_link_RP/manifest.json index bed6a34..93add19 100644 --- a/redstone-link-addon/redstone_link_RP/manifest.json +++ b/redstone-link-addon/redstone_link_RP/manifest.json @@ -4,7 +4,7 @@ "name": "Redstone Link Resources", "description": "Textures and lang for the silverlabs:redstone_link_tx / _rx blocks", "uuid": "e4f1a7c2-6b95-4d38-a7e0-3c81d5f2b004", - "version": [1, 0, 0], + "version": [1, 0, 1], "min_engine_version": [1, 21, 0] }, "modules": [ diff --git a/redstone-link-addon/redstone_link_RP/textures/blocks/redstone_link_rx.png b/redstone-link-addon/redstone_link_RP/textures/blocks/redstone_link_rx.png index e2cd18b094db86a135a9f91d6b5d6626297341cb..d070425cb398d050201136492c8f218260213028 100644 GIT binary patch delta 265 zcmV+k0rvjN1fv3wBYyzuNklX8T2}xakwgeXkcFyH{_ig6jr0)LJwXlSE@u60`(rX2c+ zVHn685L1z20UH2m&avair-Xq8lt^Il3^y6c8)XwPHNgTJB^J;DEakYx+c@ZADhg0?Lvw018zUAcsR7NeloD23uQ$Yq$RZ P0000K~|;h#FCUjWw0pXrZ)FMA0`N{6bJ4L~7!0Hg0w|*{saT-CKO^Kyv5K+&MFI zX4bfV<7SFu%Jx}oFdPo)>woonFbsow9LGFGO!;#h z2SE_P_kGy5&HJA-3p$ezpy0MK9*+@*A^oCjfHX~sC>gWB6F+yS!M@MO@%$?9>Bpy- zOeRdI0es(QS(Euy6u&$}KA*>M;jVtbM>|a>>CUZS@TrX?Nsa(2l?qXN09yzz-a_f% zA%Vpw5-#3DvVY&AF8l~j8ld0rBc5Hx$zOZ;tAdA(H9AAZ18tXX!+O4k!?_jYdrxT3 z5k;}@x-QSGyp1~zT)5hx9z_w)YPG7X&;W%(ffr$y#vILPy*`?G#`<6|(B$eC#>y$o z8mc9Me7k+10R(&+Iu+Ro4G={UobNBtKYtA~opltJ9)BU}tfN>gaw3voaJdO>Ur zWmLa)kgBT9tY?`5$&wA*Zy~<&03(1uk@Bm@2vnuAo&Qyk%jF1Qf8Bz6Zixg;nkyd6tZ?bex1;ol{e%K({UL2!duWK?1AmxZt_FUFk##;OF zl9|ipGAlgKLz1QhmbI60XOl8coj!Z)&shNe0l{VQpG(hTQ~&?~07*qoM6N<$g1Zb1 A2mk;8 diff --git a/redstone-link-addon/redstone_link_RP/textures/blocks/redstone_link_tx.png b/redstone-link-addon/redstone_link_RP/textures/blocks/redstone_link_tx.png index 840156d36c6b03ffd24c469e5cece06f5b6299f6..a112e87520207fe81c680a77f742fcd7c3616384 100644 GIT binary patch delta 248 zcmVq7-QD-i40kHE)moWQUg+pVSt3BG{ZC%J-mj1 za`uadCy5%zsd5V+9kN7#J2# zVqiG;1{@pM01Jq~CJ8naq?rI@X3d8J{62 yNg1DJWJ7Q!WnuxcS{6{2gaJ^fVguO3VPXJTI&z3rBgmKl0000u530@DPLBYy%KNklVa2LR<^|1Fi(IA~R!J&!ztzSr;kwS@OA$SYPA|BlL<`Igb)Iw(FnF}BMd{Rs(%W@F!)lQ=kR@>eIzQq zX0w7ssgoqZX7UH1=S22|U~uwTmWAPPI0vw88?r1TiXvP&{K1a5%NIF21yjb&cmTu$ zyk1&mf4yFx1CV4{hHliy3wwoWJ{tUDJB|ZZx9t_^x{j;;1H5!PTo#E+uOJ8@Nm5}@ zRXp^2xU=9gXn(8KV!$20hpn+yWlz)e-x7oncxRfBgus?&;c3(_7^EJnTQw7PUB?IK z5_Pg-AahKba=ipHolc=B3Om=I?_&LOhtD*nl5HHv%&G!NlB5ctQrhiyk$v|`p(#+7 zIV<&{9C=lOq9{DV@p#Ne+5wXNZ@()50;bUsNTbm}vwzu~GcXJTnx^4ec*xFYBEkcA zjqASaba3zN1?&uunAyhYn3K`SD+XDXaTz4!*lwP|SQpd2N@%R`;lRh3!N zepCRIi8L-#HagSlzH!(1n*u%0gO=yKKxOw!ExF6*PyIU+z+a_Q0Q>YH;#L3v002ov JPDHLkV1lg)63_qu diff --git a/scripts/build-textures.py b/scripts/build-textures.py index c30a64c..35455f2 100644 --- a/scripts/build-textures.py +++ b/scripts/build-textures.py @@ -397,12 +397,99 @@ def portal_field() -> Image.Image: return img +# ── Redstone Link transmitter / receiver ─────────────────── +# Machine faces, not icons. Following the mailbox lesson: the motif has to +# reach the edges or a cube of it reads as a placeholder. Both share a gunmetal +# plate with corner rivets and a beveled frame; the transmitter carries redstone +# traces radiating OUT to all four edges, the receiver carries traces running IN +# to a collector dish. Same silhouette, mirrored behaviour, different accent. + +LINK_PLATE = (62, 66, 74) +LINK_PLATE_HL = (92, 97, 107) +LINK_PLATE_SH = (38, 41, 47) +LINK_RIVET = (140, 146, 158) + +TX_TRACE = (168, 30, 28) +TX_TRACE_HOT = REDSTONE_BRIGHT +TX_CORE = (255, 140, 110) + +RX_TRACE = (34, 96, 150) +RX_TRACE_HOT = (92, 178, 240) +RX_CORE = (200, 240, 255) + + +def _link_plate() -> Image.Image: + """Shared gunmetal base: beveled frame + corner rivets, fully opaque.""" + img = Image.new("RGBA", (16, 16), LINK_PLATE) + # Bevel: lit top/left, shadowed bottom/right + rect(img, 0, 0, 15, 0, LINK_PLATE_HL) + rect(img, 0, 0, 0, 15, LINK_PLATE_HL) + rect(img, 0, 15, 15, 15, LINK_PLATE_SH) + rect(img, 15, 0, 15, 15, LINK_PLATE_SH) + # Corner rivets + for cx, cy in ((2, 2), (13, 2), (2, 13), (13, 13)): + px(img, cx, cy, LINK_RIVET) + px(img, cx, cy + 1, LINK_PLATE_SH) + return img + + +def redstone_link_tx() -> Image.Image: + img = _link_plate() + # Traces running from the core out to all four edges: this is what makes a + # cube of it read as wiring rather than a centred sprite. + rect(img, 7, 0, 8, 15, TX_TRACE) + rect(img, 0, 7, 15, 8, TX_TRACE) + # Diagonal spurs toward the corners + for i in range(3, 7): + px(img, i, i, TX_TRACE) + px(img, 15 - i, i, TX_TRACE) + px(img, i, 15 - i, TX_TRACE) + px(img, 15 - i, 15 - i, TX_TRACE) + # Emitter core, hot centre + rect(img, 6, 6, 9, 9, TX_TRACE_HOT) + rect(img, 7, 7, 8, 8, TX_CORE) + px(img, 7, 7, (255, 235, 220)) + # Trace highlight so the cross reads as raised + rect(img, 7, 1, 7, 5, TX_TRACE_HOT) + rect(img, 1, 7, 5, 7, TX_TRACE_HOT) + return img + + +def redstone_link_rx() -> Image.Image: + img = _link_plate() + # Collector rings, broken at the axes so the in-running traces read clearly + for x in range(3, 13): + px(img, x, 3, RX_TRACE) + px(img, x, 12, RX_TRACE) + for y in range(3, 13): + px(img, 3, y, RX_TRACE) + px(img, 12, y, RX_TRACE) + for x in range(5, 11): + px(img, x, 5, RX_TRACE_HOT) + px(img, x, 10, RX_TRACE_HOT) + for y in range(5, 11): + px(img, 5, y, RX_TRACE_HOT) + px(img, 10, y, RX_TRACE_HOT) + # Feed lines from the edges into the dish + rect(img, 7, 0, 8, 2, RX_TRACE) + rect(img, 7, 13, 8, 15, RX_TRACE) + rect(img, 0, 7, 2, 8, RX_TRACE) + rect(img, 13, 7, 15, 8, RX_TRACE) + # Collector core + rect(img, 7, 7, 8, 8, RX_TRACE_HOT) + px(img, 7, 7, RX_CORE) + px(img, 8, 8, RX_CORE) + return img + + def main() -> None: save(smart_crafting_table(), "smart-crafting-addon/smart_crafting_RP/textures/blocks/smart_crafting_table.png") save(post_office_block(), "postal-service-addon/postal_service_RP/textures/blocks/post_office.png") save(mailbox_block(), "postal-service-addon/postal_service_RP/textures/blocks/mailbox.png") save(tent_canvas(), "camping-supplies-addon/camping_supplies_RP/textures/blocks/tent_canvas.png") save(portal_field(), "lobby-addon/lobby_transfer_RP/textures/blocks/portal_field.png") + save(redstone_link_tx(), "redstone-link-addon/redstone_link_RP/textures/blocks/redstone_link_tx.png") + save(redstone_link_rx(), "redstone-link-addon/redstone_link_RP/textures/blocks/redstone_link_rx.png") if __name__ == "__main__":