Test code
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no”>
<title>Mother Box – Ultimate Edition</title>
<style>
body {
margin: 0;
overflow: hidden;
background-color: #050505;
touch-action: none;
user-select: none;
-webkit-user-select: none;
font-family: ‘Impact’, sans-serif;
}
canvas {
display: block;
}
#init-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.95);
display: flex;
justify-content: center;
align-items: center;
z-index: 100;
flex-direction: column;
transition: opacity 0.5s;
}
#init-btn {
background: #ffcc00;
border: 4px solid #000;
padding: 20px 40px;
font-size: 24px;
font-family: ‘Impact’, sans-serif;
letter-spacing: 2px;
text-transform: uppercase;
cursor: pointer;
box-shadow: 10px 10px 0 #e62e2e;
animation: pulseBtn 1s infinite alternate;
}
@keyframes pulseBtn {
from { transform: scale(1); }
to { transform: scale(1.05); }
}
.subtitle {
color: #e62e2e;
margin-top: 20px;
font-size: 14px;
letter-spacing: 1px;
text-transform: uppercase;
}
</style>
</head>
<body>
<div id=”init-overlay”>
<div id=”init-btn”>Initialize Mother Box</div>
<div class=”subtitle”>Touch Screen for Ping</div>
</div>
<canvas id=”c”></canvas>
<script>
const canvas = document.getElementById(‘c’);
const ctx = canvas.getContext(‘2d’);
// — Configuration —
let width, height;
let frame = 0;
let active = false;
// “Fourth World” Palette
const colors = {
gold: ‘#ffc400’,
goldDim: ‘#b08d00’,
red: ‘#e61919’,
redDark: ‘#7a0000’,
blue: ‘#0066cc’,
blueDark: ‘#002a5c’,
black: ‘#000000’,
white: ‘#ffffff’,
energy: ‘#ff00ff’,
cyan: ‘#00ffff’
};
// — Audio System —
const Audio = {
ctx: null,
masterGain: null,
init: function() {
this.ctx = new (window.AudioContext || window.webkitAudioContext)();
this.masterGain = this.ctx.createGain();
this.masterGain.connect(this.ctx.destination);
this.masterGain.gain.value = 0.4;
this.startHum();
},
startHum: function() {
// Deep, throbbing machine hum
const osc = this.ctx.createOscillator();
const gain = this.ctx.createGain();
osc.type = ‘sawtooth’;
osc.frequency.value = 48;
const filter = this.ctx.createBiquadFilter();
filter.type = ‘lowpass’;
filter.frequency.value = 100;
const lfo = this.ctx.createOscillator();
lfo.type = ‘sine’;
lfo.frequency.value = 0.25;
const lfoGain = this.ctx.createGain();
lfoGain.gain.value = 0.08;
lfo.connect(lfoGain);
lfoGain.connect(gain.gain);
osc.connect(filter);
filter.connect(gain);
gain.connect(this.masterGain);
gain.gain.value = 0.25;
osc.start();
lfo.start();
},
playBloop: function() {
if(!this.ctx) return;
const t = this.ctx.currentTime;
const osc = this.ctx.createOscillator();
const gain = this.ctx.createGain();
osc.connect(gain);
gain.connect(this.masterGain);
osc.type = ‘square’;
const freq = 600 + Math.random() * 800;
osc.frequency.setValueAtTime(freq, t);
gain.gain.setValueAtTime(0.03, t);
gain.gain.exponentialRampToValueAtTime(0.001, t + 0.15);
osc.start(t);
osc.stop(t + 0.15);
},
playPing: function() {
if(!this.ctx) return;
const t = this.ctx.currentTime;
// Clear Bell Tone
const osc = this.ctx.createOscillator();
const gain = this.ctx.createGain();
osc.connect(gain);
gain.connect(this.masterGain);
osc.type = ‘sine’;
osc.frequency.setValueAtTime(2217, t);
gain.gain.setValueAtTime(0, t);
gain.gain.linearRampToValueAtTime(0.7, t + 0.02);
gain.gain.exponentialRampToValueAtTime(0.001, t + 1.5);
osc.start(t);
osc.stop(t + 1.5);
// Lower Harmonic
const osc2 = this.ctx.createOscillator();
const gain2 = this.ctx.createGain();
osc2.connect(gain2);
gain2.connect(this.masterGain);
osc2.type = ‘sine’;
osc2.frequency.setValueAtTime(1108, t);
gain2.gain.setValueAtTime(0, t);
gain2.gain.linearRampToValueAtTime(0.25, t + 0.02);
gain2.gain.exponentialRampToValueAtTime(0.001, t + 1.0);
osc2.start(t);
osc2.stop(t + 1.0);
}
};
// — Drawing Primitives —
function drawHeavyRect(x, y, w, h, fill) {
ctx.fillStyle = fill;
ctx.fillRect(x, y, w, h);
ctx.lineWidth = 4;
ctx.strokeStyle = colors.black;
ctx.strokeRect(x, y, w, h);
}
function drawRivets(x, y, w, h) {
ctx.fillStyle = colors.black;
const rSz = 5;
ctx.fillRect(x+3, y+3, rSz, rSz);
ctx.fillRect(x+w-3-rSz, y+3, rSz, rSz);
ctx.fillRect(x+3, y+h-3-rSz, rSz, rSz);
ctx.fillRect(x+w-3-rSz, y+h-3-rSz, rSz, rSz);
}
function drawKrackleDots(x, y, w, h, count=8) {
ctx.fillStyle = colors.black;
for(let i=0; i<count; i++) {
const dx = x + Math.random()*(w-4);
const dy = y + Math.random()*(h-4);
const r = 3 + Math.random() * 5;
ctx.beginPath(); ctx.arc(dx, dy, r, 0, Math.PI*2); ctx.fill();
}
}
// — Tile System —
class Tile {
constructor(c, r, type) {
this.c = c;
this.r = r;
this.type = type;
this.active = false;
this.seed = Math.random();
this.rotation = Math.floor(Math.random() * 4);
}
draw(x, y, w, h) {
// Base Plate
drawHeavyRect(x, y, w, h, colors.gold);
const m = 6; // margin for inner content
const ix = x+m, iy = y+m, iw = w-m*2, ih = h-m*2;
// Dispatch to specific draw function
switch(this.type) {
case ‘pipes’: this.drawPipes(ix, iy, iw, ih); break;
case ‘circuit’: this.drawCircuit(ix, iy, iw, ih); break;
case ‘vents’: this.drawVents(ix, iy, iw, ih); break;
case ‘krackle_pit’: this.drawKracklePit(ix, iy, iw, ih); break;
case ‘machinery’: this.drawMachinery(ix, iy, iw, ih); break;
case ‘logic_node’: this.drawLogicNode(ix, iy, iw, ih); break;
case ‘energy_fins’: this.drawEnergyFins(ix, iy, iw, ih); break;
case ‘omega_block’: this.drawOmegaBlock(ix, iy, iw, ih); break;
default: this.drawPlate(ix, iy, iw, ih); break;
}
// Finish outer edge
drawRivets(x, y, w, h);
}
// 1. PIPES
drawPipes(x,y,w,h) {
ctx.fillStyle = colors.redDark;
ctx.fillRect(x,y,w,h);
drawKrackleDots(x,y,w,h, 6); // Energy leak
const count = 3;
const ph = h/count;
for(let i=0; i<count; i++) {
const py = y + i*ph;
// Pipe Body
ctx.fillStyle = colors.gold;
ctx.fillRect(x, py+3, w, ph-6);
ctx.strokeRect(x, py+3, w, ph-6);
// Highlight
ctx.fillStyle = ‘rgba(255,255,255,0.4)’;
ctx.fillRect(x, py+5, w, (ph-6)*0.3);
// Pulse
if(this.active) {
const pulseX = (frame*4 + i*60) % w;
ctx.fillStyle = colors.white;
ctx.fillRect(x+pulseX, py+3, 15, ph-6);
ctx.strokeRect(x+pulseX, py+3, 15, ph-6);
}
}
}
// 2. CIRCUIT
drawCircuit(x,y,w,h) {
ctx.fillStyle = colors.black;
ctx.fillRect(x,y,w,h);
// Grid lines
ctx.strokeStyle = colors.blueDark;
ctx.lineWidth = 2;
ctx.beginPath();
for(let i=10; i<w; i+=10) { ctx.moveTo(x+i, y); ctx.lineTo(x+i, y+h); }
ctx.stroke();
ctx.strokeStyle = this.active ? colors.cyan : colors.gold;
ctx.lineWidth = 5;
ctx.lineCap = ‘square’;
ctx.lineJoin = ‘miter’;
ctx.beginPath();
// Random-looking jagged path
const pathY = y + h * (0.3 + this.seed*0.4);
ctx.moveTo(x, pathY);
ctx.lineTo(x + w*0.3, pathY);
ctx.lineTo(x + w*0.3, pathY + (this.seed>0.5 ? 20 : -20));
ctx.lineTo(x + w*0.7, pathY + (this.seed>0.5 ? 20 : -20));
ctx.lineTo(x + w*0.7, pathY);
ctx.lineTo(x + w, pathY);
ctx.stroke();
// Nodes
if(this.active) {
ctx.fillStyle = colors.white;
ctx.beginPath(); ctx.arc(x+w*0.5, pathY + (this.seed>0.5 ? 20 : -20), 4, 0, Math.PI*2); ctx.fill();
if(Math.random() > 0.96) Audio.playBloop();
}
}
// 3. VENTS
drawVents(x,y,w,h) {
ctx.fillStyle = colors.blueDark;
ctx.fillRect(x,y,w,h);
const count = 5;
const vh = h/count;
for(let i=0; i<count; i++) {
ctx.fillStyle = colors.black;
ctx.fillRect(x+4, y + i*vh + 4, w-8, vh-6);
// Glowing ember inside vent
if(this.active) {
ctx.fillStyle = colors.energy;
ctx.fillRect(x+10, y + i*vh + 6, Math.random()*(w-20), 2);
}
}
}
// 4. KRACKLE PIT
drawKracklePit(x,y,w,h) {
ctx.fillStyle = colors.black;
ctx.fillRect(x,y,w,h);
// Inset
const ins = 4;
ctx.fillStyle = this.active ? colors.energy : colors.redDark;
ctx.fillRect(x+ins, y+ins, w-ins*2, h-ins*2);
ctx.strokeRect(x+ins, y+ins, w-ins*2, h-ins*2);
drawKrackleDots(x+ins, y+ins, w-ins*2, h-ins*2, 15);
// Floating blob
if(this.active) {
const bx = x + w/2 + Math.sin(frame*0.1 + this.seed)*5;
const by = y + h/2 + Math.cos(frame*0.13)*5;
const br = w * 0.25;
ctx.fillStyle = colors.white;
ctx.beginPath(); ctx.arc(bx, by, br, 0, Math.PI*2); ctx.fill();
// Dots inside blob
ctx.fillStyle = colors.black;
ctx.beginPath(); ctx.arc(bx-3, by-3, 4, 0, Math.PI*2); ctx.fill();
ctx.beginPath(); ctx.arc(bx+4, by+2, 5, 0, Math.PI*2); ctx.fill();
}
}
// 5. MACHINERY (New)
drawMachinery(x,y,w,h) {
// Background
ctx.fillStyle = colors.redDark;
ctx.fillRect(x,y,w,h);
// Random blocky shapes piled up
ctx.fillStyle = colors.goldDim;
ctx.lineWidth = 3;
// Block 1
ctx.fillRect(x+5, y+h*0.4, w*0.6, h*0.5);
ctx.strokeRect(x+5, y+h*0.4, w*0.6, h*0.5);
// Block 2
ctx.fillStyle = colors.gold;
ctx.fillRect(x+w*0.4, y+10, w*0.5, h*0.6);
ctx.strokeRect(x+w*0.4, y+10, w*0.5, h*0.6);
// Cylinder
ctx.fillStyle = colors.black;
ctx.fillRect(x+w*0.5, y+h*0.3, 10, h*0.4);
if(this.active) {
ctx.fillStyle = colors.red;
ctx.beginPath(); ctx.arc(x+w*0.65, y+30, 4, 0, Math.PI*2); ctx.fill();
}
}
// 6. LOGIC NODE (New)
drawLogicNode(x,y,w,h) {
ctx.fillStyle = colors.black;
ctx.fillRect(x,y,w,h);
// Radiating lines
ctx.strokeStyle = colors.blueDark;
ctx.lineWidth = 2;
const cx = x + w/2;
const cy = y + h/2;
ctx.beginPath();
ctx.moveTo(x, y); ctx.lineTo(cx, cy);
ctx.moveTo(x+w, y); ctx.lineTo(cx, cy);
ctx.moveTo(x, y+h); ctx.lineTo(cx, cy);
ctx.moveTo(x+w, y+h); ctx.lineTo(cx, cy);
ctx.stroke();
// Central Hub
const r = w * 0.25;
ctx.fillStyle = colors.blueDark;
ctx.beginPath(); ctx.arc(cx, cy, r, 0, Math.PI*2); ctx.fill();
ctx.stroke(); // Black outline
// Active core
ctx.fillStyle = this.active ? colors.cyan : ‘#003344’;
ctx.beginPath(); ctx.arc(cx, cy, r*0.6, 0, Math.PI*2); ctx.fill();
if(this.active) {
ctx.fillStyle = colors.white;
ctx.fillRect(cx-2, cy-2, 4, 4);
}
}
// 7. ENERGY FINS (New)
drawEnergyFins(x,y,w,h) {
ctx.fillStyle = colors.redDark;
ctx.fillRect(x,y,w,h);
const fins = 4;
const fw = w / fins;
for(let i=0; i<fins; i++) {
const fx = x + i*fw;
// Fin body
ctx.fillStyle = colors.gold;
ctx.fillRect(fx+2, y+5, fw-4, h-10);
ctx.strokeRect(fx+2, y+5, fw-4, h-10);
// Energy Glow between
if(this.active && i < fins-1) {
ctx.fillStyle = colors.energy;
const pulseH = h * (0.2 + Math.random()*0.6);
ctx.fillRect(fx+fw-2, y + (h-pulseH)/2, 4, pulseH);
}
}
}
// 8. OMEGA BLOCK (New)
drawOmegaBlock(x,y,w,h) {
ctx.fillStyle = colors.goldDim;
ctx.fillRect(x,y,w,h);
// Heavy black geometric glyph
ctx.fillStyle = colors.black;
if(this.seed < 0.33) {
// The “Omega” shapeish
ctx.beginPath();
ctx.moveTo(x+10, y+h-10);
ctx.lineTo(x+10, y+h*0.4);
ctx.lineTo(x+w*0.3, y+10);
ctx.lineTo(x+w*0.7, y+10);
ctx.lineTo(x+w-10, y+h*0.4);
ctx.lineTo(x+w-10, y+h-10);
ctx.lineTo(x+w*0.7, y+h-10);
ctx.lineTo(x+w*0.7, y+h*0.5);
ctx.lineTo(x+w*0.3, y+h*0.5);
ctx.lineTo(x+w*0.3, y+h-10);
ctx.fill();
} else if (this.seed < 0.66) {
// Zig Zag Block
ctx.beginPath();
ctx.moveTo(x+5, y+5);
ctx.lineTo(x+w-5, y+5);
ctx.lineTo(x+5, y+h-5);
ctx.lineTo(x+w-5, y+h-5);
ctx.lineTo(x+w-5, y+h-15);
ctx.lineTo(x+25, y+h-15);
ctx.lineTo(x+w-25, y+15);
ctx.lineTo(x+5, y+15);
ctx.fill();
} else {
// Heavy Circle
ctx.beginPath();
ctx.arc(x+w/2, y+h/2, w*0.35, 0, Math.PI*2);
ctx.fill();
ctx.fillStyle = this.active ? colors.red : colors.gold;
ctx.beginPath();
ctx.arc(x+w/2, y+h/2, w*0.15, 0, Math.PI*2);
ctx.fill();
}
}
// 9. PLATE (Varied)
drawPlate(x,y,w,h) {
ctx.fillStyle = colors.goldDim;
ctx.fillRect(x,y,w,h);
ctx.strokeStyle = colors.black;
ctx.lineWidth = 3;
// Diagonal hatch
if(this.seed > 0.5) {
ctx.beginPath();
ctx.moveTo(x+w*0.5, y);
ctx.lineTo(x, y+h*0.5);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x+w, y+h*0.5);
ctx.lineTo(x+w*0.5, y+h);
ctx.stroke();
} else {
// Square inset
ctx.strokeRect(x+12, y+12, w-24, h-24);
}
}
}
// — Grid Logic —
let grid = [];
const COLS = 4;
const ROWS = 5;
let cellW, cellH, pad;
let eyeTarget = {x:0, y:0};
let pingState = { active: false, life: 0 };
function initGrid() {
grid = [];
// 1. Create a “Deck” of tile types to shuffle
// We need 16 tiles (20 total – 4 for eye)
const deck = [
‘pipes’, ‘pipes’,
‘circuit’, ‘circuit’,
‘vents’, ‘vents’,
‘krackle_pit’, ‘krackle_pit’,
‘machinery’, ‘machinery’,
‘logic_node’, ‘logic_node’,
‘energy_fins’, ‘energy_fins’,
‘omega_block’, ‘omega_block’,
‘plate’, ‘plate’ // Spares
];
// Shuffle deck
for (let i = deck.length – 1; i > 0; i–) {
const j = Math.floor(Math.random() * (i + 1));
[deck[i], deck[j]] = [deck[j], deck[i]];
}
let deckIndex = 0;
for(let r=0; r<ROWS; r++) {
for(let c=0; c<COLS; c++) {
let type;
// Eye Housing check (center 2×2)
if((r===1 || r===2) && (c===1 || c===2)) {
type = ‘eye_housing’;
} else {
type = deck[deckIndex % deck.length];
deckIndex++;
}
grid.push(new Tile(c, r, type));
}
}
}
function resize() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
pad = 8;
cellW = (width – (pad * (COLS+1))) / COLS;
cellH = (height – (pad * (ROWS+1))) / ROWS;
}
function autonomousUpdate() {
if(frame % 50 === 0) {
// Randomly toggle a tile
const t = grid[Math.floor(Math.random() * grid.length)];
if(t.type !== ‘eye_housing’) {
t.active = !t.active;
}
}
// Eye drift
const time = Date.now() * 0.0005;
eyeTarget.x = (width/2) + Math.sin(time) * (width/3);
eyeTarget.y = (height/2) + Math.cos(time*1.3) * (height/3);
}
function triggerPing() {
pingState.active = true;
pingState.life = 1.0;
if(active) Audio.playPing();
}
function loop() {
frame++;
autonomousUpdate();
// Background
ctx.fillStyle = colors.redDark;
ctx.fillRect(0, 0, width, height);
// Draw Tiles
grid.forEach(t => {
if(t.type === ‘eye_housing’) {
const x = pad + t.c*(cellW+pad);
const y = pad + t.r*(cellH+pad);
ctx.fillStyle = colors.red;
ctx.fillRect(x, y, cellW, cellH);
// Tech detail inside eye housing
ctx.fillStyle = colors.black;
ctx.fillRect(x, y + cellH/2 – 4, cellW, 8);
ctx.fillRect(x + cellW/2 – 4, y, 8, cellH);
return;
}
const x = pad + t.c*(cellW+pad);
const y = pad + t.r*(cellH+pad);
t.draw(x, y, cellW, cellH);
});
// Draw Central Eye
const eyeX = pad + 1*(cellW+pad);
const eyeY = pad + 1*(cellH+pad);
const eyeW = (cellW*2) + pad;
const eyeH = (cellH*2) + pad;
ctx.lineWidth = 10;
ctx.strokeStyle = colors.black;
ctx.strokeRect(eyeX, eyeY, eyeW, eyeH);
const lensX = eyeX + eyeW/2;
const lensY = eyeY + eyeH/2;
const lensR = Math.min(eyeW, eyeH) * 0.38;
ctx.fillStyle = colors.black;
ctx.beginPath(); ctx.arc(lensX, lensY, lensR+6, 0, Math.PI*2); ctx.fill();
// Pulsing Lens
const pulse = pingState.active ? Math.sin(frame*0.8)*8 : 0;
ctx.fillStyle = pingState.active ? colors.white : colors.gold;
ctx.beginPath(); ctx.arc(lensX, lensY, lensR+pulse, 0, Math.PI*2); ctx.fill();
ctx.lineWidth = 4; ctx.strokeStyle = colors.black; ctx.stroke();
// Pupil
const dx = (eyeTarget.x – lensX) * 0.12;
const dy = (eyeTarget.y – lensY) * 0.12;
const dist = Math.sqrt(dx*dx + dy*dy);
const maxD = lensR*0.55;
let finalDx = dx; let finalDy = dy;
if(dist > maxD) {
const angle = Math.atan2(dy, dx);
finalDx = Math.cos(angle) * maxD;
finalDy = Math.sin(angle) * maxD;
}
ctx.fillStyle = colors.black;
ctx.beginPath(); ctx.arc(lensX + finalDx, lensY + finalDy, lensR*0.25, 0, Math.PI*2); ctx.fill();
ctx.fillStyle = colors.white;
ctx.beginPath(); ctx.arc(lensX + finalDx + lensR*0.08, lensY + finalDy – lensR*0.08, lensR*0.08, 0, Math.PI*2); ctx.fill();
// Ping Visual
if(pingState.active) {
ctx.save();
ctx.translate(width/2, height/2);
const s = 1 + Math.sin((1-pingState.life)*Math.PI)*0.25;
ctx.scale(s, s);
// Jagged Burst
ctx.beginPath();
const pts = 24;
for(let i=0; i<pts*2; i++) {
const a = (i/(pts*2)) * Math.PI*2;
const baseR = (i%2===0) ? 300 : 180;
const r = baseR + Math.random()*20;
ctx.lineTo(Math.cos(a)*r, Math.sin(a)*r);
}
ctx.closePath();
ctx.fillStyle = colors.black;
ctx.shadowColor = colors.black;
ctx.shadowOffsetX = 15; ctx.shadowOffsetY = 15;
ctx.fill();
ctx.shadowColor = ‘transparent’;
ctx.fillStyle = colors.white;
ctx.fill();
ctx.lineWidth = 8;
ctx.strokeStyle = colors.black;
ctx.stroke();
// Inner Krackle
drawKrackleDots(-100, -100, 200, 200, 20);
// Text
ctx.font = “italic 900 130px Impact”;
ctx.textAlign = “center”;
ctx.textBaseline = “middle”;
ctx.fillStyle = colors.red;
ctx.fillText(“PING!”, 0, 0);
ctx.lineWidth = 4;
ctx.strokeStyle = colors.black;
ctx.strokeText(“PING!”, 0, 0);
ctx.restore();
pingState.life -= 0.02;
if(pingState.life <= 0) pingState.active = false;
}
requestAnimationFrame(loop);
}
document.getElementById(‘init-btn’).addEventListener(‘click’, () => {
active = true;
Audio.init();
document.getElementById(‘init-overlay’).style.opacity = 0;
setTimeout(() => {
document.getElementById(‘init-overlay’).style.display = ‘none’;
triggerPing();
}, 500);
});
canvas.addEventListener(‘mousedown’, () => triggerPing());
canvas.addEventListener(‘touchstart’, (e) => { e.preventDefault(); triggerPing(); }, {passive: false});
window.addEventListener(‘resize’, resize);
resize();
initGrid();
loop();
</script>
</body>
</html>
