Jose Luis 6ba3fa457a hide: disable puzzle mode from editor without removing code
Comment out initPuzzleUI() call and remove puzzle_door from
interaction type dropdown — all puzzle code remains intact for
future re-enablement.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 17:45:19 +01:00

Logic Gates — Circuit Simulator RPG

A logic gate circuit simulator combined with a Pokemon-style tile-based world. Players explore Neon Town, interact with NPCs, and craft logic circuits in a Workshop to solve puzzle doors and progress through the game.

Live: logic.montlab.dev

🎮 Game Modes

World Mode (exploration)

  • Walk around pixel-art maps rendered from PNG backgrounds
  • Talk to NPCs, read signs, enter buildings through doors
  • Find puzzle doors that require specific circuit outputs to unlock
  • Open your backpack to manage saved gadgets

Workshop Mode (circuit editor)

  • Full-featured logic gate simulator with drag-and-drop
  • Gates: AND, OR, NOT, NAND, NOR, XOR, INPUT, OUTPUT, CLOCK
  • Wire gates together by dragging between ports
  • Real-time simulation with GTKWave-style waveform viewer
  • Save circuits as custom components for reuse
  • Save circuits as gadgets to your backpack for use on puzzles

🕹️ Controls

World

Key Action
WASD / Arrows Move
E / Enter / Space Interact with NPCs, signs, doors
I Open Backpack
TAB Open Workshop
F3 Toggle debug collision overlay

Workshop

Key Action
Click + Drag Place and connect gates
Shift + Drag Cut wires / create bus connectors
Mouse wheel Zoom
Arrows / +/- Pan and zoom
0 Reset camera

Backpack

Key Action
↑↓ / WS Navigate gadget list
E / Enter Select → Use / Toss
I / ESC / B Close

🎒 Gadget System

Circuits become portable items:

  1. Build a circuit in the Workshop with INPUT and OUTPUT gates
  2. Save as Gadget (pink button, top-right) — names it and stores in your backpack
  3. Use on puzzle doors — the game runs your circuit's truth table against the puzzle's required outputs
  4. If outputs match → puzzle solved, door unlocks!

🗺️ Maps

Map Size Description
Neon Town 20×18 Hub town with buildings, NPCs, signs
Circuit Lab 10×12 Professor's lab with workshop tables
House Interior 8×8 Generic house (WIP)
Route 1 20×36 Path to next area (WIP)

Bidirectional Door System

Every door is a two-way link with explicit coordinates — entering a building through a specific door returns you to that exact door when you exit. spawn only exists on the starting map (Neon Town).

🛠️ Level Editor

Standalone editor at /editor.html for visually editing maps:

  • Wall painting — click/drag to paint collision masks
  • Entity placement — NPCs, exits, interactions, spawn points
  • 🔗 Bi-Link tool — create bidirectional door links between maps in one click
  • Properties panel — edit entity properties (dialog, facing, target map/coords)
  • Zoom/pan — mouse wheel, +/-, arrows, right-click drag
  • Server save/load — saves directly to maps.js via API
  • Keyboard shortcuts — 1-7 for tools, Ctrl+S to save, Delete to remove

📁 Project Structure

├── index.html              # Main game page
├── editor.html             # Standalone level editor
├── server.js               # Node.js server (static + API)
├── Dockerfile              # Docker build (node:20-alpine)
├── assets/
│   ├── map/                # PNG map backgrounds (lab, pallet-town, house, route-1)
│   └── character/          # Player sprites (32×32, 4 directions × 3 frames)
│       └── npcs/           # NPC sprites (16×16)
├── css/
│   └── style.css           # Workshop UI styles
├── js/
│   ├── app.js              # Entry point, wires everything together
│   ├── state.js            # Circuit editor state
│   ├── gates.js            # Gate creation and evaluation
│   ├── connections.js      # Wire/connection logic
│   ├── renderer.js         # Circuit editor canvas rendering
│   ├── events.js           # Circuit editor mouse/keyboard events
│   ├── components.js       # Custom component system (save/eval/edit)
│   ├── saveLoad.js         # Circuit serialization
│   ├── levels.js           # Puzzle level definitions
│   ├── constants.js        # Shared constants
│   └── world/
│       ├── gameMode.js     # Mode coordinator (world ↔ workshop)
│       ├── maps.js         # Map definitions (walls, exits, NPCs, interactions)
│       ├── sprites.js      # PNG asset loading and drawing
│       ├── worldRenderer.js# World canvas rendering (map, NPCs, player, HUD, debug)
│       ├── worldInput.js   # World keyboard input (movement, interaction)
│       ├── worldState.js   # World game state (player, dialog, puzzles, gadgets)
│       └── inventory.js    # Gadget backpack (data model + full-screen UI)

🚀 Development

Run locally

npm start          # or: node server.js
# Open http://localhost:3000

Deploy (Docker via Coolify)

docker build -t logic-gates .
docker run -p 3000:3000 logic-gates

Deployed automatically via Coolify on Hetzner at logic.montlab.dev.

API Endpoints

Method Endpoint Description
GET /api/maps Get current maps.js content
PUT /api/maps Update maps.js (creates .bak backup)

🔧 Technical Details

  • Rendering: Vanilla Canvas 2D, no frameworks
  • Modules: ES6 modules (type="module")
  • Tile system: 16px native tiles, 3× scale = 48px on screen
  • Collision: Set<"x,y"> for O(1) wall lookups
  • Player sprite: 32×32 native, drawn at 48×48 (same visual size as 16×16 NPC sprites at 48×48)
  • Camera: Follows player, centered on screen
  • Movement: Interpolated tile-based (0.15s per tile)
  • Circuit evaluation: Fixed-point iteration (max 20 passes) — supports latches/flip-flops
Description
No description provided
Readme 881 KiB
Languages
JavaScript 85.2%
CSS 10.7%
HTML 4%