Run it
Copy the script and paste it into your executor.
()
Players = :()
RunService = :()
UIS = :()
GuiService = :()
ContextActionService = :()
Lighting = :()
lp = Players.LocalPlayer
camera = .CurrentCamera
camera
:():()
camera = .CurrentCamera
playerGui = lp:()
oldCameraMode = lp.CameraMode
oldCameraMinZoom = lp.CameraMinZoomDistance
oldCameraMaxZoom = lp.CameraMaxZoomDistance
F = {}
.__MCSteveStop (.__MCSteveStop)
conns = {}
F.track = (c) conns[#conns + ] = c c
BLOCK =
PX = BLOCK /
TICK = /
WALK_BLOCKS_PER_SECOND =
SPRINT_BLOCKS_PER_SECOND =
SNEAK_BLOCKS_PER_SECOND =
FLY_BLOCKS_PER_SECOND =
FLY_SPRINT_BLOCKS_PER_SECOND =
GROUND_SLIPPERINESS =
BODY_MOVE_TURN_RESPONSE =
BODY_TURN_RESPONSE =
BODY_TURN_DEADZONE = .()
MAX_HEAD_YAW = .()
IMG = {
inventory = {w=,h=,d=},
hotbar = {w=,h=,d=},
hotbar_sel = {w=,h=,d=},
xp_bg = {w=,h=,d=1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;2:28332d;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;1:141f19;1:29352f;1:202c25;5:19241e;1:202c25;1:29352f;2:09100c;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;2:202b25;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:141f19;1:36433c;1:2e3a33;5:29352f;1:2e3a33;1:36433c;1:09100c;1:-;180:09100c;1:-"},
crosshair = {w=15,h=15,d="52:-;1:ffffff;14:-;1:ffffff;14:-;1:ffffff;14:-;1:ffffff;10:-;9:ffffff;10:-;1:ffffff;14:-;1:ffffff;14:-;1:ffffff;14:-;1:ffffff;52:-"},
}
local ICON = {
stone = {w=16,h=16,d="7:-;1:7f7f7f;1:8f8f8f;12:-;2:7f7f7f;1:8f8f8f;1:686868;2:747474;8:-;1:7f7f7f;1:8f8f8f;1:686868;1:8f8f8f;1:7f7f7f;1:747474;1:7f7f7f;1:686868;1:7f7f7f;1:686868;4:-;1:8f8f8f;1:747474;4:7f7f7f;1:747474;1:8f8f8f;1:7f7f7f;1:8f8f8f;2:7f7f7f;1:686868;1:7f7f7f;1:-;1:727272;2:7f7f7f;1:747474;2:8f8f8f;1:686868;2:8f8f8f;5:747474;1:7f7f7f;1:4c4c4c;1:5c5c5c;1:656565;1:5c5c5c;1:747474;1:7f7f7f;1:747474;3:7f7f7f;1:8f8f8f;3:7f7f7f;2:454545;1:4c4c4c;1:656565;1:727272;1:5c5c5c;1:656565;1:535353;1:8f8f8f;1:7f7f7f;2:747474;1:7f7f7f;1:747474;3:4c4c4c;1:454545;1:4c4c4c;2:656565;1:5c5c5c;1:656565;1:5c5c5c;1:535353;1:656565;1:7f7f7f;1:8f8f8f;1:555555;1:4c4c4c;1:3e3e3e;2:555555;1:3e3e3e;1:4c4c4c;1:727272;1:535353;1:727272;1:656565;1:727272;2:656565;1:5c5c5c;1:4c4c4c;1:3e3e3e;1:555555;3:454545;1:4c4c4c;1:454545;3:656565;2:5c5c5c;1:535353;2:5c5c5c;1:4c4c4c;1:454545;1:4c4c4c;1:555555;2:4c4c4c;1:555555;1:454545;1:5c5c5c;1:656565;1:5c5c5c;2:727272;1:5c5c5c;1:656565;1:727272;2:555555;1:3e3e3e;1:555555;2:4c4c4c;1:555555;1:454545;2:5c5c5c;1:727272;2:656565;1:727272;2:656565;1:454545;2:4c4c4c;1:3e3e3e;1:4c4c4c;1:3e3e3e;1:454545;1:555555;1:-;2:656565;1:5c5c5c;2:656565;1:5c5c5c;1:656565;2:4c4c4c;1:555555;2:454545;1:4c4c4c;1:454545;4:-;1:5c5c5c;2:656565;1:5c5c5c;1:727272;1:4c4c4c;1:454545;2:4c4c4c;1:555555;8:-;1:656565;2:727272;1:555555;2:4c4c4c;12:-;1:656565;1:4c4c4c;7:-"},
dirt = {w=16,h=16,d="7:-;1:79553a;1:966c4a;12:-;2:79553a;1:b9855c;1:593d29;1:79553a;1:b9855c;8:-;2:79553a;1:b9855c;2:79553a;1:966c4a;4:79553a;4:-;1:79553a;1:593d29;1:79553a;1:b9855c;1:79553a;1:966c4a;1:79553a;1:b9855c;2:593d29;2:79553a;2:b9855c;1:-;1:78563b;2:b9855c;1:745844;1:966c4a;1:79553a;1:966c4a;1:79553a;2:966c4a;1:b9855c;1:79553a;2:966c4a;1:79553a;1:6f4f37;2:60442e;1:946a49;1:878787;1:593d29;2:79553a;1:966c4a;1:593d29;1:b9855c;1:79553a;2:966c4a;1:483322;1:5a402c;1:483322;3:60442e;1:473020;1:60442e;1:79553a;1:966c4a;4:79553a;1:5a402c;1:6f4f37;1:483322;1:6f4f37;1:483322;1:60442e;2:78563b;1:946a49;2:60442e;1:946a49;1:79553a;1:966c4a;1:483322;1:5a402c;1:483322;1:5a402c;1:404040;1:483322;1:5a402c;1:60442e;1:946a49;1:60442e;2:473020;1:78563b;2:473020;1:5a402c;2:352418;2:483322;1:6f4f37;2:483322;1:78563b;1:60442e;1:78563b;2:60442e;1:473020;1:78563b;1:60442e;1:404040;1:6f4f37;1:5a402c;1:6f4f37;1:352418;1:483322;1:6f4f37;1:483322;1:473020;1:78563b;2:60442e;3:78563b;1:946a49;1:352418;1:483322;1:5a402c;1:352418;1:483322;1:352418;1:5a402c;1:6f4f37;2:60442e;2:78563b;1:946a49;2:60442e;1:78563b;1:483322;1:5a402c;1:352418;2:5a402c;1:483322;1:6f4f37;1:5a402c;1:-;1:78563b;1:473020;1:78563b;2:60442e;2:78563b;1:5a402c;2:6f4f37;1:483322;1:352418;2:5a402c;4:-;1:60442e;1:946a49;1:473020;1:60442e;1:473020;3:483322;1:352418;1:5a402c;8:-;2:60442e;1:78563b;1:5a402c;1:6f4f37;1:483322;12:-;1:473020;1:483322;7:-"},
cobblestone = {w=16,h=16,d="7:-;2:616161;12:-;1:b5b5b5;1:6e6d6d;1:888788;1:a6a6a6;1:888788;1:616161;8:-;2:616161;1:6e6d6d;2:888788;1:a6a6a6;2:888788;2:a6a6a6;4:-;1:616161;1:888788;6:6e6d6d;1:525252;4:616161;1:b5b5b5;1:-;1:4d4d4d;1:616161;1:6e6d6d;1:888788;1:616161;1:888788;1:525252;2:888788;4:a6a6a6;1:616161;1:6e6d6d;1:515151;1:848484;1:6c6c6c;1:4d4d4d;3:6e6d6d;1:a6a6a6;5:616161;1:b5b5b5;1:3a3a3a;1:515151;1:424141;2:585757;1:4d4d4d;1:909090;1:848484;3:616161;1:888788;2:b5b5b5;1:636363;1:515151;1:3a3a3a;1:515151;1:3a3a3a;1:6c6c6c;1:909090;1:848484;1:585757;1:848484;1:414141;1:909090;1:888788;1:616161;1:636363;1:313131;1:515151;1:424141;1:636363;1:515151;1:6c6c6c;1:4d4d4d;1:585757;1:6c6c6c;2:4d4d4d;1:6c6c6c;1:4d4d4d;1:6c6c6c;2:636363;1:3a3a3a;2:515151;1:636363;1:515151;1:424141;1:585757;1:6c6c6c;1:585757;2:4d4d4d;1:909090;1:848484;1:414141;1:3a3a3a;2:515151;1:424141;1:6c6c6c;2:515151;2:6c6c6c;2:4d4d4d;1:585757;1:6c6c6c;1:4d4d4d;1:585757;1:6c6c6c;1:424141;4:515151;1:3a3a3a;1:6c6c6c;1:515151;1:848484;1:6c6c6c;1:4d4d4d;1:909090;2:585757;1:4d4d4d;1:6c6c6c;1:515151;1:636363;1:515151;1:313131;4:3a3a3a;1:-;1:4d4d4d;1:585757;1:6c6c6c;1:848484;1:414141;1:848484;1:4d4d4d;1:6c6c6c;2:424141;1:636363;1:515151;1:3a3a3a;1:636363;4:-;1:4d4d4d;1:6c6c6c;1:585757;2:6c6c6c;1:424141;1:636363;1:3a3a3a;1:424141;1:3a3a3a;8:-;2:6c6c6c;1:585757;1:6c6c6c;1:424141;1:515151;12:-;1:585757;1:515151;7:-"},
oak_planks = {w=16,h=16,d="7:-;1:b8945f;1:af8f55;12:-;1:af8f55;1:c29d62;1:7e6237;1:b8945f;1:967441;1:c29d62;8:-;1:b8945f;1:c29d62;1:7e6237;1:b8945f;1:9f844d;1:c29d62;1:67502c;1:9f844d;1:b8945f;1:c29d62;4:-;1:af8f55;1:9f844d;1:7e6237;1:af8f55;1:b8945f;1:af8f55;1:67502c;1:967441;1:9f844d;1:c29d62;1:67502c;1:af8f55;1:b8945f;1:c29d62;1:-;1:8c7244;1:7e6237;1:af8f55;1:9f844d;1:b8945f;1:67502c;2:9f844d;1:c29d62;1:7e6237;1:af8f55;1:b8945f;1:af8f55;1:7e6237;1:967441;1:5a4527;1:93764c;1:8c7244;1:9b7d4e;2:967441;1:9f844d;1:c29d62;1:967441;2:af8f55;1:c29d62;1:7e6237;1:9f844d;1:745e3a;1:6e5839;1:5a4527;1:9b7d4e;1:785c34;2:93764c;1:9b7d4e;1:67502c;1:9f844d;2:b8945f;1:67502c;1:9f844d;1:745e3a;1:6e5839;1:695533;1:3d301a;1:6e5839;1:7f693d;1:8c7244;1:9b7d4e;1:524023;1:7f693d;1:8c7244;1:9b7d4e;1:67502c;1:9f844d;1:745e3a;2:5f4f2e;1:4b3a21;2:6e5839;1:5f4f2e;1:9b7d4e;1:644e2c;1:8c7244;1:785c34;1:9b7d4e;1:644e2c;1:93764c;1:7f693d;2:6e5839;1:4b3a21;1:5f4f2e;2:695533;1:5a4527;1:5f4f2e;2:93764c;1:8c7244;1:524023;2:93764c;1:8c7244;1:524023;1:4b3a21;1:745e3a;1:695533;1:5a4527;1:3d301a;1:745e3a;2:5f4f2e;1:7f693d;1:785c34;2:7f693d;1:9b7d4e;1:644e2c;1:7f693d;1:8c7244;2:6e5839;1:4b3a21;1:745e3a;1:5f4f2e;1:695533;1:3d301a;1:745e3a;1:7f693d;2:93764c;1:524023;1:8c7244;1:7f693d;1:9b7d4e;1:524023;1:3d301a;2:6e5839;1:5f4f2e;1:4b3a21;1:5f4f2e;1:695533;1:5f4f2e;1:-;1:524023;1:8c7244;1:7f693d;1:9b7d4e;1:644e2c;1:7f693d;1:785c34;2:695533;1:4b3a21;1:5f4f2e;1:6e5839;1:5f4f2e;1:3d301a;4:-;1:785c34;1:93764c;1:8c7244;1:93764c;1:524023;1:3d301a;1:745e3a;1:5f4f2e;1:5a4527;1:4b3a21;8:-;1:644e2c;1:7f693d;1:8c7244;2:695533;1:4b3a21;12:-;1:524023;1:4b3a21;7:-"},
oak_log = {w=16,h=16,d="7:-;2:4c3d26;12:-;1:4c3d26;1:af8f55;2:7e6237;1:b8945f;1:4c3d26;8:-;1:4c3d26;1:af8f55;1:9f844d;3:af8f55;1:b8945f;1:967441;1:c29d62;1:4c3d26;4:-;1:5f4a2b;1:b8945f;1:9f844d;1:b8945f;1:af8f55;1:967441;2:af8f55;1:9f844d;1:af8f55;1:b8945f;1:9f844d;1:b8945f;1:5f4a2b;1:-;1:3c301e;1:5f4a2b;1:b8945f;1:9f844d;2:af8f55;1:7e6237;2:af8f55;1:9f844d;1:af8f55;1:b8945f;1:9f844d;1:b8945f;1:5f4a2b;1:392c19;1:2c2213;1:4c3b22;1:2c2213;1:5f4a2b;1:af8f55;1:967441;1:b8945f;3:af8f55;1:967441;1:af8f55;1:5f4a2b;1:574327;1:453620;1:392c19;1:3c301e;1:4c3b22;1:2c2213;1:4c3b22;1:2c2213;1:5f4a2b;1:af8f55;2:967441;1:af8f55;1:5f4a2b;1:453620;1:21190e;1:2d2416;2:453620;2:5c482b;1:2c2213;1:4c3b22;1:3c301e;2:745a34;2:5f4a2b;1:453620;1:21190e;3:392c19;1:2d2416;1:453620;1:3c301e;1:5c482b;1:4c3b22;1:3c301e;1:4c3b22;1:2c2213;1:5c482b;1:4c3b22;1:2d2416;1:392c19;1:2d2416;2:392c19;1:453620;1:392c19;1:453620;1:5c482b;1:79603a;1:5c482b;1:745a34;1:5c482b;2:3c301e;1:4c3b22;1:21190e;1:392c19;1:2d2416;2:453620;1:392c19;2:453620;1:3c301e;1:745a34;1:4c3b22;1:5c482b;2:4c3b22;1:3c301e;1:5c482b;3:453620;1:574327;1:392c19;1:2d2416;2:453620;2:5c482b;1:4c3b22;1:2c2213;1:4c3b22;1:3c301e;1:4c3b22;1:5c482b;1:453620;1:5b482b;1:453620;1:21190e;1:453620;1:21190e;2:453620;1:-;1:745a34;1:5c482b;1:3c301e;1:4c3b22;1:2c2213;2:5c482b;1:453620;1:574327;1:392c19;1:21190e;1:392c19;1:2d2416;1:574327;4:-;3:3c301e;2:5c482b;1:2d2416;2:453620;1:21190e;1:2d2416;8:-;1:5c482b;1:745a34;1:5c482b;1:453620;1:574327;1:453620;12:-;1:4c3b22;1:453620;7:-"},
grass_block = {w=16,h=16,d="7:-;1:546e34;1:6e9044;12:-;1:577135;1:4a612d;1:4e6630;1:4b612e;1:577135;1:516931;8:-;1:556f34;1:587236;1:597436;1:516a32;1:495f2d;1:62803c;1:475c2b;1:516a32;1:485e2c;1:556f34;4:-;1:495f2d;1:556f34;1:4c632e;1:5d7a39;1:4f6730;1:495f2d;1:5d7939;1:485e2c;1:4c642f;1:425628;1:506831;1:62803c;1:6e9044;1:5e7b3a;1:-;1:405428;1:4d642f;1:455b2a;1:475c2b;1:526b32;1:536c32;1:536c33;1:4c642f;1:607e3b;1:4c642f;1:617f3c;1:445829;1:475d2b;1:5e7b3a;1:67863f;1:33421f;1:473020;2:405428;1:546d33;1:536c33;1:5b7738;1:526b32;1:4f6730;1:4a612d;1:506931;1:536c33;1:485e2c;1:516931;1:364621;1:2f3d1c;1:352418;1:60442e;2:473020;1:3a4c24;1:485d2c;1:465b2b;1:4c642f;1:5a7637;1:5d7a39;1:475c2b;1:516931;2:33421f;1:3a4c24;1:352418;1:483322;1:60442e;2:78563b;1:473020;1:485d2c;1:425628;1:3a4c24;1:4d642f;1:44592a;1:2f3d1c;3:352418;1:404040;1:483322;1:5a402c;1:60442e;1:946a49;1:60442e;3:473020;1:354620;1:3f5226;1:2f3d1c;1:2d3a1b;1:352418;2:483322;1:6f4f37;2:483322;1:78563b;1:60442e;1:78563b;2:60442e;1:473020;1:78563b;1:60442e;1:404040;1:6f4f37;1:5a402c;1:6f4f37;1:352418;1:483322;1:6f4f37;1:483322;1:473020;1:78563b;2:60442e;3:78563b;1:946a49;1:352418;1:483322;1:5a402c;1:352418;1:483322;1:352418;1:5a402c;1:6f4f37;2:60442e;2:78563b;1:946a49;2:60442e;1:78563b;1:483322;1:5a402c;1:352418;2:5a402c;1:483322;1:6f4f37;1:5a402c;1:-;1:78563b;1:473020;1:78563b;2:60442e;2:78563b;1:5a402c;2:6f4f37;1:483322;1:352418;2:5a402c;4:-;1:60442e;1:946a49;1:473020;1:60442e;1:473020;3:483322;1:352418;1:5a402c;8:-;2:60442e;1:78563b;1:5a402c;1:6f4f37;1:483322;12:-;1:473020;1:483322;7:-"},
crafting_table = {w=16,h=16,d="7:-;2:0e0b06;12:-;1:733920;1:9e5932;2:ae693c;1:9e5932;1:733920;8:-;1:733920;2:ae693c;1:553824;2:ae693c;1:553824;2:ae693c;1:733920;4:-;1:0e0b06;1:41230e;1:ae693c;2:4b2b18;1:ae693c;2:553824;1:ae693c;2:4b2b18;1:ae693c;1:41230e;1:0e0b06;1:-;1:8c7244;1:0e0b06;1:41230e;1:ae693c;2:4b2b18;1:ae693c;1:4b2b18;1:553824;1:ae693c;1:4b2b18;1:553824;1:ae693c;1:41230e;1:0e0b06;1:0f0c07;1:93764c;1:8c7244;1:2c1a11;1:733920;2:ae693c;1:553824;1:9e5932;1:ae693c;1:553824;2:ae693c;1:733920;1:745e3a;1:6e5839;1:0f0c07;1:9b7d4e;1:785c34;1:93764c;1:3c2213;1:5c2d19;1:733920;1:9e5932;2:ae693c;1:9e5932;1:733920;1:2d190e;1:21130d;1:695533;1:3d301a;1:0f0c07;1:7f693d;1:341c0b;1:9b7d4e;1:15110a;1:7f693d;1:8c7244;1:9b7d4e;1:0e0b06;1:1a150d;1:745e3a;1:5f4f2e;1:16130a;1:4b3a21;2:6e5839;1:0f0c07;1:9b7d4e;1:201808;1:8c7244;1:2c1a11;1:9b7d4e;1:341c0b;1:93764c;1:141009;2:6e5839;1:4b3a21;1:2d190e;2:695533;1:5a4527;1:0f0c07;1:93764c;1:acacac;1:8c7244;1:15110a;1:93764c;2:201808;1:141009;1:4b3a21;1:745e3a;1:271508;1:21130d;1:3d301a;1:745e3a;1:5f4f2e;1:0f0c07;1:7f693d;1:785c34;1:7f693d;1:2c1a11;1:9b7d4e;1:cccccc;1:909090;1:141009;1:6e5839;1:181206;1:4b3a21;1:2d190e;1:5f4f2e;1:695533;1:3d301a;1:0f0c07;1:7f693d;2:93764c;1:0d0b06;1:8c7244;1:7f693d;1:acacac;1:141009;1:3d301a;1:818181;1:6c6c6c;1:21130d;1:4b3a21;1:5f4f2e;1:695533;1:0f0c07;1:-;1:524023;1:8c7244;1:2c1a11;1:9b7d4e;1:644e2c;1:acacac;1:141009;2:695533;1:4b3a21;1:2d190e;1:6e5839;1:5f4f2e;1:3d301a;4:-;1:141009;1:93764c;1:8c7244;1:cccccc;1:141009;1:3d301a;1:745e3a;1:5f4f2e;1:21130d;1:4b3a21;8:-;1:644e2c;1:7f693d;1:141009;2:695533;1:4b3a21;12:-;1:15110a;1:4b3a21;7:-"},
diamond_sword = {w=16,h=16,d="13:-;3:0e3f36;12:-;1:0e3f36;2:a4fdf0;1:082520;11:-;1:0e3f36;1:a4fdf0;1:2bc7ac;1:a4fdf0;1:082520;10:-;1:0e3f36;1:a4fdf0;1:2bc7ac;1:a4fdf0;1:082520;10:-;1:0e3f36;1:a4fdf0;1:2bc7ac;1:33ebcb;1:082520;10:-;1:0e3f36;1:a4fdf0;1:2bc7ac;1:33ebcb;1:082520;5:-;2:0e3f36;3:-;1:0e3f36;1:33ebcb;1:2bc7ac;1:33ebcb;1:082520;6:-;1:0e3f36;1:156355;1:0e3f36;1:-;1:0e3f36;1:33ebcb;1:2bc7ac;1:33ebcb;1:082520;8:-;1:0e3f36;1:1e8a77;1:082520;1:33ebcb;1:1e8a77;1:33ebcb;1:082520;9:-;1:0e3f36;2:1e8a77;1:156355;1:33ebcb;1:082520;11:-;1:0e3f36;1:156355;1:0e3f36;1:082520;11:-;1:493615;1:684e1e;1:082520;2:0e3f36;1:082520;9:-;1:493615;1:896727;1:281e0b;1:-;2:082520;1:0e3f36;1:082520;6:-;2:0e3f36;1:684e1e;1:281e0b;4:-;2:082520;6:-;1:0e3f36;1:156355;1:082520;13:-;3:082520;13:-"},
diamond_pickaxe = {w=16,h=16,d="38:-;5:0e3f36;10:-;1:0e3f36;1:33ebcb;1:2bc7ac;2:27b29a;1:2bc7ac;1:0e3f36;1:493615;1:684e1e;8:-;1:0e3f36;3:082520;2:27b29a;1:896727;1:281e0b;12:-;1:493615;1:2bc7ac;1:27b29a;1:082520;11:-;1:493615;1:684e1e;1:281e0b;1:27b29a;1:2bc7ac;1:082520;9:-;1:493615;1:896727;1:281e0b;1:-;1:082520;1:27b29a;1:082520;8:-;1:493615;1:684e1e;1:281e0b;2:-;1:082520;1:27b29a;1:082520;7:-;1:493615;1:896727;1:281e0b;3:-;1:082520;1:2bc7ac;1:082520;6:-;1:493615;1:684e1e;1:281e0b;4:-;1:082520;1:33ebcb;1:082520;5:-;1:493615;1:896727;1:281e0b;6:-;1:082520;5:-;1:493615;1:684e1e;1:281e0b;12:-;1:493615;1:896727;1:281e0b;13:-;2:281e0b;28:-"},
diamond_axe = {w=16,h=16,d="25:-;2:0e3f36;13:-;1:0e3f36;2:33ebcb;1:0e3f36;11:-;1:0e3f36;1:33ebcb;1:27b29a;1:2bc7ac;1:0e3f36;10:-;1:0e3f36;1:33ebcb;3:27b29a;1:493615;1:684e1e;9:-;1:082520;1:33ebcb;1:2bc7ac;1:27b29a;1:1e8a77;1:27b29a;1:281e0b;10:-;2:082520;1:493615;1:27b29a;1:1e8a77;1:27b29a;1:082520;10:-;1:493615;1:684e1e;1:281e0b;2:27b29a;1:082520;9:-;1:493615;1:896727;1:281e0b;1:-;2:082520;9:-;1:493615;1:684e1e;1:281e0b;12:-;1:493615;1:684e1e;1:281e0b;12:-;1:493615;1:896727;1:281e0b;12:-;1:493615;1:684e1e;1:281e0b;12:-;1:493615;1:896727;1:281e0b;13:-;2:281e0b;28:-"},
diamond_shovel = {w=16,h=16,d="43:-;2:0e3f36;1:082520;12:-;1:0e3f36;2:33ebcb;1:27b29a;1:082520;10:-;1:0e3f36;1:33ebcb;1:2bc7ac;1:27b29a;1:33ebcb;1:082520;9:-;1:0e3f36;1:33ebcb;1:2bc7ac;1:27b29a;1:2bc7ac;1:33ebcb;1:082520;10:-;1:493615;1:27b29a;1:2bc7ac;1:33ebcb;1:082520;10:-;1:493615;1:896727;1:281e0b;1:33ebcb;1:082520;10:-;1:493615;1:896727;1:281e0b;1:-;1:082520;10:-;1:493615;1:684e1e;1:281e0b;12:-;1:493615;1:896727;1:281e0b;12:-;1:493615;1:684e1e;1:281e0b;11:-;2:493615;1:896727;1:281e0b;12:-;1:493615;1:896727;1:281e0b;14:-;2:281e0b;27:-"},
iron_helmet = {w=16,h=16,d="53:-;6:2d2d2d;9:-;1:2d2d2d;1:969696;4:c6c6c6;1:6b6b6b;1:191919;7:-;1:2d2d2d;1:969696;1:d8d8d8;1:ffffff;1:d8d8d8;2:c6c6c6;1:969696;1:6b6b6b;1:191919;6:-;1:2d2d2d;1:c6c6c6;2:d8d8d8;2:c6c6c6;3:969696;1:191919;6:-;1:2d2d2d;2:c6c6c6;3:2d2d2d;1:191919;1:6b6b6b;1:969696;1:191919;6:-;1:2d2d2d;1:c6c6c6;1:2d2d2d;5:191919;1:969696;1:191919;6:-;1:2d2d2d;1:c6c6c6;1:2d2d2d;5:191919;1:6b6b6b;1:191919;6:-;1:2d2d2d;1:969696;6:191919;1:6b6b6b;1:191919;7:-;1:2d2d2d;1:191919;4:-;2:191919;68:-"},
iron_chestplate = {w=16,h=16,d="33:-;5:2d2d2d;4:-;5:2d2d2d;2:-;1:2d2d2d;1:ffffff;1:d8d8d8;1:c6c6c6;1:2d2d2d;4:-;1:2d2d2d;1:ffffff;1:d8d8d8;1:c6c6c6;1:2d2d2d;2:-;1:2d2d2d;1:d8d8d8;2:c6c6c6;1:969696;1:2d2d2d;2:-;1:2d2d2d;1:969696;1:d8d8d8;2:c6c6c6;1:2d2d2d;2:-;1:2d2d2d;3:c6c6c6;1:d8d8d8;1:969696;2:2d2d2d;1:969696;4:c6c6c6;1:2d2d2d;2:-;1:2d2d2d;1:6b6b6b;1:969696;1:c6c6c6;1:ffffff;3:d8d8d8;3:c6c6c6;1:969696;1:6b6b6b;1:2d2d2d;2:-;2:191919;1:6b6b6b;3:d8d8d8;5:c6c6c6;1:6b6b6b;2:191919;4:-;1:191919;2:d8d8d8;6:c6c6c6;1:191919;6:-;1:191919;1:c6c6c6;1:d8d8d8;5:c6c6c6;1:969696;1:191919;6:-;1:191919;7:c6c6c6;1:969696;1:191919;6:-;1:191919;1:969696;5:c6c6c6;2:969696;1:191919;6:-;1:191919;1:6b6b6b;6:969696;1:6b6b6b;1:191919;7:-;1:191919;1:6b6b6b;4:969696;1:6b6b6b;1:191919;9:-;6:191919;21:-"},
iron_leggings = {w=16,h=16,d="36:-;7:2d2d2d;1:191919;7:-;1:2d2d2d;1:d8d8d8;2:ffffff;2:d8d8d8;2:c6c6c6;1:6b6b6b;1:191919;6:-;1:2d2d2d;2:d8d8d8;5:c6c6c6;1:969696;1:191919;6:-;1:2d2d2d;1:d8d8d8;1:c6c6c6;3:969696;2:c6c6c6;1:969696;1:191919;6:-;1:2d2d2d;1:d8d8d8;1:c6c6c6;1:969696;2:191919;1:6b6b6b;1:c6c6c6;1:969696;1:191919;6:-;1:2d2d2d;2:c6c6c6;1:191919;2:-;1:191919;1:c6c6c6;1:969696;1:191919;6:-;1:2d2d2d;1:c6c6c6;1:969696;1:191919;2:-;1:2d2d2d;1:c6c6c6;1:969696;1:191919;6:-;1:2d2d2d;1:c6c6c6;1:969696;1:191919;2:-;1:2d2d2d;1:c6c6c6;1:969696;1:191919;6:-;1:2d2d2d;2:969696;1:191919;2:-;1:191919;2:969696;1:191919;6:-;1:2d2d2d;1:969696;1:6b6b6b;1:191919;2:-;1:191919;1:969696;1:6b6b6b;1:191919;6:-;1:191919;2:6b6b6b;1:191919;2:-;1:191919;2:6b6b6b;1:191919;6:-;4:191919;2:-;4:191919;35:-"},
iron_boots = {w=16,h=16,d="52:-;3:2d2d2d;2:-;3:2d2d2d;7:-;1:2d2d2d;1:ffffff;1:d8d8d8;1:191919;2:-;1:2d2d2d;1:ffffff;1:d8d8d8;1:191919;6:-;1:2d2d2d;2:d8d8d8;1:191919;2:-;1:2d2d2d;1:d8d8d8;1:c6c6c6;1:191919;6:-;1:2d2d2d;1:d8d8d8;1:c6c6c6;1:191919;2:-;1:2d2d2d;2:c6c6c6;1:191919;6:-;1:2d2d2d;2:c6c6c6;1:191919;2:-;1:2d2d2d;2:c6c6c6;1:191919;6:-;1:2d2d2d;1:c6c6c6;1:969696;1:191919;2:-;1:2d2d2d;2:c6c6c6;1:191919;5:-;1:2d2d2d;2:c6c6c6;1:969696;1:191919;2:-;1:2d2d2d;1:969696;1:c6c6c6;1:969696;1:191919;3:-;1:2d2d2d;2:c6c6c6;1:969696;1:6b6b6b;1:191919;2:-;1:2d2d2d;1:6b6b6b;1:969696;1:c6c6c6;1:969696;1:191919;2:-;1:2d2d2d;2:969696;1:6b6b6b;2:191919;2:-;2:191919;2:969696;1:6b6b6b;1:191919;2:-;1:2d2d2d;3:191919;6:-;4:191919;49:-"},
cooked_beef = {w=16,h=16,d="57:-;4:4e2719;11:-;1:4e2719;1:713f2d;1:7c4835;1:713f2d;1:8e523c;1:4e2719;9:-;1:4e2719;1:522f1f;1:985c43;1:8e523c;1:673728;1:713f2d;1:673728;1:4e2719;7:-;1:4e2719;2:8e523c;1:522f1f;1:7c4835;1:8e523c;1:522f1f;1:713f2d;1:2a160d;5:-;2:4e2719;1:673728;1:522f1f;1:985c43;1:8e523c;1:522f1f;1:7c4835;1:713f2d;1:522f1f;1:2a160d;4:-;1:4e2719;1:522f1f;1:7c4835;1:8e523c;1:673728;1:522f1f;1:985c43;1:8e523c;1:713f2d;1:673728;1:3f2116;1:2a160d;4:-;1:4e2719;1:713f2d;1:522f1f;1:985c43;2:8e523c;1:522f1f;1:985c43;1:673728;1:3f2116;1:2a160d;4:-;1:4e2719;1:713f2d;1:7c4835;1:985c43;1:522f1f;1:985c43;1:8e523c;1:713f2d;1:522f1f;2:3f2116;1:2a160d;4:-;1:4e2719;1:985c43;1:713f2d;1:7c4835;1:985c43;1:522f1f;1:713f2d;1:7c4835;1:673728;1:3f2116;1:2a160d;6:-;1:4e2719;1:985c43;2:8e523c;1:7c4835;1:673728;2:3f2116;1:2a160d;7:-;2:2a160d;1:522f1f;3:3f2116;2:2a160d;10:-;4:2a160d;23:-"},
bread = {w=16,h=16,d="25:-;4:654b17;10:-;2:654b17;1:8c661e;2:a27924;1:8c661e;1:654b17;8:-;1:654b17;1:8c661e;4:bc8927;1:a27924;1:8c661e;1:3f2e0e;6:-;1:654b17;1:bc8927;1:a27924;2:8c661e;3:bc8927;1:8c661e;1:3f2e0e;5:-;1:654b17;4:bc8927;1:a27924;1:8c661e;1:bc8927;1:a27924;1:8c661e;1:3f2e0e;4:-;1:654b17;6:bc8927;1:a27924;1:bc8927;1:8c661e;1:654b17;1:3f2e0e;3:-;1:654b17;1:8c661e;1:a27924;2:8c661e;4:bc8927;2:8c661e;1:4c3811;1:3f2e0e;3:-;1:654b17;3:bc8927;1:a27924;1:8c661e;2:bc8927;2:8c661e;1:654b17;1:3f2e0e;3:-;1:654b17;1:8c661e;4:bc8927;1:a27924;1:bc8927;2:8c661e;1:654b17;1:3f2e0e;4:-;1:654b17;1:a27924;5:bc8927;2:8c661e;1:654b17;1:3f2e0e;5:-;1:654b17;2:a27924;3:bc8927;2:8c661e;1:654b17;1:3f2e0e;6:-;1:574114;1:8c661e;2:a27924;3:8c661e;1:654b17;1:3f2e0e;7:-;1:574114;1:654b17;4:8c661e;1:654b17;1:3f2e0e;9:-;1:4c3811;3:654b17;1:4c3811;1:3f2e0e;11:-;1:4c3811;3:3f2e0e;9:-"},
apple = {w=16,h=16,d="25:-;1:752802;14:-;1:7e370e;1:542409;14:-;1:752802;12:-;2:9c1017;1:752802;1:542409;2:752802;8:-;1:9c1017;1:b4131e;1:ff969d;1:b4131e;1:542409;1:9c1017;1:dd1725;1:b4131e;2:752802;5:-;1:9c1017;1:b4131e;1:ff1c2b;1:ff5e69;3:ff969d;1:ff5e69;1:ff1c2b;1:b4131e;2:752802;4:-;1:9c1017;1:b4131e;6:ff1c2b;1:dd1725;1:ff1c2b;1:b4131e;1:752802;4:-;1:9c1017;1:b4131e;1:dd1725;1:ff1c2b;1:dd1725;1:ff1c2b;3:dd1725;1:ff1c2b;1:dd1725;1:54090e;4:-;1:752802;2:b4131e;2:dd1725;2:b4131e;1:dd1725;1:b4131e;1:ff1c2b;1:dd1725;1:54090e;4:-;1:752802;5:b4131e;1:dd1725;2:b4131e;1:ff1c2b;1:b4131e;1:54090e;5:-;1:752802;2:b4131e;1:dd1725;3:b4131e;1:dd1725;1:b4131e;1:54090e;6:-;1:752802;1:9c1017;3:b4131e;2:dd1725;1:b4131e;1:9c1017;1:54090e;7:-;1:54090e;1:9c1017;1:b4131e;2:9c1017;1:b4131e;1:9c1017;1:54090e;9:-;1:54090e;3:752802;2:54090e;21:-"},
stick = {w=16,h=16,d="45:-;1:493615;1:281e0b;13:-;1:493615;1:896727;1:281e0b;12:-;1:493615;1:896727;1:281e0b;12:-;1:493615;1:684e1e;1:281e0b;12:-;1:493615;1:896727;1:281e0b;12:-;1:493615;1:684e1e;1:281e0b;12:-;1:493615;1:896727;1:281e0b;12:-;1:493615;1:684e1e;1:281e0b;12:-;1:493615;1:896727;1:281e0b;12:-;1:493615;1:684e1e;1:281e0b;12:-;1:493615;1:896727;1:281e0b;12:-;1:493615;1:896727;1:281e0b;13:-;2:281e0b;28:-"},
coal = {w=16,h=16,d="37:-;4:1c1c1e;11:-;1:1c1c1e;1:2e2e2e;2:323232;1:2e2e2e;1:1c1c1e;9:-;1:1c1c1e;1:252525;1:363636;1:393e46;1:323232;2:252525;1:1c1c1e;8:-;1:1c1c1e;1:363636;1:252525;1:323232;1:2e2e2e;1:323232;1:2e2e2e;1:252525;1:1c1c1e;7:-;1:1c1c1e;2:261e24;1:252525;1:363636;1:393e46;1:363636;1:323232;1:252525;1:1c1c1e;5:-;1:1c1c1e;1:252525;1:2e2e2e;1:252525;1:261e24;1:252525;2:363636;1:2e2e2e;1:252525;1:323232;1:101015;4:-;1:1c1c1e;1:2e2e2e;1:393e46;1:323232;1:252525;3:2e2e2e;1:252525;1:261e24;1:252525;1:101015;4:-;1:1c1c1e;1:252525;3:2e2e2e;3:252525;1:2e2e2e;3:261e24;1:101015;3:-;1:1c1c1e;3:252525;1:261e24;1:252525;1:2e2e2e;1:261e24;1:252525;1:1f1721;1:252525;1:1f1721;1:101015;3:-;1:1c1c1e;1:1f1721;1:261e24;1:252525;5:261e24;1:1f1721;1:261e24;1:1f1721;1:101015;4:-;1:101015;2:1f1721;1:261e24;1:252525;1:1f1721;2:261e24;2:1f1721;1:101015;6:-;1:101015;4:1f1721;4:101015;8:-;4:101015;23:-"},
iron_ingot = {w=16,h=16,d="42:-;2:5e5e5e;11:-;3:5e5e5e;2:a8a8a8;1:727272;7:-;3:5e5e5e;1:a8a8a8;4:d8d8d8;1:a8a8a8;1:727272;3:-;3:5e5e5e;1:a8a8a8;8:d8d8d8;1:a8a8a8;1:727272;1:-;1:5e5e5e;1:ffffff;10:d8d8d8;2:ffffff;1:d8d8d8;1:727272;1:5e5e5e;1:a8a8a8;1:ffffff;6:d8d8d8;3:ffffff;1:d8d8d8;1:727272;1:a8a8a8;1:353535;1:5e5e5e;2:a8a8a8;1:ffffff;2:d8d8d8;3:ffffff;1:d8d8d8;1:828282;2:727272;1:828282;1:a8a8a8;1:353535;1:5e5e5e;3:a8a8a8;2:ffffff;1:d8d8d8;1:828282;4:727272;3:a8a8a8;1:353535;1:5e5e5e;1:828282;2:a8a8a8;1:d8d8d8;1:828282;4:727272;2:a8a8a8;1:828282;2:353535;2:-;1:5e5e5e;1:828282;1:a8a8a8;1:d8d8d8;1:828282;2:727272;2:828282;3:353535;5:-;1:5e5e5e;1:828282;1:a8a8a8;1:828282;1:585858;3:353535;9:-;2:5e5e5e;2:353535;41:-"},
diamond = {w=16,h=16,d="38:-;4:11727a;11:-;1:11727a;3:ffffff;1:d5fff6;1:11727a;9:-;1:11727a;1:ffffff;2:4aedd9;1:a1fbe8;1:d5fff6;1:20c5b5;1:145e53;7:-;1:11727a;1:ffffff;1:4aedd9;2:a1fbe8;1:d5fff6;1:a1fbe8;1:4aedd9;1:20c5b5;1:145e53;6:-;1:11727a;1:ffffff;1:4aedd9;1:ffffff;1:d5fff6;1:ffffff;1:d5fff6;2:4aedd9;1:145e53;5:-;1:11727a;1:ffffff;1:4aedd9;1:ffffff;2:4aedd9;2:a1fbe8;1:1aaaa7;1:20c5b5;1:1aaaa7;1:145e53;4:-;1:11727a;1:ffffff;1:4aedd9;1:d5fff6;1:4aedd9;3:a1fbe8;1:1c919a;1:20c5b5;1:1aaaa7;1:145e53;4:-;1:11727a;2:ffffff;1:20c5b5;3:a1fbe8;1:4aedd9;1:1c919a;2:1aaaa7;1:145e53;4:-;1:11727a;1:d5fff6;2:4aedd9;4:1aaaa7;2:20c5b5;1:1c919a;1:145e53;5:-;1:145e53;1:4aedd9;1:1aaaa7;4:20c5b5;1:1aaaa7;1:20c5b5;1:145e53;6:-;1:145e53;1:2ce0d8;1:1aaaa7;4:20c5b5;1:1aaaa7;1:a1fbe8;1:145e53;7:-;1:145e53;1:1c919a;2:4aedd9;2:a1fbe8;1:20c5b5;1:145e53;9:-;6:145e53;21:-"},
bucket = {w=16,h=16,d="21:-;6:353535;8:-;2:353535;1:727272;3:969696;2:a8a8a8;2:353535;5:-;1:353535;2:727272;3:5f5f5f;3:727272;1:969696;1:727272;1:353535;4:-;1:353535;1:5f5f5f;3:545454;1:5f5f5f;4:727272;1:5f5f5f;1:353535;4:-;3:353535;2:545454;2:5f5f5f;2:727272;3:353535;4:-;1:353535;1:d8d8d8;1:a8a8a8;6:353535;1:727272;1:969696;1:353535;4:-;1:353535;4:d8d8d8;2:a8a8a8;1:969696;2:727272;1:969696;1:353535;4:-;1:353535;2:d8d8d8;1:ffffff;1:d8d8d8;2:a8a8a8;1:969696;2:727272;1:a8a8a8;1:353535;4:-;1:353535;1:a8a8a8;1:d8d8d8;1:ffffff;1:d8d8d8;2:a8a8a8;1:969696;2:727272;1:a8a8a8;1:353535;4:-;1:353535;1:727272;1:d8d8d8;1:ffffff;1:d8d8d8;2:a8a8a8;1:969696;2:727272;1:969696;1:353535;5:-;1:353535;3:d8d8d8;2:a8a8a8;1:969696;1:727272;1:969696;1:353535;6:-;1:353535;1:a8a8a8;2:d8d8d8;1:a8a8a8;2:969696;1:727272;1:969696;1:353535;7:-;1:353535;1:a8a8a8;1:d8d8d8;1:a8a8a8;1:969696;1:727272;1:969696;1:353535;9:-;6:353535;21:-"},
torch = {w=16,h=16,d="103:-;1:ffd800;1:ff8f00;14:-;1:ffff97;1:ffffff;14:-;1:9f7f50;1:6d5736;14:-;1:957546;1:55452e;14:-;1:9f7f50;1:423522;14:-;1:9f7f50;1:55452e;14:-;1:957546;1:55452e;14:-;1:6d5736;1:3d301d;14:-;1:9f7f50;1:3b2e1b;14:-;1:6d5736;1:372a17;7:-"},
ladder = {w=16,h=16,d="2:-;1:967441;1:513d24;8:-;1:967441;1:513d24;3:-;1:7e6237;1:b58d50;1:7e6237;1:967441;1:b58d50;1:967441;4:b58d50;1:967441;1:b58d50;1:7e6237;1:b58d50;2:-;1:67502c;1:7e6237;1:67502c;1:513d24;6:67502c;1:513d24;1:7e6237;2:67502c;3:-;1:513d24;1:3a2f1e;8:-;1:513d24;1:3a2f1e;4:-;1:967441;1:513d24;8:-;1:967441;1:513d24;3:-;2:b58d50;1:7e6237;1:967441;3:b58d50;1:967441;1:b58d50;2:967441;1:b58d50;1:7e6237;1:b58d50;2:-;1:67502c;1:7e6237;1:67502c;1:513d24;6:67502c;1:513d24;1:7e6237;2:67502c;3:-;1:513d24;1:3a2f1e;8:-;1:513d24;1:3a2f1e;4:-;1:967441;1:513d24;8:-;1:967441;1:513d24;3:-;2:b58d50;1:7e6237;1:967441;6:b58d50;1:967441;1:b58d50;2:7e6237;2:-;1:67502c;1:7e6237;1:67502c;1:513d24;6:67502c;1:513d24;1:7e6237;2:67502c;3:-;1:513d24;1:3a2f1e;8:-;1:513d24;1:3a2f1e;4:-;1:967441;1:513d24;8:-;1:967441;1:513d24;3:-;2:b58d50;1:7e6237;1:967441;1:b58d50;1:967441;4:b58d50;1:967441;1:b58d50;1:7e6237;1:b58d50;2:-;1:67502c;1:7e6237;1:67502c;1:513d24;6:67502c;1:513d24;1:7e6237;2:67502c;3:-;1:513d24;1:3a2f1e;8:-;1:513d24;1:3a2f1e;2:-"},
}
local BTEX = {
stone = {w=16,h=16,d="4:8f8f8f;1:7f7f7f;2:747474;1:7f7f7f;1:747474;1:686868;2:747474;6:7f7f7f;1:747474;1:7f7f7f;1:747474;6:7f7f7f;2:686868;1:747474;1:7f7f7f;1:747474;1:7f7f7f;1:747474;2:686868;3:747474;1:686868;3:747474;7:7f7f7f;2:8f8f8f;1:7f7f7f;1:8f8f8f;2:7f7f7f;2:8f8f8f;3:7f7f7f;4:747474;2:7f7f7f;3:747474;1:7f7f7f;1:747474;1:7f7f7f;4:8f8f8f;1:747474;3:7f7f7f;1:8f8f8f;7:7f7f7f;2:747474;1:686868;1:747474;1:686868;1:747474;1:8f8f8f;1:747474;2:7f7f7f;3:8f8f8f;1:747474;2:8f8f8f;3:747474;4:7f7f7f;2:747474;2:686868;1:747474;1:686868;2:747474;2:7f7f7f;3:747474;3:7f7f7f;3:8f8f8f;1:7f7f7f;1:8f8f8f;2:7f7f7f;3:8f8f8f;5:7f7f7f;1:747474;2:7f7f7f;1:8f8f8f;3:7f7f7f;3:8f8f8f;2:7f7f7f;4:8f8f8f;1:7f7f7f;1:686868;1:7f7f7f;1:747474;1:7f7f7f;2:747474;2:686868;1:747474;1:7f7f7f;1:747474;2:7f7f7f;3:747474;5:7f7f7f;2:8f8f8f;5:7f7f7f;2:8f8f8f;1:7f7f7f;1:8f8f8f;1:7f7f7f;3:747474;1:7f7f7f;1:8f8f8f;1:7f7f7f;2:747474;2:7f7f7f;2:686868;1:747474;1:686868;1:747474;2:8f8f8f;1:7f7f7f;2:747474;2:7f7f7f;3:747474;2:7f7f7f;3:747474;1:8f8f8f;1:7f7f7f;2:747474;9:7f7f7f;4:8f8f8f;6:7f7f7f;2:747474;1:7f7f7f;2:8f8f8f;2:7f7f7f;1:747474;2:7f7f7f"},
dirt = {w=16,h=16,d="1:b9855c;2:966c4a;2:79553a;1:b9855c;2:966c4a;2:79553a;1:593d29;2:79553a;1:b9855c;1:79553a;1:b9855c;1:79553a;1:966c4a;1:593d29;2:79553a;1:966c4a;1:878787;1:593d29;1:79553a;1:b9855c;1:966c4a;1:79553a;1:b9855c;1:966c4a;2:593d29;1:b9855c;2:79553a;1:593d29;1:b9855c;3:79553a;1:b9855c;3:79553a;2:593d29;1:b9855c;1:79553a;1:966c4a;1:6c6c6c;1:b9855c;1:79553a;1:966c4a;1:593d29;1:79553a;1:b9855c;2:966c4a;1:79553a;1:966c4a;1:79553a;1:b9855c;1:966c4a;1:79553a;1:966c4a;1:79553a;1:966c4a;1:b9855c;1:593d29;1:966c4a;2:79553a;1:966c4a;1:593d29;1:79553a;1:6c6c6c;1:79553a;1:966c4a;1:593d29;2:79553a;1:593d29;2:966c4a;1:79553a;1:966c4a;3:593d29;2:79553a;1:593d29;3:79553a;2:b9855c;3:79553a;1:878787;2:79553a;2:b9855c;1:79553a;2:b9855c;1:79553a;1:966c4a;1:79553a;1:966c4a;2:79553a;2:b9855c;2:966c4a;2:79553a;1:966c4a;1:593d29;2:966c4a;2:79553a;3:966c4a;2:79553a;1:966c4a;1:79553a;1:966c4a;1:79553a;1:593d29;1:79553a;2:966c4a;3:79553a;1:593d29;2:79553a;1:966c4a;1:593d29;2:79553a;2:593d29;5:79553a;2:b9855c;1:79553a;1:966c4a;1:79553a;1:966c4a;1:79553a;2:b9855c;1:79553a;1:b9855c;1:966c4a;1:593d29;2:b9855c;1:593d29;2:966c4a;1:878787;1:79553a;1:966c4a;2:79553a;2:966c4a;1:b9855c;1:79553a;1:966c4a;1:6c6c6c;2:966c4a;1:79553a;1:593d29;1:966c4a;1:79553a;1:593d29;1:79553a;1:593d29;1:966c4a;1:79553a;2:966c4a;1:b9855c;7:79553a;2:b9855c;1:79553a;1:966c4a;2:79553a;1:745844;1:79553a;2:966c4a;1:79553a;1:593d29;1:b9855c;1:593d29;1:79553a;1:b9855c;3:966c4a;1:79553a;1:593d29;1:b9855c;1:79553a;1:593d29;1:79553a;1:593d29;2:b9855c;1:79553a;1:966c4a;2:79553a;3:966c4a;1:79553a;1:b9855c;2:966c4a;1:79553a;1:878787;1:79553a;2:966c4a;2:79553a;2:966c4a;1:79553a;1:593d29"},
cobble = {w=16,h=16,d="1:6e6d6d;1:616161;2:a6a6a6;1:525252;2:616161;1:a6a6a6;1:b5b5b5;1:a6a6a6;1:888788;1:616161;1:888788;1:b5b5b5;1:a6a6a6;1:888788;1:616161;1:a6a6a6;1:b5b5b5;2:888788;1:525252;2:b5b5b5;1:a6a6a6;2:888788;1:525252;1:616161;1:888788;1:6e6d6d;1:888788;1:616161;1:a6a6a6;1:888788;1:a6a6a6;1:6e6d6d;1:616161;1:a6a6a6;2:888788;1:a6a6a6;1:6e6d6d;1:616161;1:525252;1:616161;1:888788;1:6e6d6d;2:616161;1:888788;1:6e6d6d;2:616161;1:888788;1:6e6d6d;1:888788;1:6e6d6d;1:616161;1:888788;1:a6a6a6;1:888788;1:616161;2:525252;1:6e6d6d;1:616161;1:888788;1:b5b5b5;1:a6a6a6;1:616161;1:888788;2:616161;1:b5b5b5;3:a6a6a6;1:888788;1:616161;1:b5b5b5;1:6e6d6d;1:a6a6a6;1:b5b5b5;2:888788;1:6e6d6d;1:616161;1:525252;2:888788;1:b5b5b5;1:a6a6a6;1:888788;1:6e6d6d;1:888788;1:a6a6a6;1:888788;1:616161;1:888788;1:a6a6a6;2:888788;1:6e6d6d;2:616161;1:6e6d6d;1:a6a6a6;1:888788;1:6e6d6d;1:616161;1:b5b5b5;2:888788;2:6e6d6d;2:888788;1:6e6d6d;1:616161;1:888788;1:b5b5b5;1:a6a6a6;1:616161;1:6e6d6d;1:888788;1:616161;1:888788;1:6e6d6d;1:616161;1:b5b5b5;1:a6a6a6;2:6e6d6d;1:616161;1:888788;1:b5b5b5;3:888788;2:616161;1:525252;1:6e6d6d;1:616161;1:b5b5b5;1:a6a6a6;1:888788;1:6e6d6d;1:888788;2:6e6d6d;2:888788;1:616161;1:6e6d6d;1:616161;1:888788;1:a6a6a6;1:616161;1:888788;1:6e6d6d;1:888788;1:6e6d6d;1:888788;2:616161;1:525252;1:616161;2:6e6d6d;1:616161;1:525252;2:a6a6a6;1:b5b5b5;1:888788;2:6e6d6d;2:616161;1:6e6d6d;1:888788;1:b5b5b5;1:a6a6a6;2:616161;1:525252;1:888788;2:b5b5b5;1:888788;1:6e6d6d;1:888788;1:b5b5b5;1:a6a6a6;1:6e6d6d;1:616161;1:b5b5b5;1:a6a6a6;1:888788;1:a6a6a6;1:6e6d6d;1:616161;2:888788;1:6e6d6d;1:888788;1:616161;1:b5b5b5;1:a6a6a6;2:888788;1:616161;1:a6a6a6;1:888788;1:6e6d6d;2:888788;1:6e6d6d;2:616161;1:888788;1:6e6d6d;2:a6a6a6;1:888788;1:6e6d6d;1:888788;1:6e6d6d;1:616161;1:6e6d6d;2:888788;1:6e6d6d;1:616161;1:a6a6a6;1:888788;3:616161;1:888788;2:616161;1:6e6d6d;1:888788;1:6e6d6d;1:616161;1:6e6d6d;2:616161;1:888788;1:b5b5b5;1:a6a6a6;1:888788;1:6e6d6d"},
planks = {w=16,h=16,d="1:b8945f;1:af8f55;1:b8945f;5:c29d62;1:b8945f;5:c29d62;1:b8945f;1:967441;2:b8945f;2:af8f55;1:967441;1:9f844d;1:af8f55;3:b8945f;2:af8f55;2:b8945f;2:9f844d;1:af8f55;3:b8945f;1:af8f55;1:b8945f;1:af8f55;4:9f844d;2:af8f55;2:b8945f;2:967441;2:7e6237;2:967441;1:7e6237;2:67502c;2:7e6237;1:67502c;1:7e6237;2:67502c;1:7e6237;1:67502c;1:b8945f;1:c29d62;1:9f844d;4:c29d62;1:9f844d;3:c29d62;1:b8945f;2:af8f55;1:9f844d;1:b8945f;1:af8f55;2:b8945f;1:af8f55;1:9f844d;1:af8f55;1:9f844d;1:967441;1:9f844d;2:af8f55;4:b8945f;1:af8f55;2:9f844d;1:af8f55;1:b8945f;3:af8f55;1:967441;3:b8945f;2:af8f55;3:9f844d;2:67502c;2:7e6237;1:967441;1:7e6237;4:67502c;3:7e6237;1:967441;1:7e6237;1:67502c;1:b8945f;2:c29d62;1:b8945f;2:af8f55;8:c29d62;1:b8945f;1:9f844d;1:b8945f;1:af8f55;4:b8945f;1:af8f55;3:9f844d;1:af8f55;1:9f844d;1:af8f55;2:9f844d;1:967441;1:c29d62;1:b8945f;2:af8f55;4:9f844d;4:af8f55;2:9f844d;1:b8945f;1:9f844d;2:67502c;1:7e6237;2:967441;1:7e6237;3:67502c;1:7e6237;1:967441;2:7e6237;3:67502c;1:c29d62;1:9f844d;1:b8945f;2:c29d62;2:b8945f;1:9f844d;3:c29d62;1:9f844d;1:c29d62;1:b8945f;2:c29d62;2:af8f55;2:b8945f;2:9f844d;1:af8f55;2:9f844d;2:b8945f;1:af8f55;1:b8945f;4:af8f55;2:9f844d;1:af8f55;1:b8945f;1:af8f55;1:9f844d;1:967441;2:b8945f;1:af8f55;5:9f844d;1:67502c;2:7e6237;2:67502c;1:7e6237;3:967441;1:7e6237;1:67502c;1:7e6237;4:67502c"},
log = {w=16,h=16,d="1:745a36;1:4c3d26;1:917142;2:745a36;1:382b18;1:917142;2:745a36;1:382b18;1:745a36;1:917142;1:4c3d26;1:917142;1:745a36;1:5f4a2b;1:745a36;1:4c3d26;1:987849;1:5f4a2b;1:745a36;1:382b18;1:987849;1:5f4a2b;1:745a36;1:382b18;1:745a36;1:917142;1:4c3d26;2:745a36;1:5f4a2b;1:745a36;1:382b18;2:5f4a2b;1:745a36;1:382b18;1:987849;1:5f4a2b;1:745a36;1:4c3d26;1:745a36;2:4c3d26;2:745a36;1:5f4a2b;1:917142;1:382b18;1:745a36;1:5f4a2b;1:745a36;1:4c3d26;1:745a36;1:5f4a2b;1:745a36;1:5f4a2b;1:745a36;1:382b18;1:4c3d26;1:745a36;1:917142;1:5f4a2b;1:917142;1:4c3d26;1:745a36;1:5f4a2b;1:745a36;1:382b18;1:745a36;1:5f4a2b;1:987849;1:5f4a2b;1:745a36;1:5f4a2b;1:745a36;1:4c3d26;1:917142;1:745a36;1:917142;1:745a36;1:4c3d26;1:745a36;1:917142;1:4c3d26;1:745a36;1:4c3d26;1:987849;1:5f4a2b;1:917142;1:4c3d26;1:745a36;1:4c3d26;1:917142;1:745a36;1:5f4a2b;1:745a36;1:4c3d26;1:745a36;1:917142;2:5f4a2b;1:745a36;1:917142;1:745a36;1:917142;2:745a36;1:4c3d26;1:917142;1:745a36;1:5f4a2b;1:745a36;1:382b18;1:745a36;1:917142;1:745a36;1:5f4a2b;1:917142;2:745a36;1:917142;1:5f4a2b;1:745a36;1:5f4a2b;1:917142;2:745a36;1:4c3d26;1:382b18;1:987849;2:745a36;1:5f4a2b;1:917142;1:745a36;1:5f4a2b;1:917142;1:5f4a2b;1:917142;1:5f4a2b;1:917142;3:745a36;1:4c3d26;1:987849;2:745a36;1:5f4a2b;2:745a36;1:5f4a2b;1:917142;1:4c3d26;1:917142;1:745a36;1:382b18;4:745a36;1:917142;1:745a36;1:5f4a2b;1:745a36;1:382b18;1:745a36;1:5f4a2b;1:745a36;1:4c3d26;1:917142;1:745a36;1:382b18;2:745a36;1:4c3d26;1:745a36;1:917142;1:745a36;1:5f4a2b;1:745a36;1:382b18;1:987849;2:745a36;1:382b18;1:987849;1:745a36;1:4c3d26;1:745a36;1:987849;1:4c3d26;2:745a36;1:917142;1:5f4a2b;1:917142;1:382b18;1:987849;1:5f4a2b;1:745a36;1:382b18;2:745a36;1:5f4a2b;1:745a36;1:987849;1:745a36;1:4c3d26;1:745a36;1:917142;2:745a36;1:4c3d26;1:917142;1:5f4a2b;1:745a36;1:4c3d26;4:745a36;1:917142;1:745a36;1:4c3d26;1:917142;2:745a36;1:917142;1:382b18;1:745a36;1:4c3d26;1:745a36;2:4c3d26;1:917142;2:745a36;1:917142;1:745a36;1:4c3d26;1:917142;1:4c3d26;1:745a36;1:917142;1:4c3d26;1:745a36;1:4c3d26;2:745a36;1:4c3d26;1:917142;1:745a36;1:5f4a2b"},
log_top = {w=16,h=16,d="1:5f4a2b;1:4c3d26;1:5f4a2b;1:745a36;1:5f4a2b;1:4c3d26;2:5f4a2b;1:745a36;1:4c3d26;2:5f4a2b;1:4c3d26;3:5f4a2b;1:4c3d26;4:b8945f;1:af8f55;1:b8945f;1:af8f55;1:c29d62;2:af8f55;4:b8945f;1:4c3d26;1:5f4a2b;1:b8945f;2:7e6237;2:967441;1:9f844d;1:967441;4:9f844d;2:967441;1:c29d62;2:5f4a2b;1:b8945f;1:7e6237;2:c29d62;4:b8945f;1:af8f55;3:b8945f;1:967441;1:b8945f;2:5f4a2b;1:af8f55;1:967441;1:b8945f;8:af8f55;1:b8945f;1:9f844d;1:af8f55;1:5f4a2b;1:4c3d26;1:b8945f;1:9f844d;1:b8945f;1:af8f55;2:967441;2:9f844d;2:967441;1:af8f55;1:b8945f;1:967441;1:af8f55;1:4c3d26;1:5f4a2b;1:af8f55;1:967441;2:af8f55;1:7e6237;4:af8f55;1:967441;2:af8f55;1:967441;1:b8945f;2:5f4a2b;1:af8f55;1:9f844d;1:b8945f;1:af8f55;1:967441;1:af8f55;2:9f844d;1:af8f55;1:9f844d;1:af8f55;1:b8945f;1:9f844d;1:af8f55;2:5f4a2b;1:af8f55;1:9f844d;1:b8945f;1:af8f55;1:967441;1:af8f55;1:9f844d;1:967441;1:af8f55;1:967441;1:af8f55;1:b8945f;1:967441;1:af8f55;1:5f4a2b;1:4c3d26;1:af8f55;1:9f844d;1:b8945f;1:af8f55;1:967441;4:af8f55;1:9f844d;2:af8f55;1:967441;1:af8f55;1:4c3d26;1:5f4a2b;1:af8f55;1:967441;1:b8945f;1:af8f55;2:967441;1:7e6237;1:967441;2:9f844d;1:af8f55;1:b8945f;1:9f844d;1:af8f55;2:5f4a2b;1:af8f55;1:9f844d;1:b8945f;8:af8f55;1:b8945f;1:967441;1:af8f55;1:5f4a2b;1:4c3d26;1:b8945f;1:9f844d;2:b8945f;1:af8f55;5:b8945f;1:c29d62;1:b8945f;1:967441;1:af8f55;1:4c3d26;1:5f4a2b;1:b8945f;1:9f844d;1:967441;1:9f844d;9:967441;1:b8945f;2:5f4a2b;3:b8945f;2:af8f55;1:b8945f;2:af8f55;1:c29d62;2:af8f55;3:b8945f;2:5f4a2b;1:4c3d26;3:5f4a2b;1:4c3d26;2:5f4a2b;1:745a36;1:4c3d26;2:5f4a2b;1:4c3d26;1:745a36;2:5f4a2b"},
grass_top = {w=16,h=16,d="1:546d33;1:6e9044;1:536c33;2:4c632e;1:516931;1:485e2c;1:4f6730;1:597537;1:556f34;1:4e6630;1:4c642f;1:4d652f;1:5e7b3a;1:3f5327;1:506831;1:546e34;1:4f6730;1:5a7637;1:556f34;1:577135;1:485e2c;1:577135;1:49602d;1:485e2c;1:607d3a;1:5e7b39;1:536c33;1:6e9044;1:4f6730;1:4c642f;1:4f6730;1:5c7838;1:506831;1:475c2b;1:4b612e;1:4d652f;1:4d642f;2:516a32;1:546d33;1:5a7537;1:5f7c3a;1:62803c;1:4c642f;1:435829;1:485e2c;1:67863f;1:435729;1:4b622e;1:4e6630;1:556f34;1:526b32;1:577135;1:475c2b;1:536c32;1:485e2c;1:4a612d;1:506831;1:556f34;1:516931;1:4f6730;1:5e7b3a;1:475c2b;1:5c7838;1:4a612d;1:62803c;1:4a612d;1:617f3c;1:62803c;1:4d642f;1:617f3c;1:698940;1:425628;1:485e2c;1:5e7b3a;1:617e3b;1:475d2b;1:4d642f;1:506831;1:577135;1:567035;1:445829;1:5e7b39;1:495f2d;1:556f34;1:546e34;1:587236;1:4c642f;1:546e34;1:4d642f;1:4a612d;1:445829;1:4d642f;1:506931;1:546d33;1:475d2b;1:587336;1:5d7a39;1:516a32;1:536c32;1:4a612d;1:4e6630;1:485e2c;1:4b612e;1:4c642f;1:66863f;1:617f3c;1:526b32;1:5e7b3a;1:556f34;2:516931;1:4c642f;1:597436;1:4f6730;1:516a32;1:465b2b;1:5d7939;1:4b612e;1:556f34;1:62803c;1:4c642f;1:495f2d;1:516931;1:5a7637;1:485e2c;1:607d3a;1:5e7b3a;1:587236;1:67863f;1:607e3b;1:617f3c;1:495f2d;1:62803c;1:587336;1:65843e;1:607e3b;1:49602d;1:536c32;1:4b622e;1:536c33;1:597537;1:475d2b;1:556f34;1:49602d;1:68873f;1:506831;1:4f6730;1:567035;1:607e3b;1:485e2c;1:4c642f;1:526b32;1:536c32;1:607d3a;1:506931;1:65843e;1:516931;1:495f2d;1:587236;1:597537;1:556f34;1:5d7a39;1:49602d;1:67863f;1:506931;1:536c33;1:6d8e43;1:44592a;1:5e7b3a;1:4a612d;1:516931;1:4d642f;1:556f34;1:516931;1:4b612e;1:62803c;1:4c632e;1:5c7838;1:556f34;1:4b612e;1:536c32;1:4d652f;1:556f34;1:536c32;1:4f6730;1:455b2a;1:65843e;1:485e2c;1:475c2b;1:4e6630;1:698940;1:556f34;1:495f2d;1:4e6630;1:577135;1:526b32;1:4b622e;1:455a2a;1:4e6630;1:526b32;1:4e6630;1:475c2b;1:5a7537;1:5d7a39;1:44592a;1:556f34;1:495f2d;1:5f7c3a;1:435729;1:536c32;1:475c2b;1:577135;1:495f2d;1:6e9044;1:5b7738;1:536c33;1:5f7c3a;1:587236;1:5a7637;1:4d642f;1:5f7c3a;1:62803c;1:5c7838;1:5b7738;1:6d8e43;1:455b2a;1:65843e;1:617e3b;1:546d33;1:536c33;1:475d2b;2:546e34;1:4c642f;1:607d3a;1:597436;1:4f6730;1:44592a;1:4b622e;1:556f34;1:4d642f;1:4d652f;1:5d7939;1:567035;1:546d33;1:536c33;1:506931;1:6c8d42;1:465b2b;1:607d3a;1:4b612e;1:516a32;1:4d642f;1:597537"},
grass_side = {w=16,h=16,d="1:607d3a;1:516a32;1:556f34;1:4f6730;1:607d3a;1:516a32;1:607d3a;2:556f34;1:5a7537;1:607d3a;1:5a7537;1:65833e;1:495f2d;1:5a7537;1:556f34;1:607d3a;1:4f6730;1:607d3a;1:516a32;1:65833e;1:593d29;1:607d3a;1:49602d;1:65833e;1:556f34;1:607d3a;1:536c33;1:607d3a;1:4f6730;1:607d3a;1:4f6730;1:556f34;1:593d29;1:65833e;1:4b612e;1:607d3a;1:593d29;1:516a32;1:593d29;1:607d3a;1:5a7537;1:556f34;1:62803c;1:593d29;1:435829;1:556f34;2:593d29;1:6c6c6c;2:593d29;1:526b32;3:593d29;1:485e2c;1:593d29;1:506831;1:593d29;1:79553a;2:593d29;1:79553a;1:966c4a;1:79553a;1:966c4a;1:b9855c;1:593d29;1:966c4a;2:79553a;3:593d29;1:6c6c6c;1:79553a;1:966c4a;1:593d29;2:79553a;1:593d29;2:966c4a;1:79553a;1:966c4a;3:593d29;2:79553a;1:593d29;3:79553a;2:b9855c;3:79553a;1:878787;2:79553a;2:b9855c;1:79553a;2:b9855c;1:79553a;1:966c4a;1:79553a;1:966c4a;2:79553a;2:b9855c;2:966c4a;2:79553a;1:966c4a;1:593d29;2:966c4a;2:79553a;3:966c4a;2:79553a;1:966c4a;1:79553a;1:966c4a;1:79553a;1:593d29;1:79553a;2:966c4a;3:79553a;1:593d29;2:79553a;1:966c4a;1:593d29;2:79553a;2:593d29;5:79553a;2:b9855c;1:79553a;1:966c4a;1:79553a;1:966c4a;1:79553a;2:b9855c;1:79553a;1:b9855c;1:966c4a;1:593d29;2:b9855c;1:593d29;2:966c4a;1:878787;1:79553a;1:966c4a;2:79553a;2:966c4a;1:b9855c;1:79553a;1:966c4a;1:6c6c6c;2:966c4a;1:79553a;1:593d29;1:966c4a;1:79553a;1:593d29;1:79553a;1:593d29;1:966c4a;1:79553a;2:966c4a;1:b9855c;7:79553a;2:b9855c;1:79553a;1:966c4a;2:79553a;1:745844;1:79553a;2:966c4a;1:79553a;1:593d29;1:b9855c;1:593d29;1:79553a;1:b9855c;3:966c4a;1:79553a;1:593d29;1:b9855c;1:79553a;1:593d29;1:79553a;1:593d29;2:b9855c;1:79553a;1:966c4a;2:79553a;3:966c4a;1:79553a;1:b9855c;2:966c4a;1:79553a;1:878787;1:79553a;2:966c4a;2:79553a;2:966c4a;1:79553a;1:593d29"},
ct_top = {w=16,h=16,d="1:19140c;2:0e0b06;1:19140c;1:41230e;6:733920;1:41230e;1:1a150d;1:0e0b06;1:1a150d;1:19140c;1:0e0b06;2:bc9862;1:41230e;1:9e5932;6:ae693c;1:9e5932;1:41230e;2:bc9862;2:0e0b06;1:bc9862;1:41230e;10:ae693c;1:41230e;1:bc9862;1:0e0b06;1:19140c;1:41230e;1:ae693c;1:553824;1:4b2b18;3:553824;4:4b2b18;1:553824;1:ae693c;1:41230e;1:19140c;1:41230e;1:9e5932;1:ae693c;1:553824;1:9e5932;1:ae693c;1:553824;2:ae693c;1:4b2b18;2:ae693c;1:553824;1:ae693c;1:9e5932;1:41230e;1:733920;2:ae693c;1:553824;2:ae693c;1:4b2b18;1:9e5932;1:ae693c;1:553824;1:9e5932;1:ae693c;1:553824;2:ae693c;2:733920;2:ae693c;2:553824;1:4b2b18;2:553824;1:4b2b18;2:553824;1:4b2b18;1:553824;2:ae693c;2:733920;2:ae693c;1:553824;2:ae693c;1:553824;2:ae693c;1:553824;2:ae693c;1:553824;2:ae693c;2:733920;2:ae693c;1:553824;2:ae693c;1:553824;2:ae693c;1:553824;2:ae693c;1:553824;2:ae693c;2:733920;2:ae693c;3:4b2b18;1:553824;2:4b2b18;2:553824;1:4b2b18;1:553824;2:ae693c;2:733920;2:ae693c;1:4b2b18;1:9e5932;1:ae693c;1:4b2b18;1:ae693c;1:9e5932;1:4b2b18;2:ae693c;1:553824;2:ae693c;1:733920;1:41230e;1:9e5932;1:ae693c;1:553824;1:9e5932;1:ae693c;1:4b2b18;2:ae693c;1:4b2b18;1:9e5932;1:ae693c;1:553824;1:ae693c;1:9e5932;1:41230e;1:1a150d;1:41230e;1:ae693c;2:553824;1:4b2b18;7:553824;1:ae693c;1:41230e;1:1a150d;1:0e0b06;1:bc9862;1:41230e;10:ae693c;1:41230e;1:bc9862;1:0e0b06;1:1a150d;2:bc9862;1:41230e;1:9e5932;6:ae693c;1:9e5932;1:41230e;2:bc9862;1:1a150d;1:19140c;1:1a150d;1:0e0b06;1:1a150d;1:41230e;6:733920;1:41230e;1:19140c;2:0e0b06;1:19140c"},
ct_front = {w=16,h=16,d="1:19140c;1:af8f55;1:b8945f;2:c29d62;1:382116;1:733920;2:4b2b18;1:733920;1:382116;3:c29d62;1:b8945f;2:19140c;1:b8945f;2:af8f55;1:967441;1:9f844d;1:382116;2:4b2b18;1:382116;2:af8f55;2:b8945f;1:9f844d;2:19140c;3:b8945f;1:af8f55;1:b8945f;1:af8f55;2:382116;2:9f844d;2:af8f55;2:b8945f;2:19140c;2:7e6237;2:967441;1:7e6237;1:67502c;2:1b160d;1:7e6237;1:67502c;3:41230e;1:7e6237;2:19140c;1:c29d62;1:9f844d;4:c29d62;2:4b2b18;2:c29d62;1:281e0b;1:af8f55;1:281e0b;1:9f844d;2:19140c;2:b8945f;1:41230e;1:9f844d;1:af8f55;1:9f844d;2:382116;2:af8f55;3:281e0b;1:b8945f;2:19140c;1:9f844d;1:af8f55;1:281e0b;3:af8f55;2:382116;2:b8945f;3:b5b5b5;1:9f844d;2:19140c;1:67502c;1:7e6237;1:281e0b;1:967441;1:7e6237;1:67502c;2:1b160d;1:67502c;1:7e6237;1:ffffff;2:d8d8d8;1:7e6237;2:19140c;2:c29d62;1:281e0b;2:af8f55;1:c29d62;2:4b2b18;2:c29d62;1:ffffff;2:d8d8d8;1:b8945f;2:19140c;1:af8f55;3:d8d8d8;1:b8945f;1:af8f55;2:382116;1:9f844d;1:af8f55;1:9f844d;2:d8d8d8;1:9f844d;2:19140c;1:b8945f;1:b5b5b5;1:d8d8d8;1:ffffff;2:9f844d;2:382116;3:af8f55;1:ffffff;1:d8d8d8;1:b8945f;2:19140c;1:67502c;1:7e6237;2:967441;1:7e6237;1:67502c;2:110e08;1:7e6237;1:967441;2:7e6237;1:d8d8d8;1:67502c;2:19140c;1:9f844d;1:b8945f;2:c29d62;2:b8945f;2:4b2b18;2:c29d62;1:9f844d;1:c29d62;1:ffffff;1:c29d62;2:19140c;1:af8f55;2:b8945f;2:9f844d;1:af8f55;2:382116;2:b8945f;1:af8f55;1:b8945f;2:af8f55;2:19140c;2:9f844d;1:af8f55;1:b8945f;1:af8f55;1:9f844d;2:382116;1:b8945f;1:af8f55;4:9f844d;1:19140c;1:1b160d;2:7e6237;2:67502c;1:7e6237;1:967441;1:19140c;1:1b160d;1:7e6237;1:67502c;1:7e6237;3:67502c;1:1b160d"},
ct_side = {w=16,h=16,d="1:19140c;1:af8f55;1:b8945f;2:c29d62;1:382116;1:733920;2:4b2b18;1:733920;1:382116;3:c29d62;1:b8945f;2:19140c;1:b8945f;2:af8f55;1:967441;1:9f844d;1:382116;2:4b2b18;1:382116;2:af8f55;2:b8945f;1:9f844d;2:19140c;3:b8945f;1:af8f55;1:b8945f;1:af8f55;2:262012;2:9f844d;2:af8f55;2:b8945f;2:19140c;2:7e6237;2:967441;1:7e6237;1:67502c;2:1b160d;1:7e6237;1:67502c;1:7e6237;2:67502c;1:7e6237;2:19140c;1:c29d62;1:9f844d;4:c29d62;2:4b2b18;2:c29d62;1:b8945f;2:af8f55;1:9f844d;2:19140c;2:b8945f;1:41230e;1:9f844d;1:41230e;1:9f844d;2:382116;2:af8f55;4:b8945f;2:19140c;1:9f844d;1:af8f55;1:281e0b;1:af8f55;1:281e0b;1:af8f55;2:382116;2:b8945f;2:af8f55;2:9f844d;2:19140c;1:67502c;2:7e6237;1:d8d8d8;1:7e6237;1:67502c;2:1b160d;1:67502c;3:7e6237;1:967441;1:7e6237;2:19140c;2:c29d62;1:d8d8d8;1:af8f55;1:d8d8d8;1:c29d62;2:4b2b18;5:c29d62;1:b8945f;2:19140c;1:af8f55;1:b8945f;1:b5b5b5;1:b8945f;1:b5b5b5;1:af8f55;2:382116;1:9f844d;1:af8f55;1:9f844d;1:af8f55;2:9f844d;2:19140c;1:b8945f;2:af8f55;3:9f844d;2:382116;3:af8f55;2:9f844d;1:b8945f;2:19140c;1:67502c;1:7e6237;2:967441;1:7e6237;1:67502c;2:110e08;1:7e6237;1:967441;2:7e6237;2:67502c;2:19140c;1:9f844d;1:b8945f;2:c29d62;2:b8945f;2:4b2b18;2:c29d62;1:9f844d;1:c29d62;1:b8945f;1:c29d62;2:19140c;1:af8f55;2:b8945f;2:9f844d;1:af8f55;2:382116;2:b8945f;1:af8f55;1:b8945f;2:af8f55;2:19140c;2:9f844d;1:af8f55;1:b8945f;1:af8f55;1:9f844d;2:382116;1:b8945f;1:af8f55;4:9f844d;1:19140c;1:1b160d;2:7e6237;2:67502c;1:7e6237;1:967441;1:19140c;1:1b160d;1:7e6237;1:67502c;1:7e6237;3:67502c;1:1b160d"},
}
local PALETTE = {
A = Color3.fromRGB(43, 30, 13),
B = Color3.fromRGB(51, 36, 17),
C = Color3.fromRGB(129, 83, 57),
D = Color3.fromRGB(63, 42, 21),
E = Color3.fromRGB(118, 75, 51),
F = Color3.fromRGB(144, 89, 63),
G = Color3.fromRGB(143, 94, 62),
H = Color3.fromRGB(73, 37, 16),
I = Color3.fromRGB(36, 24, 8),
J = Color3.fromRGB(155, 99, 73),
K = Color3.fromRGB(179, 121, 94),
L = Color3.fromRGB(183, 131, 107),
M = Color3.fromRGB(170, 114, 89),
N = Color3.fromRGB(52, 37, 18),
O = Color3.fromRGB(255, 255, 255),
P = Color3.fromRGB(82, 61, 137),
Q = Color3.fromRGB(106, 64, 48),
R = Color3.fromRGB(148, 96, 62),
S = Color3.fromRGB(119, 66, 53),
T = Color3.fromRGB(66, 29, 10),
U = Color3.fromRGB(38, 26, 10),
V = Color3.fromRGB(58, 49, 137),
W = Color3.fromRGB(55, 55, 55),
X = Color3.fromRGB(40, 40, 40),
Y = Color3.fromRGB(0, 204, 204),
Z = Color3.fromRGB(0, 175, 175),
a = Color3.fromRGB(0, 164, 164),
b = Color3.fromRGB(10, 188, 188),
c = Color3.fromRGB(65, 53, 155),
d = Color3.fromRGB(70, 58, 165),
e = Color3.fromRGB(4, 149, 149),
f = Color3.fromRGB(0, 127, 127),
g = Color3.fromRGB(5, 136, 136),
h = Color3.fromRGB(0, 104, 104),
i = Color3.fromRGB(3, 122, 122),
j = Color3.fromRGB(74, 74, 74),
k = Color3.fromRGB(63, 63, 63),
l = Color3.fromRGB(85, 85, 85)
}
local SKIN = {
"........AABAABBACCCCCCCC........................................",
"........ABDABDBACCEEEECC........................................",
"........ADBABABAFEEEEEEF........................................",
"........ABABBBABFEEEEEEF........................................",
"........AAABDABDFCEEEECF........................................",
"........BBAABADDCFCCCCFG........................................",
"........BDBABBBBGCGCGCGC........................................",
"........ABBADBAACGHHHHCG........................................",
"AABBAIAABBDDDDBAAAIABBAAABAAIABA................................",
"ABAAIIBBIBBDDBDBDBIIAABAABDAIIBD................................",
"BDBAABDBAJKLKMJNBDBAADBBABBAAIBB................................",
"AIABBIAAJMKKMMMJAAIBBAIABBABAAAB................................",
"ABABAFJIMOPMJPOMIJFABABABIIBBAIB................................",
"BBABIJJJJMMQQMMJJJJIBABBAIIABIIA................................",
"IAIFJGCRFGHSSTGCRCGJFIAIAIIAAIIA................................",
"CFFJGJGCRCTHTHCGFGJGJFFCCCUUUUCC................................",
"....VVVVWWXX........YMJFFJMYVVVVVVVV........ZZZaJMMM............",
"....VVVVXXWW........YJFFFFJYVVVVVVVV........ZZZaMMJF............",
"....VVVVWWXX........YJFFFFJYVVVVVVVV........ZbZaMMMM............",
"....VVVVXXWW........YMJFFJMYVVVVVVVV........aZZaJMJF............",
"ccVcdddVcVcccddVeeeeZaMJJMaZeeeeZaaeeeaZZZZaaaZZffffZZZZ........",
"cVVcdddVcVccddddeggeZZeMMeZZeggeZZZZaZZZZZaaaZZZfhhfZaaZ........",
"cVccdddccVccddddgiigaZaZgaZagiigeZZZeZZeZaaZZZaefhhfZZaa........",
"cVccdddccVccdccdiiiieZZZeZZeiiiiaZZaeZZaffffffffhhhhffff........",
"cVcccVVcccVcVVVViiiigaZZeZZgiiiiaZZeaZZaJJJFJFJFFFFFFJJJ........",
"cVccdccdcVVccVVcgiiggaaZeZZggiigeZZeZZZeMMMJMJMMJFJJMMMM........",
"cVccddddcVccddddggggeZZaeaZgggggeZZaZZaeJMMMMJMJJFJJMJJM........",
"ccccddddcVccddddeggegZZeaaaeeggeeZZaZaaeJMMMMMMJJFJFMMMM........",
"VVccddccccVVccccegeegeaeZZaeeegeaZZaaaegJMJMMMMJJJJFMMMM........",
"jjVVVVVVVVjjjjjjeeeegeegaZZeeeeeaaaeaeggMMJMMMMMJJJJMMMM........",
"WkjjjljjjjkWkjjkcVcVVVccVgaegVVccgegegVdMMJMMMJMJJJJMJMM........",
"WWWkkjjkkWWWWkkWcVcccddcdcggcVccddcVgcddJMMJJMJJFJFJJJMJ........",
"................................................................",
"................................................................",
"................................................................",
"................................................................",
"................................................................",
"................................................................",
"................................................................",
"........................................bbbbbbbZaaaaZbbb........",
"................................................................",
"................................................................",
"................................................................",
"................................................................",
"................................................................",
"................................................................",
"................................................................",
"................................................................",
"....................VVVVXXWW........aZZZMMMJ....................",
"....................VVVVWWXX........aZZZFJMM....................",
"....................VVVVXXWW........aZbZMMMM....................",
"....................VVVVWWXX........aZZaFJMJ....................",
"................ccVcddcccVccdddcffffZZaaaZZZZZZZ................",
"................ccVccdddcVVcddddfhhfZZZaaaZZZaaZ................",
"................ccVcVdddccVcddddfhhfeaZZZaaZaaZZ................",
"................ccVccdddccVcdccdhhhhffffffffffffaaaaZbbbbbbbbbbZ",
"................cVcccVVcccVcVVVVFFFFFJFJFJJJJJJF................",
"................cVVccccdccVccVVcJJFJMMJMJMMMMMMM................",
"................ccVccdddccVcddddJJFJJMJMMMMJMJJM................",
"................ccVcVdddccccddddFJFJJMMMMMMJMMMM................",
"................VVccVcddccVVccccFJJJJMMMMJMJMMMM................",
"................jjVVVVVVVVjjjjjjJJJJMMMMMJMMMMMM................",
"................WkjjjljjjjkWkjjkJJJJMJMMMJMMMMJM................",
"................WWWkkjjkkWWWWkkWJFJFJJMJJMMJJMJJ................"
}
F.decodeRLE = function(s)
local px, i = {}, 0
for count, hex in s:gmatch("(%d+):([%x%-]+)") do
local c = false
if hex ~= "-" then
c = Color3.fromRGB(tonumber(hex:sub(1, 2), 16), tonumber(hex:sub(3, 4), 16), tonumber(hex:sub(5, 6), 16))
end
for _ = 1, tonumber(count) do i += 1 px[i] = c end
end
return px
end
F.buildImage = function(img, s)
if not img.px then img.px = F.decodeRLE(img.d) end
local px, w, h = img.px, img.w, img.h
local f = Instance.new("Frame")
f.Size = UDim2.fromOffset(w * s, h * s)
f.BackgroundTransparency = 1
f.BorderSizePixel = 0
for y = 0, h - 1 do
local x = 0
while x < w do
local c = px[y * w + x + 1]
local run = 1
while x + run < w and px[y * w + x + run + 1] == c do run += 1 end
if c then
local p = Instance.new("Frame")
p.BorderSizePixel = 0
p.BackgroundColor3 = c
p.Position = UDim2.fromOffset(x * s, y * s)
p.Size = UDim2.fromOffset(run * s, s)
p.Parent = f
end
x += run
end
end
return f
end
local vp = camera.ViewportSize
local GS = math.clamp(math.floor(math.min(vp.X / 200, vp.Y / 180)), 1, 4)
F.getPixel = function(x, y)
return PALETTE[SKIN[y + 1]:sub(x + 1, x + 1)]
end
local model = Instance.new("Model")
model.Name = "MinecraftSteve"
F.paintFace = function(part, face, u, v, w, h, flipX, flipY)
local g = Instance.new("SurfaceGui")
g.Face = face
g.SizingMode = Enum.SurfaceGuiSizingMode.FixedSize
g.CanvasSize = Vector2.new(w * 16, h * 16)
g.LightInfluence = 0.7
g.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
g.Parent = part
for row = 0, h - 1 do
local ty = v + (flipY and (h - 1 - row) or row)
local col = 0
while col < w do
local function tx(c) return u + (flipX and (w - 1 - c) or c) end
local c = F.getPixel(tx(col), ty)
local run = 1
while col + run < w and F.getPixel(tx(col + run), ty) == c do run += 1 end
if c then
local f = Instance.new("Frame")
f.BorderSizePixel = 0
f.BackgroundColor3 = c
f.Position = UDim2.fromScale(col / w, row / h)
f.Size = UDim2.fromScale(run / w, 1 / h)
f.Parent = g
end
col += run
end
end
end
F.paintBox = function(part, u, v, w, h, d)
F.paintFace(part, Enum.NormalId.Top, u + d, v, w, d, true, true)
F.paintFace(part, Enum.NormalId.Bottom, u + d + w, v, w, d)
F.paintFace(part, Enum.NormalId.Right, u, v + d, d, h)
F.paintFace(part, Enum.NormalId.Front, u + d, v + d, w, h)
F.paintFace(part, Enum.NormalId.Left, u + d + w, v + d, d, h)
F.paintFace(part, Enum.NormalId.Back, u + 2 * d + w, v + d, w, h)
end
F.toRb = function(v) return Vector3.new(-v.X, -v.Y, v.Z) * PX end
local limbs = {}
F.makeLimb = function(name, origin, size, pivot, u, v)
local part = Instance.new("Part")
part.Name = name
part.Size = size * PX
part.Color = Color3.fromRGB(176, 125, 96)
part.Material = Enum.Material.SmoothPlastic
part.Anchored, part.CanCollide, part.CanQuery, part.CanTouch = true, false, false, false
part.CastShadow = true
part.Parent = model
F.paintBox(part, u, v, size.X, size.Y, size.Z)
limbs[name] = { part = part, pivot = pivot, offset = CFrame.new(F.toRb(origin + size / 2)) }
end
F.makeLimb("head", Vector3.new(-4, -8, -4), Vector3.new(8, 8, 8), Vector3.new(0, 0, 0), 0, 0)
F.makeLimb("body", Vector3.new(-4, 0, -2), Vector3.new(8, 12, 4), Vector3.new(0, 0, 0), 16, 16)
F.makeLimb("rightArm", Vector3.new(-3, -2, -2), Vector3.new(4, 12, 4), Vector3.new(-5, 2, 0), 40, 16)
F.makeLimb("leftArm", Vector3.new(-1, -2, -2), Vector3.new(4, 12, 4), Vector3.new(5, 2, 0), 32, 48)
F.makeLimb("rightLeg", Vector3.new(-2, 0, -2), Vector3.new(4, 12, 4), Vector3.new(-1.9, 12, 0), 0, 16)
F.makeLimb("leftLeg", Vector3.new(-2, 0, -2), Vector3.new(4, 12, 4), Vector3.new(1.9, 12, 0), 16, 48)
F.placeLimb = function(l, root, pivot, rx, ry, rz)
l.part.CFrame = root * CFrame.new(F.toRb(pivot)) * CFrame.fromEulerAnglesXYZ(-rx, -ry, rz) * l.offset
end
F.placeHead = function(root, pivot, pitch, relYaw)
local head = limbs.head
-- Use the same mirrored angle convention as every other Steve limb.
-- Apply yaw and pitch separately so turning the head cannot roll/twist the neck.
-- Head angles use the same direction as the camera: positive yaw turns right,
-- and positive pitch looks upward. The previous negative signs inverted both axes.
head.part.CFrame = root * CFrame.new(F.toRb(pivot))
* CFrame.Angles(0, relYaw, 0) * CFrame.Angles(pitch, 0, 0) * head.offset
end
F.poseSteve = function(root, pitch, relYaw, walkPos, walkSpeed, age, crouch, holdingItem, interpolatedSwing)
local pi = math.pi
local rArmX = math.cos(walkPos * 0.6662 + pi) * 2 * walkSpeed * 0.5
local lArmX = math.cos(walkPos * 0.6662) * 2 * walkSpeed * 0.5
local swingProgress = math.clamp(interpolatedSwing or F.swingProgress or 0, 0, 1)
local eatBlend = math.clamp(F.eatAnimationBlend or (F.eating and 1 or 0), 0, 1)
local eatElapsed = math.clamp(F.renderEatTime or F.eatTime or 0, 0, 32)
local eatRemaining = 1 - eatElapsed / 32
local eatPull = 1 - eatRemaining ^ 27
local rArmY, lArmY, rArmSwingZ = 0, 0, 0
local bodySwingYaw = 0
-- ModelBiped's ITEM arm pose: a held item rests slightly forward instead of
-- leaving the arm in the empty-hand walk pose.
if holdingItem then rArmX = rArmX * 0.5 - pi / 10 end
-- Minecraft 1.12 biped attack math. Use render-interpolated progress so this
-- curve is smooth at 60 FPS even though the simulation advances at 20 TPS.
if swingProgress > 0 then
bodySwingYaw = math.sin(math.sqrt(swingProgress) * pi * 2) * 0.2
local eased = 1 - swingProgress
eased = 1 - eased * eased * eased * eased
local f2 = math.sin(eased * pi)
local f3 = math.sin(swingProgress * pi) * -(pitch - 0.7) * 0.75
rArmX -= f2 * 1.2 + f3
-- Main-hand arm receives body yaw plus the extra 2x ModelBiped swing term.
rArmY += bodySwingYaw * 3
lArmY += bodySwingYaw
lArmX += bodySwingYaw
rArmSwingZ = math.sin(swingProgress * pi) * -0.4
end
-- Keep eating as a held-input action, with the arm easing toward the mouth
-- during the same 32-tick use window as Java 1.12.x.
if eatBlend > 0.001 then
rArmX -= eatBlend * eatPull * 0.48
end
local rLegX = math.cos(walkPos * 0.6662) * 1.4 * walkSpeed
local lLegX = math.cos(walkPos * 0.6662 + pi) * 1.4 * walkSpeed
local headP, bodyP = Vector3.new(0, 0, 0), Vector3.new(0, 0, 0)
local rArmP = Vector3.new(-math.cos(bodySwingYaw) * 5, 2, math.sin(bodySwingYaw) * 5)
local lArmP = Vector3.new(math.cos(bodySwingYaw) * 5, 2, -math.sin(bodySwingYaw) * 5)
local rLegP, lLegP = Vector3.new(-1.9, 12, 0), Vector3.new(1.9, 12, 0)
local bodyX = 0
if crouch then
bodyX = 0.5
rArmX += 0.4 lArmX += 0.4
rLegP += Vector3.new(0, 0, 4) lLegP += Vector3.new(0, 0, 4)
headP += Vector3.new(0, 4.2, 0)
bodyP += Vector3.new(0, 3.2, 0)
rArmP += Vector3.new(0, 3.2, 0) lArmP += Vector3.new(0, 3.2, 0)
end
local rBobZ = math.cos(age * 0.09) * 0.05 + 0.05
local lBobZ = -rBobZ
rArmX += math.sin(age * 0.067) * 0.05
lArmX -= math.sin(age * 0.067) * 0.05
F.placeHead(root, headP, pitch, relYaw)
F.placeLimb(limbs.body, root, bodyP, bodyX, bodySwingYaw, 0)
F.placeLimb(limbs.rightArm, root, rArmP, rArmX, rArmY, rBobZ + rArmSwingZ)
F.placeLimb(limbs.leftArm, root, lArmP, lArmX, lArmY, lBobZ)
F.placeLimb(limbs.rightLeg, root, rLegP, rLegX, 0.005, 0.005)
F.placeLimb(limbs.leftLeg, root, lLegP, lLegX, -0.005, -0.005)
return rArmP, rArmX, rBobZ, rArmY, rArmSwingZ
end
local ITEMS = {
diamond_sword = { name = "Diamond Sword", max = 1 },
diamond_pickaxe = { name = "Diamond Pickaxe", max = 1 },
diamond_axe = { name = "Diamond Axe", max = 1 },
diamond_shovel = { name = "Diamond Shovel", max = 1 },
cooked_beef = { name = "Steak" },
bread = { name = "Bread" },
apple = { name = "Apple" },
torch = { name = "Torch" },
stick = { name = "Stick" },
coal = { name = "Coal" },
iron_ingot = { name = "Iron Ingot" },
diamond = { name = "Diamond" },
bucket = { name = "Bucket", max = 16 },
stone = { name = "Stone", placeable = true, hardness = 1.5 },
dirt = { name = "Dirt", placeable = true, hardness = 0.5 },
cobblestone = { name = "Cobblestone", placeable = true, hardness = 2.0 },
oak_planks = { name = "Oak Planks", placeable = true, hardness = 2.0 },
oak_log = { name = "Oak Log", placeable = true, hardness = 2.0 },
grass_block = { name = "Grass Block", placeable = true, hardness = 0.6 },
crafting_table = { name = "Crafting Table", placeable = true, hardness = 2.5 },
ladder = { name = "Ladder", placeable = true, hardness = 0.4 },
}
local slots = {}
local carried = nil
F.maxOf = function(id) return ITEMS[id].max or 64 end
F.canPlace = function(idx, st)
if idx == 0 or st == nil or ITEMS[st.id] == nil then return false end
if idx >= 5 and idx <= 8 then return ITEMS[st.id].armorSlot == idx end
return true
end
F.insertStack = function(st, a, b)
if F.maxOf(st.id) > 1 then
for i = a, b do
local s = slots[i]
if s and s.id == st.id and s.n < F.maxOf(s.id) then
local mv = math.min(F.maxOf(s.id) - s.n, st.n)
s.n += mv st.n -= mv
if st.n <= 0 then return true end
end
end
end
for i = a, b do
if not slots[i] and F.canPlace(i, st) then
slots[i] = { id = st.id, n = st.n }
st.n = 0
return true
end
end
return st.n <= 0
end
F.canFit = function(id, n, a, b)
local room = 0
for i = a, b do
local s = slots[i]
if s == nil then room += F.maxOf(id) elseif s.id == id then room += F.maxOf(id) - s.n end
end
return room >= n
end
F.give = function(id, n, a, b)
local st = { id = id, n = n }
F.insertStack(st, a or 9, b or 44)
end
F.updateCraft = function()
local g = {}
local count = 0
for i = 1, 4 do g[i] = slots[i] and slots[i].id or nil if g[i] then count += 1 end end
local r = nil
if count == 1 then
for i = 1, 4 do if g[i] == "oak_log" then r = { id = "oak_planks", n = 4 } end end
elseif count == 2 then
if (g[1] == "oak_planks" and g[3] == "oak_planks") or (g[2] == "oak_planks" and g[4] == "oak_planks") then
r = { id = "stick", n = 4 }
elseif (g[1] == "coal" and g[3] == "stick") or (g[2] == "coal" and g[4] == "stick") then
r = { id = "torch", n = 4 }
end
elseif count == 4 then
if g[1] == "oak_planks" and g[2] == "oak_planks" and g[3] == "oak_planks" and g[4] == "oak_planks" then
r = { id = "crafting_table", n = 1 }
end
end
slots[0] = r
end
F.consumeCraft = function()
for i = 1, 4 do
local s = slots[i]
if s then s.n -= 1 if s.n <= 0 then slots[i] = nil end end
end
F.updateCraft()
end
slots[36] = { id = "diamond_sword", n = 1 }
slots[37] = { id = "diamond_pickaxe", n = 1 }
slots[38] = { id = "diamond_axe", n = 1 }
slots[39] = { id = "diamond_shovel", n = 1 }
slots[40] = { id = "cooked_beef", n = 64 }
slots[41] = { id = "oak_planks", n = 64 }
slots[42] = { id = "cobblestone", n = 64 }
slots[43] = { id = "grass_block", n = 64 }
slots[44] = { id = "dirt", n = 64 }
F.give("stone", 64) F.give("dirt", 64) F.give("oak_log", 64)
F.give("stick", 64) F.give("coal", 64) F.give("iron_ingot", 64) F.give("diamond", 32)
F.give("apple", 64) F.give("bread", 64) F.give("bucket", 1)
F.give("ladder", 64) -- Crafting table and torch remain available through crafting recipes.
local abilities = {
invulnerable = true,
flying = false,
mayfly = true,
instabuild = true,
mayBuild = true,
flyingSpeed = 0.05,
walkingSpeed = 0.1,
}
local creative = true
local jumpTriggerTime = 0
local pos, eyeH, selected, refresh, touchJumpHeld, yaw, pitch, rp
local invOpen = false
local inventoryPage = "creative"
local hudVisible = true
local creativePlaceholder = nil
local creativePlaceholderOpen = false
local creativeTabButton = nil
local panel
local debugPanel, debugText
local chatPanel, chatInput, chatHistoryLabel, chatRowsFrame
local chatOpen = false
local mobileDpad = nil
local mobileMoveVector = Vector3.zero
local mobileHeldDirections = { Forward = false, Back = false, Left = false, Right = false }
local lastMobileForwardTap = -math.huge
local sprintLatch = false
local prevPos, vel
local recalcTouchMove
pos = Vector3.new(0, 10, 0)
eyeH = 1.62
selected = 0
touchJumpHeld = false
yaw, pitch = 0, 0
rp = RaycastParams.new()
rp.FilterType = Enum.RaycastFilterType.Exclude
rp.RespectCanCollide = true
local entityRayParams = RaycastParams.new()
entityRayParams.FilterType = Enum.RaycastFilterType.Exclude
entityRayParams.RespectCanCollide = false
F.setGameMode = function(isCreative)
creative = isCreative
if isCreative then
abilities.mayfly = true
abilities.instabuild = true
abilities.invulnerable = true
abilities.mayBuild = true
else
abilities.mayfly = false
abilities.instabuild = false
abilities.invulnerable = false
abilities.flying = false
abilities.mayBuild = true
end
if not invOpen then
inventoryPage = isCreative and "creative" or "survival"
else
inventoryPage = isCreative and "creative" or "survival"
end
if F.updateInventoryPage then F.updateInventoryPage() end
end
F.setGameMode(true)
local REACH_SURVIVAL = 4.5
local REACH_CREATIVE = 5.0
local DESTROY_DELAY_CREATIVE = 5
local isDestroying = false
local destroyBlockPos = nil
local destroyPart = nil
local destroyingItemId = nil
local destroyProgress = 0
local destroyTicks = 0
local destroyDelay = 0
local rightClickDelay = 0
local missTime = 0
do
local old = workspace:FindFirstChild("MCBlocks")
if old then old:Destroy() end
end
local char, hum, hrp
local blockFolder = Instance.new("Folder")
blockFolder.Name = "MCBlocks"
blockFolder.Parent = workspace
local existingDropFolder = workspace:FindFirstChild("MCDroppedItems")
if existingDropFolder then existingDropFolder:Destroy() end
local dropFolder = Instance.new("Folder")
dropFolder.Name = "MCDroppedItems"
dropFolder.Parent = workspace
F.baseplateOriginals = {} -- retained empty for cleanup compatibility
F.voxelOriginals = {} -- no voxel conversions are performed
F.snapToGrid = function(v)
return Vector3.new(
math.floor(v.X / BLOCK + 0.5) * BLOCK,
math.floor(v.Y / BLOCK + 0.5) * BLOCK,
math.floor(v.Z / BLOCK + 0.5) * BLOCK
)
end
local BLOCK_COLORS = {
stone = Color3.fromRGB(125, 125, 125),
dirt = Color3.fromRGB(134, 96, 67),
cobblestone = Color3.fromRGB(110, 110, 110),
oak_planks = Color3.fromRGB(162, 130, 78),
oak_log = Color3.fromRGB(102, 81, 50),
grass_block = Color3.fromRGB(91, 138, 54),
crafting_table = Color3.fromRGB(120, 90, 50),
}
F.isMCBlock = function(part)
return part and part:IsA("BasePart") and part:GetAttribute("MCBlockId") ~= nil
end
-- Any raycastable world BasePart can be selected and broken. Generated dropped items
-- are excluded so aiming at an item does not accidentally destroy the pickup.
F.isBreakableTarget = function(part)
if not (part ~= nil and part:IsA("BasePart") and part.Parent ~= nil) then return false end
if dropFolder and part:IsDescendantOf(dropFolder) then return false end
-- A part beneath a Model with a Humanoid is an entity, not a block/CSG target.
if F.getEntityTarget and F.getEntityTarget(part) then return false end
return true
end
local MCB = (function()
local blocks = {}
local bulkBuild = false
local painted = setmetatable({}, { __mode = "k" })
local function cellKey(center)
return math.floor(center.X / BLOCK + 0.5) .. ":" .. math.floor(center.Y / BLOCK + 0.5) .. ":" .. math.floor(center.Z / BLOCK + 0.5)
end
local function getBlockAt(center) return blocks[cellKey(center)] end
local BLOCKFACES = {
stone = { all = "stone" },
dirt = { all = "dirt" },
cobblestone = { all = "cobble" },
oak_planks = { all = "planks" },
oak_log = { top = "log_top", bottom = "log_top", side = "log" },
grass_block = { top = "grass_top", bottom = "dirt", side = "grass_side" },
crafting_table = { top = "ct_top", bottom = "planks", front = "ct_front", side = "ct_side" },
}
local FACES = {
{ Enum.NormalId.Top, Vector3.yAxis }, { Enum.NormalId.Bottom, -Vector3.yAxis },
{ Enum.NormalId.Front, -Vector3.zAxis }, { Enum.NormalId.Back, Vector3.zAxis },
{ Enum.NormalId.Right, Vector3.xAxis }, { Enum.NormalId.Left, -Vector3.xAxis },
}
local function faceTexKey(id, nid)
local F = BLOCKFACES[id]
if not F then return nil end
if F.all then return F.all end
if nid == Enum.NormalId.Top then return F.top end
if nid == Enum.NormalId.Bottom then return F.bottom or F.top end
if F.front and (nid == Enum.NormalId.Front or nid == Enum.NormalId.Left) then return F.front end
return F.side
end
local function rectsOf(px, w, h)
local used, out = {}, {}
for y = 0, h - 1 do
for x = 0, w - 1 do
local i = y * w + x + 1
local c = px[i]
if c and not used[i] then
local rw = 1
while x + rw < w and px[i + rw] == c and not used[i + rw] do rw += 1 end
local rh, ok = 1, true
while ok and y + rh < h do
for dx = 0, rw - 1 do
local j = (y + rh) * w + x + dx + 1
if px[j] ~= c or used[j] then ok = false break end
end
if ok then rh += 1 end
end
for dy = 0, rh - 1 do for dx = 0, rw - 1 do used[(y + dy) * w + x + dx + 1] = true end end
out[#out + 1] = { x = x, y = y, w = rw, h = rh, c = c }
end
end
end
return out
end
local faceTpl = {}
local function faceTemplate(texKey, nid)
local ck = texKey .. nid.Name
local g = faceTpl[ck]
if g then return g end
local tex = BTEX[texKey]
if not tex then return nil end
if not tex.px then tex.px = F.decodeRLE(tex.d) end
g = Instance.new("SurfaceGui")
g.Face = nid
g.SizingMode = Enum.SurfaceGuiSizingMode.FixedSize
g.CanvasSize = Vector2.new(64, 64)
g.LightInfluence = 0.5
g.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
for _, r in ipairs(rectsOf(tex.px, 16, 16)) do
local f = Instance.new("Frame")
f.BorderSizePixel = 0
f.BackgroundColor3 = r.c
f.Position = UDim2.fromOffset(r.x * 4, r.y * 4)
f.Size = UDim2.fromOffset(r.w * 4, r.h * 4)
f.Parent = g
end
faceTpl[ck] = g
return g
end
local function paintFaceOf(part, nid, id)
local key = faceTexKey(id, nid)
local tpl = key and faceTemplate(key, nid)
if tpl then tpl:Clone().Parent = part end
end
local function refreshFaces(part)
if bulkBuild or not part.Parent then return end
local id = part:GetAttribute("MCBlockId")
if not id or id == "ladder" then return end
local cell = part:GetAttribute("MCCell") or part.Position
local p = painted[part]
if not p then p = {} painted[part] = p end
for _, f in ipairs(FACES) do
if not p[f[1]] then
local nb = getBlockAt(cell + f[2] * BLOCK)
if not nb or nb:GetAttribute("MCClimb") then
p[f[1]] = true
paintFaceOf(part, f[1], id)
end
end
end
end
local function buildLadderVisual(part, center, n)
local tex = ICON.ladder
if not tex.px then tex.px = F.decodeRLE(tex.d) end
local right = (-n):Cross(Vector3.yAxis)
for _, r in ipairs(rectsOf(tex.px, 16, 16)) do
local v = Instance.new("Part")
v.Size = Vector3.new(r.w, r.h, 1) * PX
v.Color = r.c
v.Material = Enum.Material.SmoothPlastic
v.Anchored, v.CanCollide, v.CanQuery, v.CanTouch, v.CastShadow = true, false, false, false, false
local p = center - n * (BLOCK / 2) + n * (1.3 * PX) + right * ((r.x + r.w / 2 - 8) * PX) + Vector3.yAxis * ((8 - r.y - r.h / 2) * PX)
v.CFrame = CFrame.fromMatrix(p, right, Vector3.yAxis, n)
v.Parent = part
end
end
local function createBlock(id, center, face)
center = F.snapToGrid(center)
if getBlockAt(center) then return nil end
local part = Instance.new("Part")
part.Name = id
part.Anchored = true
part.CanTouch = false
part.TopSurface = Enum.SurfaceType.Smooth
part.BottomSurface = Enum.SurfaceType.Smooth
part.Material = Enum.Material.SmoothPlastic
part:SetAttribute("MCBlockId", id)
part:SetAttribute("MCCell", center)
if id == "ladder" then
local n = (face and math.abs(face.Y) < 0.5) and face or Vector3.zAxis
local t = 2 / 16 * BLOCK
local alongX = math.abs(n.X) > 0.5
part.Size = alongX and Vector3.new(t, BLOCK, BLOCK) or Vector3.new(BLOCK, BLOCK, t)
part.CFrame = CFrame.new(center - n * (BLOCK / 2 - t / 2))
part.Transparency = 1
part.CanCollide = false
part.CanQuery = true
part.CastShadow = false
part:SetAttribute("MCClimb", true)
buildLadderVisual(part, center, n)
else
part.Size = Vector3.new(BLOCK, BLOCK, BLOCK)
part.CFrame = CFrame.new(center)
part.CanCollide = true
part.CanQuery = true
part.CastShadow = true
part.Color = BLOCK_COLORS[id] or Color3.fromRGB(150, 150, 150)
end
blocks[cellKey(center)] = part
part.Parent = blockFolder
refreshFaces(part)
return part
end
local function removeBlock(part)
local cell = part:GetAttribute("MCCell") or part.Position
blocks[cellKey(cell)] = nil
painted[part] = nil
part:Destroy()
for _, f in ipairs(FACES) do
local nb = getBlockAt(cell + f[2] * BLOCK)
if nb then refreshFaces(nb) end
end
end
return {
get = getBlockAt, create = createBlock, remove = removeBlock, refresh = refreshFaces,
paintFace = paintFaceOf, rects = rectsOf, FACES = FACES, BLOCKFACES = BLOCKFACES, blocks = blocks,
setBulk = function(v) bulkBuild = v end,
}
end)()
local getBlockAt, createBlock, removeBlock = MCB.get, MCB.create, MCB.remove
-- All world geometry stays as its existing geometry. No baseplate chunking,
-- voxelization, or replacement with generated block Parts is performed.
-- A target cell is identified on the same world grid used by placed MC blocks.
F.getGridCellCenter = function(part, hitPos, hitNormal)
if F.isMCBlock(part) then
return part:GetAttribute("MCCell") or F.snapToGrid(part.Position)
end
if not hitPos then
return F.snapToGrid(part and part.Position or Vector3.zero)
end
local n = hitNormal or Vector3.yAxis
local ax, ay, az = math.abs(n.X), math.abs(n.Y), math.abs(n.Z)
local face
if ay >= ax and ay >= az then
face = Vector3.new(0, n.Y >= 0 and 1 or -1, 0)
elseif ax >= az then
face = Vector3.new(n.X >= 0 and 1 or -1, 0, 0)
else
face = Vector3.new(0, 0, n.Z >= 0 and 1 or -1)
end
return F.snapToGrid(hitPos - face * (BLOCK * 0.5))
end
-- Cut exactly one grid-sized cube out of the world geometry in the selected cell.
-- Every part that overlaps the cell is cut on its own, so each keeps its own
-- material, color and transparency (for example a visible grass part and an
-- invisible anti-cheat hitbox are never merged into one union). Roblox's CSG
-- result is a UnionOperation; it is not expanded into a collection of Parts.
F.cutGridCellWithUnion = function(source, cellCenter)
if not (source and source.Parent and source:IsA("BasePart") and cellCenter) then
return false
end
if source:IsDescendantOf(dropFolder) or source.Name == "MCSelectionGridProxy" then
return false
end
if F.isMCBlock(source) then
removeBlock(source)
return true
end
local GeometryService = game:GetService("GeometryService")
local half = BLOCK * 0.5
local cellCFrame = CFrame.new(cellCenter)
-- Collect every eligible world part whose bounds intersect the selected cell.
local excluded = { dropFolder, blockFolder, model }
if char then table.insert(excluded, char) end
local overlap = OverlapParams.new()
overlap.FilterType = Enum.RaycastFilterType.Exclude
overlap.FilterDescendantsInstances = excluded
overlap.RespectCanCollide = false
overlap.MaxParts = 0
local targets, seen = {}, {}
local function addTarget(part)
if not (part and part.Parent and part:IsA("BasePart")) then return end
if seen[part] or part:IsDescendantOf(dropFolder) or part:IsDescendantOf(blockFolder) then return end
if part.Name == "MCSelectionGridProxy" then return end
if F.getEntityTarget and F.getEntityTarget(part) then return end
local playerModel = part:FindFirstAncestorOfClass("Model")
if playerModel and Players:GetPlayerFromCharacter(playerModel) then return end
seen[part] = true
table.insert(targets, part)
end
addTarget(source)
local overlapOK, overlapping = pcall(function()
return workspace:GetPartBoundsInBox(cellCFrame, Vector3.one * BLOCK, overlap)
end)
if overlapOK and type(overlapping) == "table" then
for _, part in ipairs(overlapping) do addTarget(part) end
end
if #targets == 0 then return false end
local function partInsideCell(part)
for sx = -1, 1, 2 do
for sy = -1, 1, 2 do
for sz = -1, 1, 2 do
local corner = part.CFrame:PointToWorldSpace(Vector3.new(
part.Size.X * 0.5 * sx,
part.Size.Y * 0.5 * sy,
part.Size.Z * 0.5 * sz
))
local localCorner = cellCFrame:PointToObjectSpace(corner)
if math.abs(localCorner.X) > half + 0.01
or math.abs(localCorner.Y) > half + 0.01
or math.abs(localCorner.Z) > half + 0.01 then
return false
end
end
end
end
return true
end
local options = {
CollisionFidelity = Enum.CollisionFidelity.Default,
RenderFidelity = Enum.RenderFidelity.Automatic,
SplitApart = false,
}
local function cutOnePart(target)
if not (target and target.Parent) then return false end
local targetParent = target.Parent
local targetCFrame = target.CFrame
local targetName = target.Name
local targetAttributes = target:GetAttributes()
local cutter = Instance.new("Part")
cutter.Name = "MCUnionCutCutter"
cutter.Size = Vector3.one * BLOCK
cutter.CFrame = cellCFrame
cutter.Anchored = true
cutter.CanCollide = false
cutter.CanTouch = false
cutter.CanQuery = false
cutter.CastShadow = false
cutter.Transparency = 1
local cutOK, cutRaw = pcall(function()
return GeometryService:SubtractAsync(target, { cutter }, options)
end)
cutter:Destroy()
local results = {}
if cutOK and type(cutRaw) == "table" then
for _, item in ipairs(cutRaw) do
if typeof(item) == "Instance" and item:IsA("BasePart") then table.insert(results, item) end
end
end
local function destroyResults()
for _, item in ipairs(results) do
if item then pcall(function() item:Destroy() end) end
end
end
if not cutOK or type(cutRaw) ~= "table" then
destroyResults()
if partInsideCell(target) then
pcall(function() target:Destroy() end)
return true
end
warn("[Minecraft 1.12.1] Union cell cut failed for " .. targetName .. "; it was left unchanged.")
return false
end
-- An empty successful result means this part was entirely inside the cell.
if #results == 0 then
pcall(function() target:Destroy() end)
return true
end
for index, result in ipairs(results) do
-- Each cut piece keeps the properties of the part it came from.
pcall(function() result.CFrame = targetCFrame end)
result.Name = index == 1 and targetName or (targetName .. "_CutPart" .. tostring(index))
pcall(function() result.Color = target.Color end)
pcall(function() result.Material = target.Material end)
pcall(function() result.MaterialVariant = target.MaterialVariant end)
pcall(function() result.Reflectance = target.Reflectance end)
pcall(function() result.Transparency = target.Transparency end)
pcall(function() result.LocalTransparencyModifier = target.LocalTransparencyModifier end)
pcall(function() result.Anchored = target.Anchored end)
pcall(function() result.CanCollide = target.CanCollide end)
pcall(function() result.CanQuery = target.CanQuery end)
pcall(function() result.CanTouch = target.CanTouch end)
pcall(function() result.CastShadow = target.CastShadow end)
pcall(function() result.CollisionGroup = target.CollisionGroup end)
pcall(function() result.CustomPhysicalProperties = target.CustomPhysicalProperties end)
pcall(function()
if result:IsA("PartOperation") and target:IsA("PartOperation") then
result.UsePartColor = target.UsePartColor
end
end)
for name, value in pairs(targetAttributes) do
pcall(function() result:SetAttribute(name, value) end)
end
result:SetAttribute("MCClientUnionReplacement", true)
result.Parent = targetParent
end
-- Keep textures, decals, surface GUIs and attachments from the original.
local firstResult = results[1]
for _, child in ipairs(target:GetChildren()) do
if not child:IsA("BasePart") and not child:IsA("Model") and child.Parent == target then
pcall(function() child.Parent = firstResult end)
end
end
pcall(function() target:Destroy() end)
return true
end
local changed = false
for _, target in ipairs(targets) do
if cutOnePart(target) then changed = true end
end
return changed
end
-- Resolving a target is deliberately read-only. The same hit cell is used for
-- highlighting, breaking, and placement; no world geometry is changed here.
F.resolveBreakTarget = function(part, hitPos, hitNormal)
return part, hitPos, hitNormal
end
local selectBox = Instance.new("SelectionBox")
selectBox.Color3 = Color3.new(0, 0, 0)
selectBox.LineThickness = 0.012
selectBox.Transparency = 0.3
selectBox.Name = "MCSelectBox"
local selectionProxy = Instance.new("Part")
selectionProxy.Name = "MCSelectionGridProxy"
selectionProxy.Size = Vector3.new(BLOCK, BLOCK, BLOCK)
selectionProxy.Anchored = true
selectionProxy.CanCollide = false
selectionProxy.CanTouch = false
selectionProxy.CanQuery = false
selectionProxy.CastShadow = false
selectionProxy.Transparency = 1
selectionProxy.Parent = workspace
local crackOverlay = Instance.new("SelectionBox")
crackOverlay.Color3 = Color3.new(1, 1, 1)
crackOverlay.LineThickness = 0.025
crackOverlay.Transparency = 1
crackOverlay.Name = "MCCrackOverlay"
F.setDestroyStage = function(stage)
if stage < 0 or not destroyPart then
crackOverlay.Adornee = nil
crackOverlay.Transparency = 1
else
-- Crack feedback follows the same single-cell proxy used for selection.
crackOverlay.Adornee = selectionProxy
crackOverlay.Transparency = 1 - math.clamp(stage / 9, 0, 1) * 0.85
end
end
F.getDestroyStage = function()
return destroyProgress > 0 and math.floor(destroyProgress * 10) or -1
end
F.getDestroyProgressFor = function(id)
local h = (id == "baseplate") and 0.6 or ((ITEMS[id] and ITEMS[id].hardness) or 1.0)
if h <= 0 then return 1 end
return 1 / (h * 30)
end
F.stopDestroyBlock = function()
if isDestroying then
isDestroying = false
destroyProgress = 0
destroyTicks = 0
F.setDestroyStage(-1)
destroyPart = nil
destroyBlockPos = nil
destroyingItemId = nil
end
end
F.destroyBlock = function(part, cellCenter)
if not F.isBreakableTarget(part) then return false end
local id = part:GetAttribute("MCBlockId")
cellCenter = cellCenter or F.getGridCellCenter(part, nil, nil)
local removed = F.cutGridCellWithUnion(part, cellCenter)
if removed and not abilities.instabuild and id and ITEMS[id] then
F.give(id, 1, 36, 44)
refresh()
end
return removed
end
F.sameDestroyTarget = function(part, cellCenter)
if not part or not destroyPart then return false end
local held = slots[36 + selected]
local sid = held and held.id or nil
return part == destroyPart and cellCenter == destroyBlockPos and sid == destroyingItemId
end
F.startDestroyBlock = function(part, _direction, hitPos, hitNormal)
if not abilities.mayBuild then return false end
if not F.isBreakableTarget(part) then return false end
local cellCenter = F.getGridCellCenter(part, hitPos, hitNormal)
if abilities.instabuild then
F.destroyBlock(part, cellCenter)
destroyDelay = DESTROY_DELAY_CREATIVE
return true
end
if not isDestroying or not F.sameDestroyTarget(part, cellCenter) then
if isDestroying then F.stopDestroyBlock() end
local id = part:GetAttribute("MCBlockId")
local prog = F.getDestroyProgressFor(id)
if prog >= 1 then
F.destroyBlock(part, cellCenter)
else
isDestroying = true
destroyPart = part
destroyBlockPos = cellCenter
local held = slots[36 + selected]
destroyingItemId = held and held.id or nil
destroyProgress = 0
destroyTicks = 0
F.setDestroyStage(0)
end
end
return true
end
F.continueDestroyBlock = function(part, _direction, hitPos, hitNormal)
if destroyDelay > 0 then
destroyDelay -= 1
return true
end
if not F.isBreakableTarget(part) then return false end
local cellCenter = F.getGridCellCenter(part, hitPos, hitNormal)
if abilities.instabuild then
destroyDelay = DESTROY_DELAY_CREATIVE
F.destroyBlock(part, cellCenter)
return true
end
if F.sameDestroyTarget(part, cellCenter) then
if not part.Parent then
isDestroying = false
return false
end
local id = part:GetAttribute("MCBlockId")
destroyProgress += F.getDestroyProgressFor(id)
destroyTicks += 1
F.setDestroyStage(F.getDestroyStage())
if destroyProgress >= 1 then
isDestroying = false
F.destroyBlock(part, cellCenter)
destroyProgress = 0
destroyTicks = 0
destroyDelay = DESTROY_DELAY_CREATIVE
F.setDestroyStage(-1)
destroyPart = nil
end
return true
else
return F.startDestroyBlock(part, _direction, hitPos, hitNormal)
end
end
F.pickBlock = function()
local reach = (abilities and abilities.instabuild) and REACH_CREATIVE or REACH_SURVIVAL
local p = pos or Vector3.zero
local eh = eyeH or 1.62
local y = yaw or 0
local pi = pitch or 0
local eye = p + Vector3.new(0, eh * BLOCK, 0)
local look = (CFrame.Angles(0, y, 0) * CFrame.Angles(pi, 0, 0)).LookVector
local dir = look * (reach * BLOCK)
if not rp then return nil, nil, nil end
local r = workspace:Raycast(eye, dir, rp)
-- If the normal ray already hit a collidable limb, return it without extra work.
if r and F.getEntityTarget then
local alreadyEntity = F.getEntityTarget(r.Instance)
if alreadyEntity then return r.Instance, r.Position, r.Normal end
end
-- Standard block targeting intentionally ignores non-collidable BaseParts. This
-- second ray lets Humanoid limbs/accessories count as entities without changing
-- which ordinary world parts are eligible for union-cut block breaking.
local excluded = {}
for _, item in ipairs(rp.FilterDescendantsInstances or {}) do excluded[#excluded + 1] = item end
if dropFolder then excluded[#excluded + 1] = dropFolder end
entityRayParams.FilterDescendantsInstances = excluded
local blockDistance = r and (r.Position - eye).Magnitude or math.huge
for _ = 1, 16 do
local candidate = workspace:Raycast(eye, dir, entityRayParams)
if not candidate then break end
local entity, entityHumanoid
if F.getEntityTarget then entity, entityHumanoid = F.getEntityTarget(candidate.Instance) end
if entity and entityHumanoid then
local entityDistance = (candidate.Position - eye).Magnitude
if entityDistance < blockDistance then
return candidate.Instance, candidate.Position, candidate.Normal
end
break
end
-- Skip non-collidable decorative parts only. A collidable obstacle blocks the
-- entity ray here, matching the normal block ray's line-of-sight behavior.
if candidate.Instance.CanCollide then break end
excluded[#excluded + 1] = candidate.Instance
entityRayParams.FilterDescendantsInstances = excluded
end
if not r then return nil, nil, nil end
return r.Instance, r.Position, r.Normal
end
F.faceFromNormal = function(n)
if typeof(n) ~= "Vector3" or n.Magnitude < 1e-6 then return Vector3.yAxis end
local ax, ay, az = math.abs(n.X), math.abs(n.Y), math.abs(n.Z)
if ay >= ax and ay >= az then
return n.Y > 0 and Vector3.yAxis or -Vector3.yAxis
elseif ax >= az then
return n.X > 0 and Vector3.xAxis or -Vector3.xAxis
else
return n.Z > 0 and Vector3.zAxis or -Vector3.zAxis
end
end
F.placeBlock = function(handId, hitPart, hitPos, hitNormal)
if not abilities.mayBuild then return false end
if not handId or not ITEMS[handId] or not ITEMS[handId].placeable then return false end
if not hitPos or not hitNormal then return false end
local face = F.faceFromNormal(hitNormal)
local base
if F.isMCBlock(hitPart) then
base = hitPart:GetAttribute("MCCell") or hitPart.Position
else
base = F.snapToGrid(hitPos - face * (BLOCK * 0.5))
end
local center = F.snapToGrid(base + face * BLOCK)
if handId == "ladder" and math.abs(face.Y) > 0.5 then return false end
local halfW = 0.6 * BLOCK / 2 * 0.9
local feet = pos
local playerMin = feet - Vector3.new(halfW, 0.05, halfW)
local playerMax = feet + Vector3.new(halfW, 1.8 * BLOCK - 0.05, halfW)
local bmin = center - Vector3.new(BLOCK, BLOCK, BLOCK) * 0.5
local bmax = center + Vector3.new(BLOCK, BLOCK, BLOCK) * 0.5
if handId ~= "ladder" and playerMin.X < bmax.X and playerMax.X > bmin.X
and playerMin.Y < bmax.Y and playerMax.Y > bmin.Y
and playerMin.Z < bmax.Z and playerMax.Z > bmin.Z then
return false
end
local part = createBlock(handId, center, face)
if not part then return false end
if not abilities.instabuild then
local s = slots[36 + selected]
if s and s.id == handId then
s.n -= 1
if s.n <= 0 then slots[36 + selected] = nil end
refresh()
end
end
return true
end
local attackHeld = false
local useHeld = false
local swingTime = 0
local swinging = false
local swingQueued = false
F.startSwing = function()
if not swinging then
swingTime = 0
swingQueued = false
swinging = true
elseif swingTime >= 4 then
-- Queue a follow-up swing rather than resetting the current one mid-arc.
swingQueued = true
end
end
F.startAttack = function()
if invOpen or F.playerDead then return false end
F.startSwing()
if missTime > 0 then return false end
local part, hitPos, normal = F.pickBlock()
local entity, entityHumanoid
if F.getEntityTarget then entity, entityHumanoid = F.getEntityTarget(part) end
if entity and entityHumanoid then
F.stopDestroyBlock()
F.attackEntity(entity, entityHumanoid)
return true
end
part, hitPos, normal = F.resolveBreakTarget(part, hitPos, normal)
if F.isBreakableTarget(part) then
F.startDestroyBlock(part, normal, hitPos, normal)
F.startSwing()
return true
end
F.stopDestroyBlock()
if abilities.instabuild then
missTime = 0
else
missTime = 10
end
return false
end
F.continueAttack = function(down)
if F.playerDead then return end
if not down then
missTime = 0
F.stopDestroyBlock()
return
end
if missTime > 0 or invOpen then return end
local part, hitPos, normal = F.pickBlock()
local entity, entityHumanoid
if F.getEntityTarget then entity, entityHumanoid = F.getEntityTarget(part) end
if entity and entityHumanoid then
F.stopDestroyBlock()
if F.attackEntity(entity, entityHumanoid) then F.startSwing() end
return
end
part, hitPos, normal = F.resolveBreakTarget(part, hitPos, normal)
if F.isBreakableTarget(part) then
if F.continueDestroyBlock(part, normal, hitPos, normal) then F.startSwing() end
else
F.stopDestroyBlock()
end
end
F.startUseItem = function()
if F.playerDead or invOpen or F.eating then return end
if rightClickDelay > 0 then return end
local held = slots[36 + selected]
local id = held and held.id or nil
if id == "cooked_beef" or id == "bread" or id == "apple" then
F.eating = true
F.eatTime = 0
F.eatTimePrev = 0
F.eatItemId = id
rightClickDelay = 32
return
end
rightClickDelay = 4
local part, hitPos, normal = F.pickBlock()
-- Placement uses the hit face and shared grid directly; it must not replace
-- the target part with voxel chunks as a side effect of placing a block.
if not normal then return end
if id and ITEMS[id] and ITEMS[id].placeable then
F.placeBlock(id, part, hitPos, normal)
F.startSwing()
end
end
F.stopUseItem = function()
useHeld = false
if F.eating then
-- Freeze the elapsed phase and let the render-smoothed blend fade out.
-- Resetting eatTime here made the item/arm jump back to frame zero.
F.eating = false
F.eatItemId = nil
rightClickDelay = 0
end
end
local gui = Instance.new("ScreenGui")
gui.Name = "MinecraftGui"
gui.ResetOnSpawn = false
gui.IgnoreGuiInset = true
gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
gui.DisplayOrder = 50
gui.Parent = playerGui
-- Separate ScreenGui for the control UI so it always renders above every other UI layer.
local controlsGui = Instance.new("ScreenGui")
controlsGui.Name = "MinecraftControlsGui"
controlsGui.ResetOnSpawn = false
controlsGui.IgnoreGuiInset = true
controlsGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
controlsGui.DisplayOrder = 4000
controlsGui.Parent = playerGui
selectBox.Parent = gui
crackOverlay.Parent = gui
local iconTpl = {}
F.cloneIcon = function(id)
if not iconTpl[id] then iconTpl[id] = F.buildImage(ICON[id], GS) end
return iconTpl[id]:Clone()
end
F.textLabel = function(parent, size, z)
local t = Instance.new("TextLabel")
t.BackgroundTransparency = 1
t.Font = Enum.Font.Arcade
t.TextSize = size
t.TextXAlignment = Enum.TextXAlignment.Right
t.TextYAlignment = Enum.TextYAlignment.Bottom
t.ZIndex = z
t.Text = ""
t.Parent = parent
return t
end
F.newView = function(parent, x, y, z)
local v = {}
v.holder = Instance.new("Frame")
v.holder.BackgroundTransparency = 1
v.holder.Size = UDim2.fromOffset(16 * GS, 16 * GS)
v.holder.Position = UDim2.fromOffset(x * GS, y * GS)
v.holder.ZIndex = z
v.holder.Parent = parent
v.shadow = F.textLabel(v.holder, 8 * GS, z + 2)
v.shadow.TextColor3 = Color3.fromRGB(62, 62, 62)
v.shadow.Size = UDim2.fromOffset(17 * GS, 17 * GS)
v.shadow.Position = UDim2.fromOffset(GS, GS)
v.count = F.textLabel(v.holder, 8 * GS, z + 3)
v.count.TextColor3 = Color3.new(1, 1, 1)
v.count.Size = UDim2.fromOffset(17 * GS, 17 * GS)
return v
end
F.setView = function(v, st)
if st then
if v.id ~= st.id then
if v.icon then v.icon:Destroy() end
v.icon = F.cloneIcon(st.id)
v.icon.ZIndex = v.holder.ZIndex + 1
v.icon.Parent = v.holder
v.id = st.id
end
local t = st.n > 1 and tostring(st.n) or ""
v.count.Text = t
v.shadow.Text = t
else
if v.icon then v.icon:Destroy() v.icon = nil end
v.id = nil
v.count.Text = ""
v.shadow.Text = ""
end
end
local hud = Instance.new("Frame")
hud.Name = "MinecraftHUD"
hud.BackgroundTransparency = 1
hud.Size = UDim2.fromScale(1, 1)
hud.Parent = gui
-- Restore the attachment's original hotbar. The previous merge accidentally
-- removed this block while leaving refresh(), selectHotbar(), and the render loop
-- referring to hudViews and selFrame. That nil reference stopped initialization
-- before the GUI and player interactions could finish initializing.
local MAIN_HOTBAR_SCALE = 0.78 -- Shrinks only the main HUD row that holds the grass block and tools.
local hotbar = F.buildImage(IMG.hotbar, GS)
hotbar.Name = "HotbarBackground"
hotbar.Position = UDim2.new(0.5, -91 * GS * MAIN_HOTBAR_SCALE, 1, -23 * GS * MAIN_HOTBAR_SCALE)
hotbar.ZIndex = 1
hotbar.Parent = hud
local mainHotbarScale = Instance.new("UIScale")
mainHotbarScale.Name = "MainHotbarScale"
mainHotbarScale.Scale = MAIN_HOTBAR_SCALE
mainHotbarScale.Parent = hotbar
local selFrame = F.buildImage(IMG.hotbar_sel, GS)
selFrame.Name = "HotbarSelection"
selFrame.ZIndex = 2
selFrame.Parent = hotbar
local hudViews = {}
F.selectHotbar = function(i)
i = math.clamp(math.floor(i), 0, 8)
selected = i
end
for i = 0, 8 do
hudViews[i] = F.newView(hotbar, 3 + i * 20, 3, 3)
local button = Instance.new("TextButton")
button.Name = "HotbarSlot" .. i
button.BackgroundTransparency = 1
button.Text = ""
button.AutoButtonColor = false
button.Active = true
button.Size = UDim2.fromOffset(20 * GS, 22 * GS)
button.Position = UDim2.fromOffset(i * 20 * GS, 0)
button.ZIndex = 20
button.Parent = hotbar
local slotIndex = i
F.track(button.Activated:Connect(function()
F.selectHotbar(slotIndex)
end))
F.track(button.InputBegan:Connect(function(input)
local inputType = input.UserInputType
if inputType == Enum.UserInputType.MouseButton1 or inputType == Enum.UserInputType.Touch then
F.selectHotbar(slotIndex)
end
end))
end
F.selectHotbar(8)
-- Creative HUD keeps the hotbar and crosshair but has no XP bar.
local crosshair = F.buildImage(IMG.crosshair, GS)
crosshair.AnchorPoint = Vector2.new(0.5, 0.5)
crosshair.Position = UDim2.fromScale(0.5, 0.5)
crosshair.Parent = hud
local nameLabel = Instance.new("TextLabel")
nameLabel.BackgroundTransparency = 1
nameLabel.Font = Enum.Font.Arcade
nameLabel.TextSize = 8 * GS
nameLabel.TextColor3 = Color3.new(1, 1, 1)
nameLabel.TextStrokeTransparency = 0.3
nameLabel.AnchorPoint = Vector2.new(0.5, 1)
nameLabel.Position = UDim2.new(0.5, 0, 1, -(23 + 22) * GS * MAIN_HOTBAR_SCALE)
nameLabel.Size = UDim2.fromOffset(200 * GS, 10 * GS)
nameLabel.Text = ""
nameLabel.Parent = hud
local nameUntil, lastSel = 0, -1
invOpen = false
local invDim = Instance.new("TextButton")
invDim.Text = ""
invDim.AutoButtonColor = false
invDim.BackgroundColor3 = Color3.new(0, 0, 0)
invDim.BackgroundTransparency = 0.55
invDim.BorderSizePixel = 0
invDim.Size = UDim2.fromScale(1, 1)
invDim.Visible = false
invDim.Parent = gui
-- Keep the original inventory texture intact: the black player-preview rectangle,
-- armor-slot art, crafting grid, arrow, and result slot all remain visible. No 2D Steve
-- sprite is drawn over the preview area.
panel = F.buildImage(IMG.inventory, GS)
panel.Name = "SecondaryInventoryPanel"
panel.AnchorPoint = Vector2.new(0.5, 0.5)
panel.Position = UDim2.fromScale(0.5, 0.5)
panel.Active = true
panel.ZIndex = 30
panel.Parent = invDim
for _, child in ipairs(panel:GetDescendants()) do
if child:IsA("GuiObject") then child.ZIndex = 31 end
end
local inventoryScale = Instance.new("UIScale")
inventoryScale.Scale = 0.55
inventoryScale.Parent = panel
local layout = {}
-- Vanilla 1.12.1 player-container positions on the unmodified 176x166 background.
layout[0] = { 152, 28 } -- crafting output
layout[1] = { 96, 17 }
layout[2] = { 114, 17 }
layout[3] = { 96, 35 }
layout[4] = { 114, 35 }
-- Armor slots are drawn by the original background; no 2D player preview is drawn.
layout[5] = { 8, 8 } -- head
layout[6] = { 8, 26 } -- chest
layout[7] = { 8, 44 } -- legs
layout[8] = { 8, 62 } -- feet
for r = 0, 2 do for c = 0, 8 do layout[9 + c + r * 9] = { 8 + c * 18, 84 + r * 18 } end end
for c = 0, 8 do layout[36 + c] = { 8 + c * 18, 142 } end
layout[45] = { 77, 62 }
local views = {}
local slotButtons = {}
local hover = nil
local highlight = Instance.new("Frame")
highlight.BackgroundColor3 = Color3.new(1, 1, 1)
highlight.BackgroundTransparency = 0.5
highlight.BorderSizePixel = 0
highlight.Size = UDim2.fromOffset(16 * GS, 16 * GS)
highlight.ZIndex = 38
highlight.Visible = false
highlight.Parent = panel
local carriedView = F.newView(gui, 0, 0, 30)
carriedView.holder.Visible = false
local tooltip = Instance.new("TextLabel")
tooltip.BackgroundColor3 = Color3.fromRGB(16, 0, 16)
tooltip.BackgroundTransparency = 0.06
tooltip.BorderSizePixel = 0
tooltip.Font = Enum.Font.Arcade
tooltip.TextSize = 8 * GS
tooltip.TextColor3 = Color3.new(1, 1, 1)
tooltip.ZIndex = 40
tooltip.Visible = false
tooltip.Size = UDim2.fromOffset(100 * GS, 12 * GS)
tooltip.Parent = gui
local stroke = Instance.new("UIStroke")
stroke.Color = Color3.fromRGB(40, 0, 77)
stroke.Thickness = GS
stroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
stroke.Parent = tooltip
refresh = function()
for i = 0, 45 do
if views[i] then F.setView(views[i], slots[i]) end
end
for i = 0, 8 do
if hudViews[i] then F.setView(hudViews[i], slots[36 + i]) end
end
F.setView(carriedView, carried)
carriedView.holder.Visible = invOpen and carried ~= nil
if hover ~= nil and slots[hover] and not carried then
tooltip.Text = ITEMS[slots[hover].id].name
tooltip.Size = UDim2.fromOffset((#tooltip.Text * 6 + 8) * GS, 12 * GS)
tooltip.Visible = invOpen
else
tooltip.Visible = false
end
end
F.quickMove = function(idx)
local s = slots[idx]
if not s then return end
if (idx >= 1 and idx <= 4) or idx == 45 then
F.insertStack(s, 9, 44)
elseif idx >= 9 and idx <= 35 then
F.insertStack(s, 36, 44)
elseif idx >= 36 and idx <= 44 then
F.insertStack(s, 9, 35)
end
if s and s.n <= 0 then slots[idx] = nil end
F.updateCraft()
end
F.resultClick = function(shift)
local r = slots[0]
if not r then return end
if shift then
for _ = 1, 64 do
r = slots[0]
if not r then break end
if not F.canFit(r.id, r.n, 9, 44) then break end
F.insertStack({ id = r.id, n = r.n }, 9, 44)
F.consumeCraft()
end
else
if carried == nil then
carried = { id = r.id, n = r.n }
F.consumeCraft()
elseif carried.id == r.id and carried.n + r.n <= F.maxOf(r.id) then
carried.n += r.n
F.consumeCraft()
end
end
end
F.clickSlot = function(idx, button, shift)
if idx == 0 then F.resultClick(shift) refresh() return end
if shift then F.quickMove(idx) refresh() return end
local s = slots[idx]
if button == 1 then
if carried == nil then
if s then carried = s slots[idx] = nil end
elseif s == nil then
if F.canPlace(idx, carried) then slots[idx] = carried carried = nil end
elseif s.id == carried.id and F.maxOf(s.id) > 1 then
local mv = math.min(F.maxOf(s.id) - s.n, carried.n)
s.n += mv carried.n -= mv
if carried.n <= 0 then carried = nil end
elseif F.canPlace(idx, carried) then
slots[idx], carried = carried, s
end
else
if carried == nil then
if s then
local take = math.ceil(s.n / 2)
carried = { id = s.id, n = take }
s.n -= take
if s.n <= 0 then slots[idx] = nil end
end
elseif s == nil then
if F.canPlace(idx, carried) then
slots[idx] = { id = carried.id, n = 1 }
carried.n -= 1
end
elseif s.id == carried.id and s.n < F.maxOf(s.id) then
s.n += 1 carried.n -= 1
elseif F.canPlace(idx, carried) then
slots[idx], carried = carried, s
end
if carried and carried.n <= 0 then carried = nil end
end
F.updateCraft()
refresh()
end
for idx, p in pairs(layout) do
views[idx] = F.newView(panel, p[1], p[2], 33)
local b = Instance.new("TextButton")
b.BackgroundTransparency = 1
b.Text = ""
b.AutoButtonColor = false
b.Size = UDim2.fromOffset(18 * GS, 18 * GS)
b.Position = UDim2.fromOffset((p[1] - 1) * GS, (p[2] - 1) * GS)
b.ZIndex = 42
b.Parent = panel
slotButtons[idx] = b
local touchStart = 0
F.track(b.MouseEnter:Connect(function()
hover = idx
highlight.Position = UDim2.fromOffset(p[1] * GS, p[2] * GS)
highlight.Visible = true
refresh()
end))
F.track(b.MouseLeave:Connect(function()
if hover == idx then hover = nil highlight.Visible = false refresh() end
end))
F.track(b.InputBegan:Connect(function(input)
local t = input.UserInputType
if t == Enum.UserInputType.MouseButton1 then
F.clickSlot(idx, 1, UIS:IsKeyDown(Enum.KeyCode.LeftShift) or UIS:IsKeyDown(Enum.KeyCode.RightShift))
elseif t == Enum.UserInputType.MouseButton2 then
F.clickSlot(idx, 2, false)
elseif t == Enum.UserInputType.Touch then
touchStart = os.clock()
F.activeTouchSlot = idx
F.touchDragStartPos = Vector2.new(input.Position.X, input.Position.Y)
F.touchDragStartTime = touchStart
F.touchDragCanPick = carried == nil and slots[idx] ~= nil
F.touchDragging = false
hover = idx
highlight.Position = UDim2.fromOffset(p[1] * GS, p[2] * GS)
highlight.Visible = true
end
end))
F.track(b.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch and touchStart > 0 then
local long = os.clock() - touchStart > 0.35
local endPos = Vector2.new(input.Position.X, input.Position.Y)
if F.touchDragging then
local hitDelete = false
local deleteButton = F.deleteButton
if deleteButton and deleteButton.Visible then
local ap, as = deleteButton.AbsolutePosition, deleteButton.AbsoluteSize
hitDelete = endPos.X >= ap.X and endPos.X <= ap.X + as.X and endPos.Y >= ap.Y and endPos.Y <= ap.Y + as.Y
end
if hitDelete then
carried = nil
refresh()
else
local targetSlot = nil
for targetIdx, targetButton in pairs(slotButtons) do
if targetButton.Visible then
local ap, as = targetButton.AbsolutePosition, targetButton.AbsoluteSize
if endPos.X >= ap.X and endPos.X <= ap.X + as.X and endPos.Y >= ap.Y and endPos.Y <= ap.Y + as.Y then
targetSlot = targetIdx
break
end
end
end
if targetSlot ~= nil then F.clickSlot(targetSlot, 1, false) end
end
else
F.clickSlot(idx, long and 2 or 1, false)
end
touchStart = 0
F.activeTouchSlot = nil
F.touchDragStartPos = nil
F.touchDragCanPick = false
F.touchDragging = false
hover = nil
highlight.Visible = false
refresh()
end
end))
end
F.track(invDim.InputBegan:Connect(function(input)
if not invOpen or carried == nil then return end
local t = input.UserInputType
if t == Enum.UserInputType.MouseButton1 or t == Enum.UserInputType.Touch then
carried = nil refresh()
elseif t == Enum.UserInputType.MouseButton2 then
carried.n -= 1
if carried.n <= 0 then carried = nil end
refresh()
end
end))
F.setInventory = function(open)
if F.playerDead and open then return end
if open == invOpen then return end
invOpen = open
if F.applyCameraMode then F.applyCameraMode() end
invDim.Visible = open
attackHeld = false
useHeld = false
if F.stopUseItem then F.stopUseItem() end
touchJumpHeld = false
F.stopDestroyBlock()
if not open then
for i = 1, 4 do
if slots[i] then F.insertStack(slots[i], 9, 44) slots[i] = nil end
end
if carried then F.insertStack(carried, 9, 44) carried = nil end
F.updateCraft()
hover = nil
highlight.Visible = false
end
if F.updateInventoryPage then F.updateInventoryPage() end
crosshair.Visible = not open
refresh()
end
local touchButtons = {}
local sprintToggle, sneakToggle = false, false
F.makeButton = function(label, order, cb, opts)
opts = opts or {}
local b = Instance.new("TextButton")
b.Text = label
b.Font = Enum.Font.Arcade
b.TextSize = opts.textSize or 14
b.TextColor3 = Color3.new(1, 1, 1)
b.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
b.BackgroundTransparency = 0.18
b.BorderSizePixel = 0
b.AutoButtonColor = false
b.Size = opts.size or UDim2.fromOffset(74, 34)
if opts.pos then
b.Position = opts.pos
else
b.Position = UDim2.new(1, -84, 0.18, order * 42)
end
b.AnchorPoint = opts.anchor or Vector2.new(0, 0)
b.ZIndex = 12
b.Parent = controlsGui
if opts.hold then
F.track(b.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
cb(b, true)
end
end))
F.track(b.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
cb(b, false)
end
end))
else
F.track(b.Activated:Connect(function() cb(b) end))
end
touchButtons[#touchButtons + 1] = b
return b
end
F.paintToggle = function(b, _on) b.BackgroundColor3 = Color3.fromRGB(0, 0, 0); b.BackgroundTransparency = 0.18; b.BorderSizePixel = 0 end
local viewMode = 0
local creativeBtn, flyBtn
local cameraViewButton
if UIS.TouchEnabled then
-- Keep jump on the right. Sneak, inventory, primary and secondary actions
-- are placed around the D-pad itself below.
F.makeButton("○", 0, function(_, down)
touchJumpHeld = down and not invOpen
end, {
hold = true,
size = UDim2.fromOffset(70, 38),
pos = UDim2.new(1, -82, 0.55, 0),
color = Color3.fromRGB(70, 100, 160),
textSize = 22,
})
end
F.deleteButton = Instance.new("TextButton")
F.deleteButton.Name = "DeleteCarriedItem"
F.deleteButton.AnchorPoint = Vector2.new(0, 0)
-- Place the tiny X in the right margin aligned with the hotbar/inventory row.
F.deleteButton.Position = UDim2.fromOffset(170 * GS, 142 * GS)
F.deleteButton.Size = UDim2.fromOffset(12 * GS, 18 * GS)
F.deleteButton.BackgroundColor3 = Color3.fromRGB(150, 45, 45)
F.deleteButton.BorderSizePixel = 1
F.deleteButton.BorderColor3 = Color3.fromRGB(35, 20, 20)
F.deleteButton.Text = "X"
F.deleteButton.TextColor3 = Color3.new(1, 1, 1)
F.deleteButton.Font = Enum.Font.Code
F.deleteButton.TextScaled = true
F.deleteButton.ZIndex = 46
F.deleteButton.Parent = panel
F.track(F.deleteButton.Activated:Connect(function()
if carried then carried = nil; refresh() end
end))
---------------------------------------------------------------------
-- CREATIVE INVENTORY PLACEHOLDER
---------------------------------------------------------------------
-- Reserved UI space for the future creative item browser. It is intentionally a
-- placeholder: the survival inventory/crafting implementation above remains real.
creativePlaceholder = Instance.new("Frame")
creativePlaceholder.Name = "CreativeInventoryPlaceholder"
creativePlaceholder.AnchorPoint = Vector2.new(0.5, 0.5)
creativePlaceholder.Position = UDim2.fromScale(0.5, 0.5)
creativePlaceholder.Size = UDim2.fromOffset(176 * GS, 166 * GS)
creativePlaceholder.BackgroundColor3 = Color3.fromRGB(198, 198, 198)
creativePlaceholder.BorderSizePixel = 0
creativePlaceholder.ZIndex = 20
creativePlaceholder.Visible = false
creativePlaceholder.Parent = invDim
local creativeInventoryScale = Instance.new("UIScale")
creativeInventoryScale.Scale = 0.32
creativeInventoryScale.Parent = creativePlaceholder
local cpStroke = Instance.new("UIStroke")
cpStroke.Color = Color3.fromRGB(55, 55, 55)
cpStroke.Thickness = math.max(1, GS)
cpStroke.Parent = creativePlaceholder
local cpTitle = Instance.new("TextLabel")
cpTitle.BackgroundColor3 = Color3.fromRGB(55, 55, 55)
cpTitle.BorderSizePixel = 0
cpTitle.Position = UDim2.fromOffset(3 * GS, 3 * GS)
cpTitle.Size = UDim2.new(1, -6 * GS, 0, 18 * GS)
cpTitle.Font = Enum.Font.Arcade
cpTitle.TextSize = 9 * GS
cpTitle.TextColor3 = Color3.new(1, 1, 1)
cpTitle.Text = "CREATIVE INVENTORY"
cpTitle.ZIndex = 21
cpTitle.Parent = creativePlaceholder
local cpNote = Instance.new("TextLabel")
cpNote.BackgroundTransparency = 1
cpNote.Position = UDim2.fromOffset(7 * GS, 24 * GS)
cpNote.Size = UDim2.new(1, -14 * GS, 0, 23 * GS)
cpNote.Font = Enum.Font.Code
cpNote.TextSize = 8 * GS
cpNote.TextColor3 = Color3.fromRGB(45, 45, 45)
cpNote.TextWrapped = true
cpNote.Text = "Creative catalog placeholder"
cpNote.ZIndex = 21
cpNote.Parent = creativePlaceholder
local cpSearch = Instance.new("TextBox")
cpSearch.Name = "CreativeSearchPlaceholder"
cpSearch.Position = UDim2.fromOffset(7 * GS, 49 * GS)
cpSearch.Size = UDim2.new(1, -14 * GS, 0, 14 * GS)
cpSearch.BackgroundColor3 = Color3.fromRGB(238, 238, 238)
cpSearch.BorderSizePixel = 1
cpSearch.BorderColor3 = Color3.fromRGB(55, 55, 55)
cpSearch.Font = Enum.Font.Code
cpSearch.TextSize = 8 * GS
cpSearch.TextColor3 = Color3.fromRGB(55, 55, 55)
cpSearch.PlaceholderText = "Search items (not active yet)"
cpSearch.Text = ""
cpSearch.ClearTextOnFocus = false
cpSearch.ZIndex = 21
cpSearch.Parent = creativePlaceholder
local cpCategoryNames = { "BLOCKS", "DECOR", "TOOLS", "MISC" }
for i, name in ipairs(cpCategoryNames) do
local cat = Instance.new("TextButton")
cat.Name = "CreativeCategory_" .. name
cat.Position = UDim2.fromOffset((7 + (i - 1) * 41) * GS, 67 * GS)
cat.Size = UDim2.fromOffset(39 * GS, 12 * GS)
cat.BackgroundColor3 = Color3.fromRGB(145, 145, 145)
cat.BorderSizePixel = 1
cat.BorderColor3 = Color3.fromRGB(55, 55, 55)
cat.Font = Enum.Font.Code
cat.TextSize = 6 * GS
cat.TextColor3 = Color3.new(1, 1, 1)
cat.Text = name
cat.ZIndex = 21
cat.Parent = creativePlaceholder
cat.Active = false
end
for row = 0, 2 do
for col = 0, 8 do
local cell = Instance.new("Frame")
cell.Name = string.format("CreativeSlotPlaceholder_%02d", row * 9 + col + 1)
cell.Position = UDim2.fromOffset((7 + col * 18) * GS, (83 + row * 18) * GS)
cell.Size = UDim2.fromOffset(16 * GS, 16 * GS)
cell.BackgroundColor3 = Color3.fromRGB(120, 120, 120)
cell.BorderSizePixel = 1
cell.BorderColor3 = Color3.fromRGB(70, 70, 70)
cell.ZIndex = 21
cell.Parent = creativePlaceholder
end
end
local cpClose = Instance.new("TextButton")
cpClose.Name = "SwitchToSurvivalInventory"
cpClose.AnchorPoint = Vector2.new(1, 1)
cpClose.Position = UDim2.new(1, -4 * GS, 1, -4 * GS)
cpClose.Size = UDim2.fromOffset(54 * GS, 13 * GS)
cpClose.BackgroundColor3 = Color3.fromRGB(100, 100, 100)
cpClose.BorderSizePixel = 1
cpClose.BorderColor3 = Color3.fromRGB(40, 40, 40)
cpClose.Font = Enum.Font.Arcade
cpClose.TextSize = 7 * GS
cpClose.TextColor3 = Color3.new(1, 1, 1)
cpClose.Text = "SURVIVAL >"
cpClose.ZIndex = 22
cpClose.Visible = true
cpClose.Parent = creativePlaceholder
local inventoryPageToggle = nil
creativeTabButton = Instance.new("TextButton")
creativeTabButton.Name = "SwitchToCreativeInventory"
creativeTabButton.Position = UDim2.fromOffset(112 * GS, 5 * GS)
creativeTabButton.Size = UDim2.fromOffset(59 * GS, 12 * GS)
creativeTabButton.BackgroundColor3 = Color3.fromRGB(80, 110, 80)
creativeTabButton.BorderSizePixel = 1
creativeTabButton.BorderColor3 = Color3.fromRGB(45, 45, 45)
creativeTabButton.Font = Enum.Font.Code
creativeTabButton.TextSize = 6 * GS
creativeTabButton.TextColor3 = Color3.new(1, 1, 1)
creativeTabButton.Text = "CREATIVE >"
creativeTabButton.ZIndex = 25
creativeTabButton.Visible = false
creativeTabButton.Parent = panel
F.track(cpClose.Activated:Connect(function()
if invOpen then F.setInventoryPage("survival") end
end))
F.track(creativeTabButton.Activated:Connect(function()
if invOpen and creative then F.setInventoryPage("creative") end
end))
F.updateInventoryPage = function()
local page = inventoryPage
local showCreative = invOpen and creative and page == "creative"
local showSurvival = invOpen and page == "survival"
creativePlaceholderOpen = showCreative
creativePlaceholder.Visible = showCreative
panel.Visible = showSurvival
if F.deleteButton then F.deleteButton.Visible = showSurvival end
cpClose.Visible = false
creativeTabButton.Visible = false
if inventoryPageToggle then
inventoryPageToggle.Visible = invOpen and creative
inventoryPageToggle.Text = ""
end
if showCreative then
creativePlaceholder.ZIndex = 50
else
creativePlaceholder.ZIndex = 20
end
if F.updateHudVisibility then F.updateHudVisibility() end
end
F.setInventoryPage = function(page)
if page ~= "creative" and page ~= "survival" then return end
if page == "creative" and not creative then return end
inventoryPage = page
hover = nil
highlight.Visible = false
if F.updateInventoryPage then F.updateInventoryPage() end
refresh()
end
inventoryPageToggle = Instance.new("TextButton")
inventoryPageToggle.Name = "InventoryPageToggle"
inventoryPageToggle.AnchorPoint = Vector2.new(0, 0)
-- A single toggle outside the panel's lower-right corner, so it does not cover slots.
inventoryPageToggle.Position = UDim2.new(0.5, 46 * GS, 0.5, 45 * GS)
inventoryPageToggle.Size = UDim2.fromOffset(18 * GS, 18 * GS)
inventoryPageToggle.BackgroundColor3 = Color3.fromRGB(198, 198, 198)
inventoryPageToggle.BorderSizePixel = 1
inventoryPageToggle.BorderColor3 = Color3.fromRGB(55, 55, 55)
inventoryPageToggle.Text = ""
inventoryPageToggle.ZIndex = 75
inventoryPageToggle.Visible = false
inventoryPageToggle.Parent = invDim
-- Pixel-painted vanilla-style chest face: no external image or asset dependency.
local chestPixelFolder = Instance.new("Frame")
chestPixelFolder.Name = "PixelChestIcon"
chestPixelFolder.BackgroundTransparency = 1
chestPixelFolder.Position = UDim2.fromOffset(GS, GS)
chestPixelFolder.Size = UDim2.fromOffset(16 * GS, 16 * GS)
chestPixelFolder.Active = false
chestPixelFolder.ZIndex = 76
chestPixelFolder.Parent = inventoryPageToggle
-- A tiny isometric, blocky chest icon, using the vanilla inventory gray behind it.
local chestPalette = {
outline = Color3.fromRGB(52, 31, 17),
deep = Color3.fromRGB(91, 49, 22),
wood = Color3.fromRGB(148, 86, 38),
light = Color3.fromRGB(190, 126, 61),
top = Color3.fromRGB(214, 157, 82),
glint = Color3.fromRGB(235, 190, 119),
latch = Color3.fromRGB(127, 127, 127),
metalLight = Color3.fromRGB(191, 191, 191),
}
local chestPixels = {}
for y = 0, 15 do chestPixels[y] = {} end
local function chestPixel(x, y, color)
if x >= 0 and x < 16 and y >= 0 and y < 16 then chestPixels[y][x] = color end
end
-- Top plane: a shaded, slanted wooden lid.
for y = 2, 5 do
local leftEdge = 5 - (y - 2)
local rightEdge = 10 + (y - 2)
for x = leftEdge, rightEdge do
local color = (y == 2 or x == leftEdge or x == rightEdge) and "outline" or "top"
if y == 3 and x >= 7 and x <= 9 then color = "glint" end
if y == 4 and x <= 5 then color = "light" end
chestPixel(x, y, color)
end
end
-- Front panel.
for y = 5, 13 do
for x = 2, 12 do
local color
if y == 5 or y == 13 or x == 2 or x == 12 then
color = "outline"
elseif y == 6 then
color = "deep"
elseif y == 7 or y == 8 then
color = (x <= 4) and "light" or "wood"
elseif y == 9 or y == 10 then
color = (x <= 4) and "wood" or "light"
elseif y == 11 or y == 12 then
color = (x <= 4) and "deep" or "wood"
end
chestPixel(x, y, color)
end
end
-- Darker right side gives the chest its Minecraft inventory-item perspective.
for y = 5, 12 do
for x = 12, 14 do
local color
if x == 12 or x == 14 or y == 5 or y == 12 then
color = "outline"
elseif x == 13 then
color = (y <= 8) and "deep" or "wood"
end
chestPixel(x, y, color)
end
end
-- Gold latch and lid seam.
for x = 3, 12 do chestPixel(x, 6, "outline") end
chestPixel(7, 7, "outline")
chestPixel(8, 7, "latch")
chestPixel(7, 8, "latch")
chestPixel(8, 8, "metalLight")
chestPixel(7, 9, "latch")
chestPixel(8, 9, "outline")
for x = 3, 11 do
if x % 3 == 0 then chestPixel(x, 11, "light") end
end
for y = 0, 15 do
for x = 0, 15 do
local shade = chestPixels[y][x]
if shade then
local pixel = Instance.new("Frame")
pixel.BorderSizePixel = 0
pixel.BackgroundColor3 = chestPalette[shade]
pixel.Position = UDim2.fromOffset(x * GS, y * GS)
pixel.Size = UDim2.fromOffset(GS, GS)
pixel.ZIndex = 77
pixel.Parent = chestPixelFolder
end
end
end
F.track(inventoryPageToggle.Activated:Connect(function()
if not invOpen or not creative then return end
F.setInventoryPage(inventoryPage == "creative" and "survival" or "creative")
end))
-- Raise the creative-page controls above the unchanged survival-page panel.
for _, child in ipairs(creativePlaceholder:GetDescendants()) do
if child:IsA("GuiObject") then child.ZIndex = child.ZIndex + 40 end
end
creativePlaceholder.ZIndex = 50
local dropInventoryButton = Instance.new("TextButton")
dropInventoryButton.Name = "DropMainInventoryItem"
dropInventoryButton.AnchorPoint = Vector2.new(0, 1)
-- This button belongs to the main HUD hotbar, not the creative or survival inventory screen.
dropInventoryButton.Position = UDim2.new(0.5, 91 * GS * MAIN_HOTBAR_SCALE + 3 * GS, 1, -1 * GS * MAIN_HOTBAR_SCALE)
dropInventoryButton.Size = UDim2.fromOffset(34 * GS * MAIN_HOTBAR_SCALE, 18 * GS * MAIN_HOTBAR_SCALE)
dropInventoryButton.BackgroundColor3 = Color3.fromRGB(48, 48, 48)
dropInventoryButton.BackgroundTransparency = 0
dropInventoryButton.BorderSizePixel = 0
dropInventoryButton.Font = Enum.Font.Arcade
dropInventoryButton.Text = "DROP"
dropInventoryButton.TextSize = 7 * GS
dropInventoryButton.TextColor3 = Color3.new(1, 1, 1)
dropInventoryButton.AutoButtonColor = true
dropInventoryButton.ZIndex = 25
dropInventoryButton.Parent = controlsGui
F.track(dropInventoryButton.Activated:Connect(function()
if F.dropInventorySelection then
local all = UIS:IsKeyDown(Enum.KeyCode.LeftShift) or UIS:IsKeyDown(Enum.KeyCode.RightShift)
F.dropInventorySelection(all)
end
end))
-- The creative catalog stays visibly unfinished and cannot be interacted with yet.
local comingSoonOverlay = Instance.new("Frame")
comingSoonOverlay.Name = "CreativeComingSoonOverlay"
comingSoonOverlay.BackgroundColor3 = Color3.fromRGB(18, 18, 18)
comingSoonOverlay.BackgroundTransparency = 0.35
comingSoonOverlay.BorderSizePixel = 0
comingSoonOverlay.Position = UDim2.fromScale(0, 0)
comingSoonOverlay.Size = UDim2.fromScale(1, 1)
comingSoonOverlay.Active = true
comingSoonOverlay.ZIndex = 120
comingSoonOverlay.Parent = creativePlaceholder
local comingSoonText = Instance.new("TextLabel")
comingSoonText.Name = "ComingSoonText"
comingSoonText.BackgroundTransparency = 1
comingSoonText.AnchorPoint = Vector2.new(0.5, 0.5)
comingSoonText.Position = UDim2.fromScale(0.5, 0.5)
comingSoonText.Size = UDim2.new(1, -10 * GS, 0, 28 * GS)
comingSoonText.Font = Enum.Font.Arcade
comingSoonText.Text = "Coming soon"
comingSoonText.TextColor3 = Color3.fromRGB(255, 255, 255)
comingSoonText.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
comingSoonText.TextStrokeTransparency = 0.15
comingSoonText.TextScaled = true
comingSoonText.ZIndex = 121
comingSoonText.Parent = comingSoonOverlay
---------------------------------------------------------------------
-- POJAVLAUNCHER-STYLE TOUCH HUD: TOP BAR, D-PAD, CHAT AND DEBUG
---------------------------------------------------------------------
local topToolbar = Instance.new("Frame")
topToolbar.Name = "PojavTouchToolbar"
topToolbar.AnchorPoint = Vector2.new(0.5, 0)
topToolbar.Position = UDim2.new(0.5, 0, 0, 3)
topToolbar.Size = UDim2.fromOffset(304, 31)
topToolbar.BackgroundTransparency = 1
topToolbar.Visible = UIS.TouchEnabled
topToolbar.ZIndex = 10
topToolbar.Parent = controlsGui
local pojavButtons = {}
F.makePojavTopButton = function(label, x, width, callback, alwaysVisible)
local b = Instance.new("TextButton")
b.Name = "Pojav_" .. label:gsub("[^%w]", "")
b.Position = UDim2.fromOffset(x, 1)
b.Size = UDim2.fromOffset(width, 27)
b.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
b.BackgroundTransparency = 0.18
b.BorderSizePixel = 0
b.Text = label
b.TextColor3 = Color3.fromRGB(245, 247, 250)
b.TextSize = 10
b.Font = Enum.Font.Code
b.AutoButtonColor = false
b.ZIndex = 11
b.Parent = topToolbar
F.track(b.Activated:Connect(callback))
pojavButtons[#pojavButtons + 1] = {button = b, always = alwaysVisible == true}
return b
end
local debugEnabled = false
F.updateHudVisibility = function()
hud.Visible = hudVisible
if debugPanel then debugPanel.Visible = hudVisible and debugEnabled end
if topToolbar then
-- Touch controls sit underneath inventory/chat overlays and never cover the inventory window.
topToolbar.Visible = UIS.TouchEnabled
for _, entry in ipairs(pojavButtons) do
entry.button.Visible = (entry.always or hudVisible)
end
end
for _, b in ipairs(touchButtons) do b.Visible = hudVisible end
if mobileDpad then mobileDpad.Visible = hudVisible and UIS.TouchEnabled end
if dropInventoryButton then dropInventoryButton.Visible = hudVisible end
if chatPanel then
chatPanel.Visible = hudVisible
if chatInput then chatInput.Visible = hudVisible and chatOpen end
end
end
F.toggleDebug = function()
debugEnabled = not debugEnabled
if debugPanel then
debugPanel:SetAttribute("MCEnabled", debugEnabled)
debugPanel.Visible = debugEnabled and hudVisible
end
end
-- Debug readout is intentionally small and Pojav-like rather than a new full HUD.
debugPanel = Instance.new("Frame")
debugPanel.Name = "PojavDebugOverlay"
debugPanel.Position = UDim2.new(0, 8, 0, 38)
debugPanel.Size = UDim2.new(1, -16, 0, 112)
debugPanel.BackgroundColor3 = Color3.new(0, 0, 0)
debugPanel.BackgroundTransparency = 0.35
debugPanel.BorderSizePixel = 0
debugPanel.Visible = false
debugPanel.ZIndex = 15
debugPanel.Parent = gui
debugText = Instance.new("TextLabel")
debugText.Name = "DebugText"
debugText.BackgroundTransparency = 1
debugText.Position = UDim2.fromOffset(6, 4)
debugText.Size = UDim2.new(1, -12, 1, -8)
debugText.Font = Enum.Font.Code
debugText.TextSize = 12
debugText.TextColor3 = Color3.new(1, 1, 1)
debugText.TextXAlignment = Enum.TextXAlignment.Left
debugText.TextYAlignment = Enum.TextYAlignment.Top
debugText.TextWrapped = false
debugText.ZIndex = 16
debugText.Parent = debugPanel
chatPanel = Instance.new("Frame")
chatPanel.Name = "JavaLocalChat"
chatPanel.Position = UDim2.new(0, 0, 1, -188)
chatPanel.Size = UDim2.new(1, 0, 0, 160)
chatPanel.BackgroundTransparency = 1
chatPanel.BorderSizePixel = 0
chatPanel.Visible = true
chatPanel.ZIndex = 90
chatPanel.Parent = gui
chatRowsFrame = Instance.new("Frame")
chatRowsFrame.Name = "ChatLines"
chatRowsFrame.Position = UDim2.fromOffset(0, 0)
chatRowsFrame.Size = UDim2.new(1, 0, 1, -30)
chatRowsFrame.BackgroundTransparency = 1
chatRowsFrame.BorderSizePixel = 0
chatRowsFrame.ClipsDescendants = true
chatRowsFrame.ZIndex = 90
chatRowsFrame.Parent = chatPanel
local chatRowsLayout = Instance.new("UIListLayout")
chatRowsLayout.Name = "BottomAlignedChatLayout"
chatRowsLayout.FillDirection = Enum.FillDirection.Vertical
chatRowsLayout.HorizontalAlignment = Enum.HorizontalAlignment.Left
chatRowsLayout.VerticalAlignment = Enum.VerticalAlignment.Bottom
chatRowsLayout.SortOrder = Enum.SortOrder.LayoutOrder
chatRowsLayout.Padding = UDim.new(0, 0)
chatRowsLayout.Parent = chatRowsFrame
-- The row frame replaces the old large opaque chat rectangle. Each line receives
-- its own translucent black background, like Java Edition's HUD chat.
chatHistoryLabel = chatRowsFrame
chatInput = Instance.new("TextBox")
chatInput.Name = "ChatInput"
chatInput.Position = UDim2.new(0, 0, 1, -27)
chatInput.Size = UDim2.new(1, 0, 0, 25)
chatInput.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
chatInput.BackgroundTransparency = 0.56
chatInput.BorderSizePixel = 0
chatInput.BorderColor3 = Color3.fromRGB(80, 80, 80)
chatInput.TextColor3 = Color3.fromRGB(255, 255, 255)
chatInput.PlaceholderColor3 = Color3.fromRGB(190, 190, 190)
chatInput.PlaceholderText = ""
chatInput.Text = ""
chatInput.ClearTextOnFocus = false
chatInput.Font = Enum.Font.Arcade
chatInput.TextSize = 11
chatInput.TextXAlignment = Enum.TextXAlignment.Left
chatInput.Visible = false
chatInput.ZIndex = 92
chatInput.Parent = chatPanel
local chatEntries = {}
local function escapeRichText(value)
return tostring(value):gsub("&", "&"):gsub("<", "<"):gsub(">", ">"):gsub('"', """):gsub("'", "'")
end
local function renderChatEntries()
for _, child in ipairs(chatRowsFrame:GetChildren()) do
if child:IsA("TextLabel") then child:Destroy() end
end
for index, entry in ipairs(chatEntries) do
local row = Instance.new("TextLabel")
row.Name = "ChatLine" .. tostring(index)
row.LayoutOrder = index
row.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
row.BackgroundTransparency = 0.56
row.BorderSizePixel = 0
row.Size = UDim2.new(1, 0, 0, 14)
row.AutomaticSize = Enum.AutomaticSize.Y
row.Font = Enum.Font.Arcade
row.TextSize = 10
row.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
row.TextStrokeTransparency = 0.60
row:SetAttribute("MCChatCreatedAt", entry.time or os.clock())
row.TextColor3 = Color3.fromRGB(255, 255, 255)
row.TextXAlignment = Enum.TextXAlignment.Left
row.TextYAlignment = Enum.TextYAlignment.Center
row.TextWrapped = true
row.RichText = true
row.Text = entry.color and ('<font color="' .. entry.color .. '">' .. escapeRichText(entry.text) .. '</font>') or escapeRichText(entry.text)
row.ZIndex = 91
row.Parent = chatRowsFrame
end
end
F.appendChatLine = function(line, color)
line = tostring(line or "")
if not color and (line:match(" joined the game$") or line:match(" left the game$")) then
color = "#FFFF55" -- Java formatting code §e (yellow).
end
table.insert(chatEntries, { text = line, color = color, time = os.clock() })
while #chatEntries > 8 do table.remove(chatEntries, 1) end
renderChatEntries()
end
local chatFadeAccumulator = 0
F.track(RunService.Heartbeat:Connect(function(dt)
chatFadeAccumulator += dt
if chatFadeAccumulator < 0.1 then return end
chatFadeAccumulator = 0
if not chatRowsFrame or not chatRowsFrame.Parent then return end
local now = os.clock()
for _, row in ipairs(chatRowsFrame:GetChildren()) do
if row:IsA("TextLabel") then
local createdAt = row:GetAttribute("MCChatCreatedAt") or now
local age = math.max(0, now - createdAt)
if chatOpen then
row.Visible = true
row.TextTransparency = 0
row.BackgroundTransparency = 0.56
else
local fresh = age < 10
row.Visible = fresh
if fresh then
row.AutomaticSize = Enum.AutomaticSize.Y
local fade = age <= 8 and 1 or math.clamp((10 - age) / 2, 0, 1)
row.TextTransparency = 1 - fade
row.BackgroundTransparency = 1 - 0.44 * fade
else
row.AutomaticSize = Enum.AutomaticSize.None
row.Size = UDim2.new(1, 0, 0, 0)
row.TextTransparency = 1
row.BackgroundTransparency = 1
end
end
end
end
end))
-- Announce the players already in this server, then watch future join/leave events.
for _, existingPlayer in ipairs(Players:GetPlayers()) do
if existingPlayer ~= lp then
F.appendChatLine(tostring(existingPlayer.DisplayName or existingPlayer.Name) .. " joined the game")
end
end
F.track(Players.PlayerAdded:Connect(function(joiningPlayer)
if joiningPlayer ~= lp then
F.appendChatLine(tostring(joiningPlayer.DisplayName or joiningPlayer.Name) .. " joined the game")
end
end))
F.track(Players.PlayerRemoving:Connect(function(leavingPlayer)
if leavingPlayer ~= lp then
F.appendChatLine(tostring(leavingPlayer.DisplayName or leavingPlayer.Name) .. " left the game")
end
end))
F.setChatOpen = function(open, focus)
chatOpen = open == true
renderChatEntries()
chatPanel.Visible = hudVisible
chatInput.Visible = hudVisible and chatOpen
if F.applyCameraMode then F.applyCameraMode() end
if open and focus then chatInput:CaptureFocus() else chatInput:ReleaseFocus() end
if open then
attackHeld, useHeld, touchJumpHeld = false, false, false
if F.stopUseItem then F.stopUseItem() end
F.stopDestroyBlock()
end
end
F.executeLocalCommand = function(raw)
local message = tostring(raw or ""):gsub("^%s+", ""):gsub("%s+$", "")
if message == "" then return end
chatInput.Text = ""
if message:sub(1, 1) ~= "/" then F.appendChatLine("<" .. tostring(lp.DisplayName or lp.Name) .. "> " .. message) return end
local args = {}
for word in message:gmatch("%S+") do args[#args + 1] = word end
local cmd = (args[1] or ""):lower()
if cmd == "/help" then
F.appendChatLine("/help /fly /gamemode creative|survival /tp x y z /time set day|night")
elseif cmd == "/fly" then
if abilities.mayfly then abilities.flying = not abilities.flying F.appendChatLine("Flight: " .. (abilities.flying and "enabled" or "disabled")) else F.appendChatLine("Flight is Creative-only.") end
elseif cmd == "/gamemode" then
local mode = (args[2] or ""):lower()
if mode == "creative" then F.setGameMode(true) elseif mode == "survival" then F.setGameMode(false) else F.appendChatLine("Usage: /gamemode creative|survival") end
if creativeBtn then F.paintToggle(creativeBtn, creative); creativeBtn.Text = creative and "Creative" or "Survival" end
if flyBtn then flyBtn.Visible = creative; F.paintToggle(flyBtn, abilities.flying) end
F.appendChatLine("Gamemode: " .. (creative and "Creative" or "Survival"))
elseif cmd == "/tp" or cmd == "/teleport" then
local x, y, z = tonumber(args[2]), tonumber(args[3]), tonumber(args[4])
if x and y and z then
pos = Vector3.new(x * BLOCK, y * BLOCK, z * BLOCK)
prevPos = pos
vel = Vector3.zero
F.appendChatLine(string.format("Teleported to %.1f %.1f %.1f", x, y, z))
else F.appendChatLine("Usage: /tp x y z") end
elseif cmd == "/time" and (args[2] or ""):lower() == "set" then
local value = (args[3] or ""):lower()
if value == "day" then Lighting.ClockTime = 12; F.appendChatLine("Set local time to day.")
elseif value == "night" then Lighting.ClockTime = 0; F.appendChatLine("Set local time to night.")
else F.appendChatLine("Usage: /time set day|night") end
else
F.appendChatLine("Unknown command. Use /help.")
end
end
F.track(chatInput.FocusLost:Connect(function(enterPressed)
if enterPressed then F.executeLocalCommand(chatInput.Text); F.setChatOpen(false, false) end
end))
F.makePojavTopButton("DEBUG", 0, 52, F.toggleDebug)
F.makePojavTopButton("CHAT", 56, 46, function() local open = not chatOpen; F.setChatOpen(open, open) end)
F.makePojavTopButton("KEYBOARD", 106, 65, function() F.setChatOpen(true, true) end)
F.makePojavTopButton("GUI", 175, 43, function()
hudVisible = not hudVisible
F.updateHudVisibility()
end, true)
cameraViewButton = F.makePojavTopButton("1ST", 221, 81, function()
viewMode = (viewMode + 1) % 3
if F.applyCameraMode then F.applyCameraMode() end
end, true)
-- Place directional buttons at bottom-left; these provide movement while touch
-- camera look remains on the right side of the screen.
if UIS.TouchEnabled then
mobileDpad = Instance.new("Frame")
mobileDpad.Name = "PojavDirectionalPad"
mobileDpad.BackgroundTransparency = 1
mobileDpad.Size = UDim2.fromOffset(114, 114)
mobileDpad.Position = UDim2.new(0, 10, 1, -184)
mobileDpad.ZIndex = 10
mobileDpad.Parent = controlsGui
local function makeDpadButton(name, symbol, x, y, direction)
local b = Instance.new("TextButton")
b.Name = "Move_" .. name
b.Position = UDim2.fromOffset(x, y)
b.Size = UDim2.fromOffset(36, 36)
b.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
b.BackgroundTransparency = 0.18
b.BorderSizePixel = 0
b.AutoButtonColor = false
b.TextColor3 = Color3.fromRGB(248, 249, 252)
b.TextSize = 19
b.Font = Enum.Font.Code
b.Text = symbol
b.ZIndex = 11
b.Parent = mobileDpad
local function begin()
if direction == "Forward" then
local now = os.clock()
if now - lastMobileForwardTap <= 0.34 then sprintLatch = true end
lastMobileForwardTap = now
end
mobileHeldDirections[direction] = true
recalcTouchMove()
end
local function finish()
mobileHeldDirections[direction] = false
recalcTouchMove()
end
F.track(b.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then begin() end
end))
F.track(b.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then finish() end
end))
return b
end
makeDpadButton("Forward", "▲", 39, 0, "Forward")
makeDpadButton("Left", "◀", 0, 39, "Left")
makeDpadButton("Back", "▼", 39, 78, "Back")
makeDpadButton("Right", "▶", 78, 39, "Right")
local function makeDpadAction(name, label, x, y, color, callback, hold)
local b = Instance.new("TextButton")
b.Name = "Action_" .. name
b.Position = UDim2.fromOffset(x, y)
b.Size = UDim2.fromOffset(36, 36)
b.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
b.BackgroundTransparency = 0.18
b.BorderSizePixel = 0
b.TextColor3 = Color3.fromRGB(255, 255, 255)
b.Font = Enum.Font.Code
b.Text = label
b.TextWrapped = true
b.TextScaled = true
b.AutoButtonColor = false
b.ZIndex = 11
b.Parent = mobileDpad
if hold then
F.track(b.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
callback(true)
end
end))
F.track(b.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
callback(false)
end
end))
else
F.track(b.Activated:Connect(function() callback() end))
end
return b
end
-- The 3x3 D-pad grid: actions occupy corners and the center without
-- overlapping the four directional buttons.
local mobileSneakButton
mobileSneakButton = makeDpadAction("Sneak", "◇", 39, 39, Color3.fromRGB(98, 115, 135), function()
sneakToggle = not sneakToggle
if mobileSneakButton then
mobileSneakButton.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
end
end, false)
makeDpadAction("PrimaryBreak", "PRI\n(BREAK)", 0, 0, Color3.fromRGB(160, 70, 70), function(down)
if invOpen then return end
if down then attackHeld = true; F.startAttack()
else attackHeld = false; F.stopDestroyBlock() end
end, true)
makeDpadAction("SecondaryPlace", "SEC\n(PLACE)", 78, 0, Color3.fromRGB(70, 120, 70), function(down)
if invOpen then return end
if down then useHeld = true; F.startUseItem()
else F.stopUseItem() end
end, true)
makeDpadAction("Inventory", "INV", 0, 78, Color3.fromRGB(95, 95, 115), function()
F.setInventory(not invOpen)
end, false)
end
F.updateCraft()
refresh()
if F.updateInventoryPage then F.updateInventoryPage() end
F.updateHudVisibility()
local rootVisualOffset = 3
pos = Vector3.new(0, 10, 0)
prevPos = pos
local spawnPos = pos
vel = Vector3.zero
local onGround = false
local fallDistance = 0
local bodyYaw, prevBodyYaw = 0, 0
local sneaking, sprinting = false, false
local cameraEyeH = 1.62
sprintLatch = false
eyeH = 1.62
local jumpDelay = 0
local walkPos, walkSpeed, prevWalkSpeed = 0, 0, 0
local age = 0
---------------------------------------------------------------------
-- MINECRAFT-STYLE ENTITY HEALTH, HIT FLASHES, DEATH ANIMATION, AND DEATH SCREEN
---------------------------------------------------------------------
F.playerDead = false
F.pendingPlayerDeathMessage = nil
F.entityAttackCooldown = 0
F.entityStates = setmetatable({}, { __mode = "k" })
F.observedHumanoids = setmetatable({}, { __mode = "k" })
local ENTITY_HEALTH_SCALE = 5 -- Roblox 100 health maps to 20 Minecraft health.
local ENTITY_DEATH_TICKS = 20 -- Minecraft's familiar ~1-second death pose.
local deathGui = Instance.new("ScreenGui")
deathGui.Name = "MinecraftDeathScreen"
deathGui.ResetOnSpawn = false
deathGui.IgnoreGuiInset = true
deathGui.DisplayOrder = 5000
deathGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
deathGui.Enabled = false
deathGui.Parent = playerGui
local deathTint = Instance.new("Frame")
deathTint.Name = "RedDeathTint"
deathTint.BackgroundColor3 = Color3.fromRGB(130, 0, 0)
deathTint.BackgroundTransparency = 0.35
deathTint.BorderSizePixel = 0
deathTint.Size = UDim2.fromScale(1, 1)
deathTint.Active = true
deathTint.ZIndex = 1
deathTint.Parent = deathGui
local deathTitle = Instance.new("TextLabel")
deathTitle.Name = "DeathTitle"
deathTitle.BackgroundTransparency = 1
deathTitle.AnchorPoint = Vector2.new(0.5, 0.5)
deathTitle.Position = UDim2.fromScale(0.5, 0.318)
deathTitle.Size = UDim2.new(0.64, 0, 0, 25)
deathTitle.Font = Enum.Font.Arcade
deathTitle.Text = "You died!"
deathTitle.TextColor3 = Color3.fromRGB(255, 255, 255)
deathTitle.TextStrokeColor3 = Color3.fromRGB(65, 0, 0)
deathTitle.TextStrokeTransparency = 0.12
deathTitle.TextScaled = true
deathTitle.ZIndex = 2
deathTitle.Parent = deathTint
local deathCauseLabel = Instance.new("TextLabel")
deathCauseLabel.Name = "DeathCause"
deathCauseLabel.BackgroundTransparency = 1
deathCauseLabel.AnchorPoint = Vector2.new(0.5, 0.5)
deathCauseLabel.Position = UDim2.fromScale(0.5, 0.392)
deathCauseLabel.Size = UDim2.new(0.66, 0, 0, 17)
deathCauseLabel.Font = Enum.Font.Arcade
deathCauseLabel.Text = tostring(lp.Name) .. " was killed"
deathCauseLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
deathCauseLabel.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
deathCauseLabel.TextStrokeTransparency = 0.35
deathCauseLabel.TextWrapped = true
deathCauseLabel.TextScaled = true
deathCauseLabel.ZIndex = 2
deathCauseLabel.Parent = deathTint
local deathScoreLabel = Instance.new("TextLabel")
deathScoreLabel.Name = "DeathScore"
deathScoreLabel.BackgroundTransparency = 1
deathScoreLabel.AnchorPoint = Vector2.new(0.5, 0.5)
deathScoreLabel.Position = UDim2.fromScale(0.5, 0.45)
deathScoreLabel.Size = UDim2.new(0.64, 0, 0, 12)
deathScoreLabel.Font = Enum.Font.Arcade
deathScoreLabel.Text = "Score: 0"
deathScoreLabel.TextColor3 = Color3.fromRGB(255, 221, 72)
deathScoreLabel.TextScaled = true
deathScoreLabel.ZIndex = 2
deathScoreLabel.Parent = deathTint
local function makeDeathButton(name, caption, yScale, isEnabled)
local b = Instance.new("TextButton")
b.Name = name
b.AnchorPoint = Vector2.new(0.5, 0.5)
b.Position = UDim2.fromScale(0.5, yScale)
b.Size = UDim2.new(0, math.min(210, math.max(138, vp.X * 0.46)), 0, math.clamp(math.floor(vp.Y * 0.030), 21, 26))
b.BackgroundColor3 = isEnabled and Color3.fromRGB(128, 128, 128) or Color3.fromRGB(82, 82, 82)
b.BorderColor3 = Color3.fromRGB(24, 24, 24)
b.BorderSizePixel = 2
b.Font = Enum.Font.Arcade
b.Text = caption
b.TextColor3 = Color3.fromRGB(255, 255, 255)
b.TextTransparency = isEnabled and 0 or 0.45
b.TextScaled = false
b.TextSize = 10
b.AutoButtonColor = isEnabled
b.Active = isEnabled
b.Selectable = isEnabled
b.ZIndex = 3
b.Parent = deathTint
local stroke = Instance.new("UIStroke")
stroke.Color = isEnabled and Color3.fromRGB(190, 190, 190) or Color3.fromRGB(85, 85, 85)
stroke.Thickness = 1
stroke.Parent = b
return b
end
local deathRespawnButton = makeDeathButton("RespawnDisabled", "Respawn", 0.55, false)
local deathQuitButton = makeDeathButton("Quit", "Title Screen", 0.61, true)
F.track(deathQuitButton.Activated:Connect(function()
-- Player:Kick from a LocalScript affects only this local player.
pcall(function() lp:Kick("Quit from the Minecraft death screen") end)
end))
F.hideDeathScreen = function()
F.playerDead = false
F.pendingPlayerDeathMessage = nil
F.deathStartedAt = nil
F.deathModelPivot = nil
F.deathModelHeight = nil
deathGui.Enabled = false
pcall(function() RunService:UnbindFromRenderStep("MCSteve_DeathCamera") end)
if F.deathCameraOriginalFOV and workspace.CurrentCamera then
workspace.CurrentCamera.FieldOfView = F.deathCameraOriginalFOV
end
F.deathCameraOriginalFOV = nil
F.deathCameraBaseCFrame = nil
end
F.beginPlayerDeath = function(message)
if F.playerDead then return end
F.playerDead = true
F.deathStartedAt = os.clock()
F.pendingPlayerDeathMessage = nil
message = tostring(message or (tostring(lp.Name) .. " was killed"))
deathCauseLabel.Text = message
deathTitle.Text = "You died!"
deathScoreLabel.Text = "Score: 0"
deathGui.Enabled = true
attackHeld, useHeld, touchJumpHeld = false, false, false
if F.stopDestroyBlock then F.stopDestroyBlock() end
if F.stopUseItem then F.stopUseItem() end
pcall(function() F.deathModelPivot = model:GetPivot(); F.deathModelHeight = model:GetExtentsSize().Y end)
local cam = workspace.CurrentCamera
if cam then
F.deathCameraOriginalFOV = cam.FieldOfView
F.deathCameraBaseCFrame = cam.CFrame
end
F.appendChatLine(message)
pcall(function() RunService:UnbindFromRenderStep("MCSteve_DeathCamera") end)
RunService:BindToRenderStep("MCSteve_DeathCamera", Enum.RenderPriority.Camera.Value + 4, function()
if not F.playerDead then return end
local activeCamera = workspace.CurrentCamera
if not activeCamera then return end
local progress = math.clamp((os.clock() - (F.deathStartedAt or os.clock())) / 0.55, 0, 1)
if F.deathCameraOriginalFOV then activeCamera.FieldOfView = F.deathCameraOriginalFOV + 8 * progress end
if F.deathCameraBaseCFrame then
activeCamera.CFrame = F.deathCameraBaseCFrame * CFrame.Angles(0, 0, math.rad(90 * progress))
end
end)
end
F.getEntityTarget = function(part)
if not (part and part:IsA("BasePart")) then return nil, nil end
local node = part.Parent
while node and node ~= workspace do
if node:IsA("Model") then
local targetHumanoid = node:FObfuscated. The code is scrambled, so you can't read what it does. Common for key systems, but take care.
Features : creative mode, accurate minecraft movement, accurate physics, steve model, block placement and block removal (includes world too), you can hit players or even kill any entity / npc. Info : this is purely recreation of minecraft java edition not ported. It's still on work in progress so expect bugs, catalog blocks and items of creative mode is coming soon. Any icon or something that looks off, it's because i didn't have texture for it. I still had to find or make textures and many other mechanics. Possibly discontinued, it's client side but actual player movement still replicates to others players (the animation doesn't replicate). I recommend for mobile users to use another keyboard if pasting doesn't work, because it's too long. Or just straight up execute it in game if you have delta or any executor that involves scriptblox as their search user generated scripts engine.

Universal