import { initGPU } from "./gpu.js"; import { World } from "./world.js"; import { record, replay } from "./plme.js"; import { Agents } from "./agents.js"; const canvas = document.getElementById("viewport"); const log = document.getElementById("log"); const input = document.getElementById("input"); function println(msg) { log.textContent += "\n" + msg; log.scrollTop = log.scrollHeight; } const gpu = await initGPU(); println("GPU mode: " + gpu.mode); const world = new World(canvas, gpu); const agents = new Agents(world); let last = performance.now(); function loop(t) { const dt = (t - last) / 1000; last = t; agents.update(dt); world.update(dt); world.render(); requestAnimationFrame(loop); } requestAnimationFrame(loop); input.addEventListener("keydown", e => { if (e.key === "Enter") { const text = input.value.trim(); input.value = ""; const cmd = parseCommand(text); record(cmd); execute(cmd); } }); function execute(cmd) { println("> " + cmd.raw); if (cmd.lane === "world") world.apply(cmd); if (cmd.lane === "agent") agents.apply(cmd); if (cmd.lane === "system" && cmd.action === "replay") { println("Replaying PLME stream..."); replay(execute); } } function parseCommand(text) { const timestamp = performance.now(); if (text.startsWith("power")) { return { lane: "world", payload: { power: parseFloat(text.split(" ")[1]) }, raw: text, timestamp }; } if (text === "spawn") { return { lane: "agent", action: "spawn", raw: text, timestamp }; } if (text === "replay") { return { lane: "system", action: "replay", raw: text, timestamp }; } return { lane: "text", raw: text, timestamp }; }