Skip to content

integrate Playdate target, host input, and example apps - #205

Merged
doodlewind merged 5 commits into
pocket-stack:mainfrom
colmugx:feat/vapor-playdate
Aug 3, 2026
Merged

integrate Playdate target, host input, and example apps#205
doodlewind merged 5 commits into
pocket-stack:mainfrom
colmugx:feat/vapor-playdate

Conversation

@colmugx

@colmugx colmugx commented Jul 30, 2026

Copy link
Copy Markdown
Contributor
IMG_0028

colmugx and others added 5 commits July 30, 2026 18:46
…under the oracle

vp_pd_render_frame wrote style 0 as raw glyph bytes. Font bits are ink and
Playdate framebuffer bits are white, so every pair rendered inverted from its
declared luminance orientation — the PR's own device photo shows the
bg-white/text-black title bar as white-on-black and the dark-theme body as
dark-on-light, the exact inverse of the styles2 preview and of what GB/NES
render for the same app. Style 0 now clears ink bits onto set paper; the C
harness pins the corrected direction.

The design doc claimed the Playdate Todo replays under the real Vue Vapor
oracle; no test did. bootOracle now takes a bundle entry, entry-playdate.ts
mounts todo.playdate.tsx, and three tests replay boot, signed 45-degree crank
detents with clamping, and edit-mode crank isolation on the 50x30 grid.

Also trims the CLAUDE.md bullet to the enforceable app-facing rule; the
design exposition lives in vapor/DESIGN.md §5.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@doodlewind

Copy link
Copy Markdown
Collaborator

Verdict: fit to merge — this is a model target addition, and it lands with one real rendering bug fixed forward on the branch (1440211). Reviewed with the repo review workflow (skills/pocketjs-review-pr).

The finding: 1bpp polarity was inverted on device

vp_pd_render_frame wrote style 0 as raw glyph bytes and style 1 as ~glyph. Font bits are ink (vapor_esp32.c pins this: bits & 0x80>>x ? ink : paper), and Playdate framebuffer bits are white — your own device photo proves it: the bg-white text-black title bar renders white-on-black, and the dark-theme body renders dark-on-light. Every pair displayed as the exact inverse of its declared luminance orientation, of this PR's own styleTableCss playdate preview (s === 0 → ink #000 on #fff), and of what GB/NES render for the same app under the shared styles2 contract. It photographed fine because complementing every pixel preserves contrast — but it breaks the "same file, every target agrees" invariant.

Fixed to style ? glyph : ~glyph with the semantics stated in a comment, and the C harness now pins the corrected direction (frame[0] == ~0x81 for style 0). Note: a rebuilt .pdx will look color-flipped relative to your photo — dark title text on a white bar, light body text on the dark theme — which is the orientation the oracle preview and DMG render. A fresh device glance when convenient would be welcome, but the direction is proven by the photo + the ink/white bit semantics, so I didn't hold the merge on it.

Second gap: the oracle replay was claimed, not present

DESIGN.md says the Playdate Todo "is also replayed through the real Vue Vapor oracle with signed Primary-axis deltas" — no test booted todo.playdate.tsx; entry.ts hardcodes todo.tsx, so the new axisDelta hook had no listener. Rather than edit the claim down, I made it true: bootOracle takes a bundle entry, entry-playdate.ts mounts the crank variant, and three tests replay boot on the 50×30 grid, signed 45° detents with sub-detent accumulation and end-clamping, and edit-mode crank isolation. The grid-line assertions passed on first run — the app and oracle plumbing were already correct.

What was verified as-is

  • Taxonomy: Playdate slots into VAPOR_TARGETS as data; the BOARDS.md addition correctly argues why a fixed SDK target is not an ESP32-style board JSON. relativeAxesUsed joins buttonsUsed as a derived demand; VT101/VT102 admission errors extend the existing VB/VS-code convention without collision.
  • RelativeAxis contract: hardware-neutral signed millidegrees, apps own detents — the runtime preserves sub-millidegree remainders across frames, drains docked/lifecycle motion (no ghost events), and the C runtime harness pins all of it against a fake SDK table. The dev server's wheel adapter uses the same accumulation. This is the right shape for the future ESP32 encoder, and BOARDS.md records that follow-up honestly.
  • Emitted-C changes for existing targets (condition() paren trim, app_on_axis_delta stub, VP_UNUSED_FN): behavior-neutral, proven by the GBA/GB/NES emulator per-press parity suites passing unchanged. esp32BuildId shifts for identical sources as a consequence — that is the documented contract (the id follows generated code + runtime sources; the board-half pin in boards.test.ts is untouched), so a pre-integrate Playdate target, host input, and example apps #205 MeowBit will correctly report stale on vapor:esp32:verify.
  • Passing doc-rot fix: the screen.ts "NES 24x20" comment was stale; 22×18 matches VAPOR_TARGETS.nes.
  • pd_api.h in the test harness is a 62-line clean-room shim (function-pointer tables + enum values, no SDK expression). No new deps; vapor/ stays outside the npm files map.
  • CLAUDE.md: kept your rule, trimmed to the enforceable sentence — the design exposition lives in DESIGN.md §5.

Local gate

  • bun run vapor:test: 67 pass, 0 fail (64 from the branch + 3 new oracle-replay tests; includes both C harnesses under -Wall -Wextra -Werror and the GBA/GB/NES parity replays)
  • bunx tsc --noEmit -p vapor and root bunx tsc --noEmit: clean
  • Root bun run test: 450 pass, 0 fail (base-relative)
  • Real SDK smoke on this machine (SDK 3.x at ~/Developer/PlaydateSDK): simulator .pdx builds and validates end-to-end (51.3 KB). The device build needs the newlib-bearing ARM GNU toolchain that Panic's arm.cmake assumes — Homebrew's bare arm-none-eabi-gcc stops at stdint.h — so device evidence remains your on-hardware photo, which is exactly what runtime/playdate/README.md prescribes.

@doodlewind
doodlewind merged commit 88b2812 into pocket-stack:main Aug 3, 2026
@colmugx
colmugx deleted the feat/vapor-playdate branch August 3, 2026 07:02
doodlewind added a commit that referenced this pull request Aug 5, 2026
The landing page (and site title/description) now leads with the core
value proposition — a compact JavaScript runtime for building UI, games,
3D experiences and AI-native applications across radically different
devices — instead of the device-first "impossible devices" hero, which
moves down to anchor the device-taxonomy section.

- Hero: "Rich interactive JavaScript where no browser fits." with the
  four software pillars and "radically different devices" in the sub;
  eyebrow now points at the Octane post (the newest one).
- New pillars section after the proof strip: user interfaces / games /
  3D experiences / AI-native apps, each claim backed by a shipped link
  (frameworks doc, OpenStrike, Pocket Character, the flake post +
  pocket-pi).
- Proof strip: the Symbian cell becomes "Three frameworks, one core"
  (Octane).
- Targets: Octane named in the lead and reactivity card; new Playdate
  tab (Pocket Vapor AOT, crank as a signed relative axis, .pdx).
- Devices: kicker/lead adopt "radically different"; "Retro consoles"
  becomes "Consoles & handhelds" and gains a live Playdate chip (#205),
  mirrored in the JSON-LD platform list.
- System software: the Input & OSK card catches up with the touch stack
  (gestures, kinetic scroll, tap-to-press).
- og:image:alt now derives from SITE_TITLE instead of a hardcoded copy
  of the old tagline.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
doodlewind added a commit that referenced this pull request Aug 5, 2026
The landing page (and site title/description) now leads with the core
value proposition — a compact JavaScript runtime for building UI, games,
3D experiences and AI-native applications across radically different
devices — instead of the device-first "impossible devices" hero, which
moves down to anchor the device-taxonomy section.

- Hero: "Rich interactive JavaScript where no browser fits." with the
  four software pillars and "radically different devices" in the sub;
  eyebrow now points at the Octane post (the newest one).
- New pillars section after the proof strip: user interfaces / games /
  3D experiences / AI-native apps, each claim backed by a shipped link
  (frameworks doc, OpenStrike, Pocket Character, the flake post +
  pocket-pi).
- Proof strip: the Symbian cell becomes "Three frameworks, one core"
  (Octane).
- Targets: Octane named in the lead and reactivity card; new Playdate
  tab (Pocket Vapor AOT, crank as a signed relative axis, .pdx).
- Devices: kicker/lead adopt "radically different"; "Retro consoles"
  becomes "Consoles & handhelds" and gains a live Playdate chip (#205),
  mirrored in the JSON-LD platform list.
- System software: the Input & OSK card catches up with the touch stack
  (gestures, kinetic scroll, tap-to-press).
- og:image:alt now derives from SITE_TITLE instead of a hardcoded copy
  of the old tagline.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
doodlewind added a commit that referenced this pull request Aug 5, 2026
The landing page (and site title/description) now leads with the core
value proposition — a compact JavaScript runtime for building UI, games,
3D experiences and AI-native applications across radically different
devices — instead of the device-first "impossible devices" hero, which
moves down to anchor the device-taxonomy section.

- Hero: "Rich interactive JavaScript where no browser fits." with the
  four software pillars and "radically different devices" in the sub;
  eyebrow now points at the Octane post (the newest one).
- New pillars section after the proof strip: user interfaces / games /
  3D experiences / AI-native apps, each claim backed by a shipped link
  (frameworks doc, OpenStrike, Pocket Character, the flake post +
  pocket-pi).
- Proof strip: the Symbian cell becomes "Three frameworks, one core"
  (Octane).
- Targets: Octane named in the lead and reactivity card; new Playdate
  tab (Pocket Vapor AOT, crank as a signed relative axis, .pdx).
- Devices: kicker/lead adopt "radically different"; "Retro consoles"
  becomes "Consoles & handhelds" and gains a live Playdate chip (#205),
  mirrored in the JSON-LD platform list.
- System software: the Input & OSK card catches up with the touch stack
  (gestures, kinetic scroll, tap-to-press).
- og:image:alt now derives from SITE_TITLE instead of a hardcoded copy
  of the old tagline.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants