← All projects

Corne Arcane OLED

Accepted on hardware

A spell duel on a split keyboard's OLED screens, driven by timing and key positions from ordinary typing without retaining text.

CEmbeddedRP2040QMKFirmware

At a glance

  • Outcome: Runs a spell duel and populated city on Corne OLEDs without allocation. Enforces memory budgets and reconstructs both versioned displays from one byte.
  • Status: Accepted v0.4 on hardware in July 2026. The newer checked-in candidate passes automated gates but remains unflashed; v0.4 remains the rollback authority.
  • Role: Led solo design, constraints, gates, diagnostics and validation; reviewed AI-assisted implementation.
  • Stack & libraries: Uses C11, pinned Vial-QMK, native C rigs and Python tests. Provides an optional Python daemon with shell/desktop/browser adapters.
  • Source: Publishes the GPLv2 Vial-QMK derivative at github.com/Griffinhale/corne-arcane-oled.
  • Validation: Uses sanitizers, 548 hashed golden screen states, linker allocation scans, CI budgets and measured hardware gates with rollback artifacts. v0.4 used 85,040 of 90,112 flash bytes.
  • Limitations: Leaves four of five candidate hardware gates open; desktop integration supports Linux only. Illustrative media is not acceptance evidence: it records no observation window/resource budget and supersedes no checklist. C proves constrained systems, not C++ gameplay-engine work.

Interaction

Casts after a short typing pause and brief wind-up. Steady prose lands first blood in about fifteen seconds without a game mode. The duel cannot read or interfere with text; ordinary work controls its pace.

Defines the invented incantation from rhythm, favored rows, hand travel and layer changes, not a key combination. A break casts it. Position-and-timing arithmetic makes identical typing produce the same spell on the keyboard and laptop.

City display

Shows no health bar or spell name. Displays tower floors, a lit room, a resident and a sky with a thirty-minute cycle and sixteen-step celestial arc. Assigns Astral and Mechanical cities to separate halves rather than mirroring them.

Gives the active-floor resident one of five personalities: diligent, curious, nervous, proud or distracted. Gives it one of seven actions: working, walking, inspecting, resting, watching the roof, handling a delivery or reacting to roof damage. The master packs one presentation byte, not coordinates, sprites or pixels. Each half derives identity, action, station and pose from it, the session seed, half, floor, personality and civic phase.

Maps one notification, several or a flood to one messenger, parcel, beacon or sentinel. Volume changes one visitor’s density through plumage, stacked parcels or conduit rays without adding figures. Civic events include a runaway scroll, jammed gear, work break and post-duel damage complaint.

Includes four floors, twin tower silhouettes, couriers, rare events and the full sky cycle in accepted v0.4. The unflashed, hash-pinned candidate expands them into six named districts: Commons, Research, Workshop, Observatory, Scriptorium and Studio. It also adds a three-page Scry almanac for city, duel and host, so these additions are not yet accepted claims.

Split protocol

Runs mechanics only on the master. The slave checks snapshots and renders without replaying mechanics or receiving images. Mismatched versions refuse each other and show a safe local display; reboots rejoin on the next valid snapshot.

Lets QMK emit normal keystrokes while the duel observes only physical switch positions and timing. Keycodes, characters and text never enter the simulation. Uses fixed ticks, integer math, no hidden state and no clock reads, so the same input creates the same testable world without a connected keyboard.

Linux integration

Uses an optional Linux daemon to change the display through bounded signals. A shell hook sends command duration and failure state; the browser bridge sends event kind and intensity. Titles, URLs, commands, paths and typed text have no channel. Host signals expire after one and a half seconds; missing extensions or permissions disable one adapter, and the keyboard works without the daemon.

Fixed a notification monitor that returned eavesdropped D-Bus messages from its filter. GDBus then routed each copy to the daemon, found no notifications path and sent UnknownMethod from the monitor connection. NixOS uses dbus-broker, which terminates monitors that send, so the adapter stopped after its first notification while reporting itself enabled. The fix consumes every message and registers a close handler that reports termination.

Validation

Runs under sanitizers and hashes both screens, so one wrong pixel fails. An image dumper supports visual review. Linker scans cover every module; CI rejects allocator references and exceeded flash or RAM budgets.

Accepted v0.4 through a five-minute two-half session measuring render peaks, free stack, snapshot age, link transfers and unchanged failure counters. Corrected a housekeeping metric that first counted an invalid wait before recording those results.

Tests candidate wizard health at 8 and 10 with matching shaft geometry. Three pinned thirty-minute workloads produced aggregate medians of 237 and 240 seconds, which did not select a value. Two physical sessions remain required. The prewritten tie-break chooses the closer median, or 10 for an exact tie.