Recreating Qbeh-1
Placing and removing the puzzle cubes in Qbeh-1 works differently in Minecraft.
In Qbeh-1, you can pick up a cube and it will instantly go into your inventory. It has the restriction that cubes must have some connection to a yellow block, when placing or picking up.
Qbeh-1 picking up a cube at the end of some cubes
(press pick-up button)
Qbeh-1 picking up a cube at the base of some cubes
(press pick-up button)
In Minecraft, breaking any block will make it drop an item. You then have to walk over to the item to put it in your inventory to use it. Any block
In order to make differentiate cubes that can be picked up from cubes that can’t, Minecraft has gamemode adventure
to disable all block breaking, and the CanDestory
tag on tools to re-enable block breaking, but only for specific blocks
execute as @a run item replace entity @s container.0 with
minecraft:iron_pickaxe{Enchantments:[{id:efficiency,lvl:3}],
Unbreakable:1
CanDestroy:["minecraft:lapis_block","minecraft:redstone_block","minecraft:purpur_block","minecraft:emerald_block"],
display:{Name:"{\"text\":\"Retriever\"}",Lore:["{\"text\":\"Collect groups of cubes\"}","{\"text\":\"Items teleport to you\"}"]}}
Making items instantly teleport to the player’s inventory was easy. I could have also done this by disabling item drops, detecting items breaking, and then usuing /give
, but this works.
execute as @e[type=item] run data merge entity @s {Age:10s,PickupDelay:0s}
execute as @e[type=item] at @s at @a[gamemode=adventure,limit=1,sort=nearest] run teleport @s ~ ~1 ~
Instead of maintaining a tree structure for Qbeh-1, I instead went for a mechanic that modded Minecraft players will recognize as “vein-mining”. Whenever one cube is broken, the adjacent 6 cubes are searched for more cubes to break, and this loops recursively until the entire contiguous structure is broken. The trickiest part of this was detecting where the player breaks a block. Its easy to detect when with scoreboards, and its trivial to detect where the player is, but there is no easy way to trigger a function at the block that was just broken.
I ended up recording the XYZ position of the puzzle cube the player has most recently looked at, and then waiting for that block to turn into air.
(this is done by creating an invisible armorstand at the XYZ position with a constant offset of -100 y blocks, because even invisible armorstands still have some subtle interactions, and I just needed to record the XYZ position) (a modern datapack would just use a marker
entity)
Mineraft datapacks don’t have any clean way of detecting what block the player is looking at! So I have to write a loop that scans a line in front of the players vision.
Minecraft’s internal raycasting can perfectly detect this blue cube, but datapack functions can only detect points. This isn’t reliable, so if the scan line hasn’t found anything, the players ability to mine is disabled with mining fatigue until the player looks at an angle where the raycast can find a cube. This fixes most cases, but it is still possible to mine a block that the datapack doesn’t detect, if you happen to be looking at a different block.
All 3 of these blocks should have been picked up here, but since the datapack thought the player was looking at a different block, it never detected it was broken.
This is a pretty precise and rare glitch, and since it doesn’t break any of the puzzles, I didn’t try to spend another week fixing it. It would be nice if Mojang added something like /execute targeted <block/liquid> <max range>
, or a way to run functions not only when a block is placed/broken, but also at that block.
A similar point-raycast method is used when placing the purple “gravity” cube and the green “force” cube. A scoreboard objective was created that detects every time a purple/green block is placed, and then searches the area in front of the player to find that cube, then spawns an entity.
The purple “gravity” cube entity just applies a few potion effects (jump boost, slow falling) to a volume around the cube and creates some particle effects.
The green “force” cube deletes the original green block, and recreates it as a collection of entities. An invisible shulker mob for its solid collision box, a falling sand entity to display a block (modern data packs would use a display entity), and an invisible armorstand for them both to ride on. This entity can then move around however I need it, and this creates a decent illusion of a moving block. If a player is standing on top of it when it moves upwards, the player will fall through, so I had to write some hacky code to also move up any players that were standing on one of these upward-moving cubes.