feat: module interaction system with wiring panel

Add a new "module" interaction type where doors/devices define ports
(in/out) and a JS verify function. Players wire their gadget's I/O
to the module's ports via a canvas-rendered wiring panel, then execute
to verify the circuit logic.

- New wiringPanel.js: full wiring UI with keyboard nav, bezier wires,
  mini circuit evaluator, and verify execution
- AND-gate example door in Circuit Lab (tile 9,1)
- Editor support: module type with ports editor and JS verify textarea
- Integrated into gameMode, worldInput, worldRenderer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jose Luis
2026-03-20 17:59:25 +01:00
parent 6ba3fa457a
commit f9492bff4c
6 changed files with 671 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ import { initWorldRenderer, startWorldLoop, stopWorldLoop } from './worldRendere
import { initWorldInput, destroyWorldInput, setInteractionHandler } from './worldInput.js';
import { getMap } from './maps.js';
import { saveGadget, openBackpack, getGadgets, openNamingScreen, showNotification } from './inventory.js';
import { openWiringPanel } from './wiringPanel.js';
// Circuit editor stop function (to stop its render loop when switching modes)
import { stopCircuitLoop } from '../renderer.js';
@@ -144,6 +145,31 @@ function handleInteraction(event) {
break;
}
case 'module': {
const inter = event.data;
// Already solved?
if (inter.moduleId && isPuzzleSolved(inter.moduleId)) {
startDialog(['This module is already unlocked.'], 'System');
return;
}
// Need gadgets
const mGadgets = getGadgets();
if (mGadgets.length === 0) {
const portDesc = (inter.ports || []).map(p => `${p.name} (${p.dir})`).join(', ');
startDialog([
`This module requires a gadget to operate.`,
`Ports: ${portDesc}`,
'Craft a circuit in your Workshop (TAB) and save it as a gadget!'
], 'System');
return;
}
// Open backpack → on "Use", open wiring panel
openBackpack((gadget) => {
openWiringPanel(inter, gadget);
});
break;
}
case 'openInventory':
// TODO: inventory UI
console.log('[gameMode] inventory:', worldState.inventory);