Skip to content

cagedbird043/brilliant-sort

Repository files navigation

Brilliant Sort

English · 简体中文

English

A deterministic, playable web slice of a Brilliant Sort-style gem puzzle. The browser drives a headless C++20 BrilliantSortCore compiled to WebAssembly; the original TypeScript reducer remains only as a differential-test oracle.

Live demos: https://cagedbird043.github.io/brilliant-sort/ · https://brilliant-sort.cagedbird.cn/

Assessment submission: SUBMISSION.md · PDF · Evidence matrix

Post-submission correction: source-video review showed that removing an articulation gem may leave a disconnected Selection lifted. The immutable submission remains linked above; the current implementation and regression evidence live in correct-selection-snapshot-semantics.

What is implemented

  • The compiled 24×32 tux-01 flagship fixture: 546 active sockets, a deterministic 75.09% locked opening, and a sixteen-slot Shelf.
  • Same-color movable eight-neighbor component creation with a latched Gem-ID Selection snapshot; partial extraction may leave a disconnected remainder selected.
  • Matching target-component placement, compact configured Shelf storage, and ordered two-bank presentation.
  • A deterministic apply-global-wand demo assist shared by TypeScript, native C++, and WASM: locked gems stay fixed while every remaining identity is paired to its target, the Shelf is cleared, and victory is emitted once.
  • Responsive desktop/square/portrait Tux staging with integer fit, bounded zoom/pan, ordinary WAAPI flight, a diagonal full-board wand wave, and a shared SVG arc-light plus three pixel-firework victory finale.
  • A contextual post-finale replay control that dispatches the canonical restart command, restores the initial Board and camera, and keeps onboarding/audio preferences without reloading the page.
  • A separate deterministic C++20 pixel-audio engine compiled to AudioWorklet WASM, with gameplay cues, first-gesture resume, persisted in-world mute, silent failure fallback, and an ordered replay reset cue so every run can play its victory fanfare.
  • Canonical replay, browser E2E, byte-exact TypeScript ↔ native C++ ↔ WebAssembly differential verification, and a 32-seed deterministic reducer state-machine property sweep.
  • One-sentence, versioned onboarding that disappears only after an accepted puzzle or wand command and remains non-blocking when browser storage is unavailable.
  • Pinned Lefthook local gates: parallel type/unit/fixture/spec checks before commit, then native/WASM/build/browser verification plus native ASan/UBSan and an exercised audio-queue TSan path before push.
  • Official OpenSpec 1.6 skills and commands checked into the repository for Oh My Pi, Codex, Claude Code, and OpenCode.

The built-in wand is a deterministic, non-commercial demo assist. Commercial power-ups, payment, random generation, random mode, and progression are intentionally deferred. See openspec/ for the evidence boundary and acceptance contracts.

Run locally

bun install

# One local, ignored Emscripten 6.0.3 toolchain setup.
git clone --depth 1 --branch 6.0.3 https://github.com/emscripten-core/emsdk.git .cache/emsdk
.cache/emsdk/emsdk install 6.0.3
.cache/emsdk/emsdk activate 6.0.3

bun run dev

Open the Vite URL printed by the command. bun run dev builds the game-core and pixel-audio WASM modules before starting Vite. The production app is static:

bun run build

Deployments

main continues to publish the GitHub Pages build at /brilliant-sort/. After the same verification job passes, publish-hk downloads a separate root-based static artifact, rsyncs it to an immutable release under /srv/cagedbird/brilliant-sort/releases/<sha>, and atomically switches Caddy's current symlink for https://brilliant-sort.cagedbird.cn/.

The Hong Kong job uses the repository secret HK_EDGE_DEPLOY_KEY, a pinned SSH host key, and a restricted remote key without shell forwarding. Caddy serves the site directly with compressed responses, immutable hashed assets, and uncached HTML; no origin application process or reverse proxy is needed for this static WASM game.

Pixel asset pipeline

pixel-bloom turns one reviewed pixel-art PNG master into a validated family of semantic palette variants. It runs locally with Bun; no AI API, service, or image editor is required after the source art has been approved.

bun run pixel-bloom inspect art/inbox/<master>.png --json
bun run pixel-bloom derive \
  --source art/inbox/<master>.png \
  --palette art/palettes/brilliant-sort.json \
  --out art/review/pixel-bloom/gems
bun run pixel-bloom preview \
  --sprites art/review/pixel-bloom/gems \
  --out art/review/pixel-bloom/index.html

The CLI rejects fake transparency, translucent v1 source pixels, and undeclared opaque palette noise. The project-local pixel-asset-pipeline workflow requires inspect → derive → preview → human approval before art is promoted into the game.

Flagship fixture and pixel audio

The reviewed compact map at src/fixtures/source/tux-01.map.json is the authoring source for the canonical LevelSpec; prism-01 remains a focused regression fixture. The committed Tux trace wins identically in the TypeScript oracle, native C++ core, and production WASM core. The same parity gate covers initial and mid-game global-wand solves: one aggregate global-wand-applied event followed by one won, with identical canonical state in all three backends.

bun run level:compile:tux
bun run level:check:tux
bun run harness replay tux-01
bun run harness differential tux-01

Pixel music and effects are synthesized by cpp/audio/ from the constrained score in src/audio/tux-01.music.json. The browser loads the raw standalone audio WASM only through an AudioWorklet; no PCM or tracker asset is shipped.

bun run build:cpp
.cache/cmake/pixel_audio_offline_renderer --seconds 8

Verify

bun run typecheck
bun run test:cpp
bun run test:wasm
bun run test:differential
bun run test:e2e
bun run test:cpp:sanitized
bun run test:cpp:tsan
bun run spec:validate

bun run check runs typechecking, native C++ tests, WASM build, TypeScript/WASM/native differential tests, and a Vite production build. The separate sanitizer gates run the same four native CTests under ASan/UBSan and TSan; the TSan path includes a 10,000-cue concurrent SPSC transfer rather than an idle sanitizer badge. Browser E2E requires Chromium installed through Playwright:

bunx playwright install chromium

bun install installs the pinned Lefthook runner. Install or refresh the Git hooks explicitly, then exercise the same local gates without creating a commit:

bun run hooks:install
bunx lefthook run pre-commit --all-files
bunx lefthook run pre-push --all-files

Pre-commit runs typecheck, Bun tests, fixture drift, and strict OpenSpec validation in parallel. Pre-push runs the native/WASM/production build, native ASan/UBSan, the exercised audio-queue TSan path, desktop/mobile Playwright, fixture drift, and strict specs sequentially so shared build outputs cannot race.

Replay the flagship fixed trace through the production WASM core, or run the three-backend Harness gate:

bun run harness replay tux-01
bun run harness differential tux-01

Use prism-01 with the same commands for the compact regression fixture.

Architecture

cpp/             C++20 BrilliantSortCore, C ABI, CMake targets, and component exercise
cpp/audio/       Fixed-capacity pixel synth, constrained Tux score, worklet ABI, and offline renderer
src/core/        Versioned state types, dump format, and TypeScript differential oracle
src/wasm/        Emscripten module declaration and GameCorePort adapter
src/audio/       Cue bridge, persisted browser port, AudioWorklet processor, score, and audio WASM
src/fixtures/    Compact Tux authoring map, generated LevelSpec fixtures, and replay traces
src/app/         React Tux stage, adaptive camera, accessibility, and authoritative motion
src/harness/     GameCorePort replay, native/WASM differential diagnostics, and CLI
src/assets/      Promoted large and Micro pixel families consumed by the browser bundle
src/agent/       Constrained agent context and auditable validation records
src/pixel-bloom/ Deterministic PNG inspection, palette derivation, and preview CLI
tools/           Deterministic compact-map compiler
art/             Candidate inbox, versioned palette manifests, and review artifacts
.agents/skills/  Project-local agent workflows
lefthook.yml     Fast pre-commit and complete pre-push local quality gates
.omp/.codex/     Generated OpenSpec skills for Oh My Pi and Codex
.claude/         Generated Claude Code OpenSpec skills and `/opsx:*` commands
.opencode/       Generated OpenCode OpenSpec skills and commands
openspec/        Product rules, design, requirements, and task contracts

The deployed artifact is dist/; production does not require a Bun daemon or backend service.

License

MIT


简体中文

English · 简体中文

一个确定性的 Brilliant Sort 宝石拼图核心、Harness 与可在线游玩的 Web Demo。浏览器通过 WebAssembly 驱动无头 C++20 BrilliantSortCore;原始 TypeScript reducer 仅保留为独立差分 Oracle。

在线试玩:GitHub Pages · Hong Kong 生产站

笔试材料:SUBMISSION.md · PDF · 需求证据矩阵

提交后纠正:复核题目视频后确认,移走割点宝石时,已经抬起的 Selection 即使断成多块也会继续保持选中。上方提交材料保持不变;当前实现与回归证据见 correct-selection-snapshot-semantics

已实现内容

  • 编译后的 24×32 tux-01 旗舰关卡:546 个有效 Socket、确定性的 75.09% 初始锁定比例和 16 槽 Shelf。
  • 同色可移动宝石在创建 Selection 时按八方向连通;Selection 随后锁存 Gem ID,部分提取后剩余成员即使断开也继续保持选中。
  • 匹配目标组件放置、紧凑且可配置容量的 Shelf 存储,以及有序的双 Bank 表现。
  • 确定性的 apply-global-wand Demo 辅助命令由 TypeScript、原生 C++ 和 WASM 共同实现:锁定宝石保持不动,其余宝石身份全局配对到目标,Shelf 清空,并且只产生一次胜利。
  • 自适应桌面/方屏/竖屏 Tux 舞台:整数尺寸拟合、受限缩放/平移、普通 WAAPI 飞行、对角线全图魔法棒波次,以及手动/魔法棒通关共用的 SVG 弧光与三组像素烟花终章。
  • 终章结束后,右上角魔法棒会换成重玩按钮;它走 canonical 重开命令,复原初始棋盘和相机,同时保留新手提示与音频偏好,不刷新页面。
  • 独立的确定性 C++20 像素音频引擎,编译到 AudioWorklet WASM,支持玩法 Cue、首次交互恢复、场景内静音持久化、静默失败降级,以及按顺序处理的重玩重置 Cue,保证每一局都能再次播放胜利音乐。
  • Canonical replay、浏览器 E2E、TypeScript ↔ 原生 C++ ↔ WebAssembly 的逐字节差分验证,以及 32 个固定 seed 的 reducer 状态机属性扫描。
  • 版本化的一句话新手提示:仅在首次接受的棋盘/Shelf/魔法棒命令后消失;浏览器存储不可用时仍不阻塞游戏。
  • 固定版本的 Lefthook 本地门禁:提交前并行检查类型、单测、夹具和规格;推送前再跑 native/WASM/生产构建、浏览器 E2E、原生 ASan/UBSan,以及真正并发执行音频队列的 TSan。
  • 仓库内直接提供 OpenSpec 1.6 为 Oh My Pi、Codex、Claude Code、OpenCode 生成的技能与命令。

内置魔法棒是确定性的非商业 Demo 辅助。商业 Power-up、付费、运行时随机生成、随机模式和进度系统均被明确延后。证据边界和验收契约见 openspec/

本地运行

bun install

# 一份本地、被 Git 忽略的 Emscripten 6.0.3 工具链。
git clone --depth 1 --branch 6.0.3 https://github.com/emscripten-core/emsdk.git .cache/emsdk
.cache/emsdk/emsdk install 6.0.3
.cache/emsdk/emsdk activate 6.0.3

bun run dev

打开命令打印出的 Vite URL。bun run dev 会先构建游戏核心和像素音频 WASM,再启动 Vite。生产产物为静态文件:

bun run build

部署

main 会持续发布 GitHub Pages 构建到 /brilliant-sort/。同一验证任务成功后,publish-hk 下载独立的根路径静态产物,rsync 到 /srv/cagedbird/brilliant-sort/releases/<sha> 下的不可变发布目录,并原子切换 Caddy 的 current 符号链接,服务于 https://brilliant-sort.cagedbird.cn/

香港发布任务使用仓库 Secret HK_EDGE_DEPLOY_KEY、固定 SSH 主机密钥和禁止 shell forwarding 的受限远端密钥。Caddy 直接提供压缩响应、不可变哈希资源和无缓存 HTML;这个静态 WASM 游戏不需要源站应用进程或反向代理。

像素资源管线

pixel-bloom 将一个经过评审的像素 PNG 主素材派生为经验证的语义调色板变体。它通过 Bun 在本地运行;源图获批后不需要 AI API、服务或图像编辑器。

bun run pixel-bloom inspect art/inbox/<master>.png --json
bun run pixel-bloom derive \
  --source art/inbox/<master>.png \
  --palette art/palettes/brilliant-sort.json \
  --out art/review/pixel-bloom/gems
bun run pixel-bloom preview \
  --sprites art/review/pixel-bloom/gems \
  --out art/review/pixel-bloom/index.html

CLI 会拒绝伪透明、v1 源图中的半透明像素,以及未声明的不透明调色板噪声。项目内的 pixel-asset-pipeline 流程要求 inspect → derive → preview → 人工批准 后,才能把资源提升到游戏消费目录。

旗舰关卡与像素音频

已评审的紧凑地图 src/fixtures/source/tux-01.map.json 是 canonical LevelSpec 的作者输入;prism-01 保留为聚焦回归夹具。提交的 Tux 轨迹会在 TypeScript Oracle、原生 C++ 核心和生产 WASM 核心中完全相同地胜利。 同一 parity 门禁覆盖初始和中途状态的一键全局修复:三个后端都只产生一个 global-wand-applied 聚合事件和一个 won,最终 canonical 状态完全一致。

bun run level:compile:tux
bun run level:check:tux
bun run harness replay tux-01
bun run harness differential tux-01

像素音乐和效果由 cpp/audio/ 根据受约束的 src/audio/tux-01.music.json 合成。浏览器只通过 AudioWorklet 加载原始的独立音频 WASM;不携带 PCM 或 tracker 资源。

bun run build:cpp
.cache/cmake/pixel_audio_offline_renderer --seconds 8

验证

bun run typecheck
bun run test:cpp
bun run test:wasm
bun run test:differential
bun run test:e2e
bun run test:cpp:sanitized
bun run test:cpp:tsan
bun run spec:validate

bun run check 会运行类型检查、原生 C++ 测试、WASM 构建、TypeScript/WASM/原生差分测试和 Vite 生产构建。两个独立的 sanitizer 门禁会在 ASan/UBSan 与 TSan 下重跑 4 个原生 CTest;TSan 路径包含 10,000 个 Cue 的并发 SPSC 传输,不是空跑工具。浏览器 E2E 需要通过 Playwright 安装 Chromium:

bunx playwright install chromium

bun install 会安装固定版本的 Lefthook。可以显式安装/刷新 Git Hook,再手动跑一遍相同门禁:

bun run hooks:install
bunx lefthook run pre-commit --all-files
bunx lefthook run pre-push --all-files

Pre-commit 并行运行 typecheck、Bun 测试、夹具漂移和严格 OpenSpec;pre-push 顺序运行 native/WASM/生产构建、原生 ASan/UBSan、真正执行音频队列并发传输的 TSan、desktop/mobile Playwright、夹具漂移和严格规格,避免共享构建目录互相打架。

可以通过生产 WASM 核心回放旗舰固定轨迹,或运行三后端 Harness 门禁:

bun run harness replay tux-01
bun run harness differential tux-01

对紧凑回归夹具使用相同命令并将 tux-01 替换为 prism-01

架构

cpp/             C++20 BrilliantSortCore、C ABI、CMake target 与连通分量练习
cpp/audio/       固定容量像素合成器、受约束 Tux 乐曲、Worklet ABI 与离线渲染器
src/core/        版本化状态类型、dump 格式和 TypeScript 差分 Oracle
src/wasm/        Emscripten 模块声明和 GameCorePort 适配器
src/audio/       Cue 桥、持久化浏览器端口、AudioWorklet 处理器、乐曲和音频 WASM
src/fixtures/    紧凑 Tux 作者地图、生成的 LevelSpec 夹具和回放轨迹
src/app/         React Tux 舞台、自适应相机、无障碍与权威动画
src/harness/     GameCorePort 回放、native/WASM 差分诊断和 CLI
src/assets/      浏览器 Bundle 消费的已提升 Large 与 Micro 像素资源家族
src/agent/       受约束的 Agent 上下文和可审计验证记录
src/pixel-bloom/ 确定性 PNG 检查、调色板派生和预览 CLI
tools/           确定性紧凑地图编译器
art/             候选 inbox、版本化调色板 manifest 和评审产物
.agents/skills/  项目内 Agent 工作流
lefthook.yml     快速 pre-commit 与完整 pre-push 本地质量门禁
.omp/.codex/     Oh My Pi 与 Codex 的 OpenSpec 技能
.claude/         Claude Code 的 OpenSpec 技能和 `/opsx:*` 命令
.opencode/       OpenCode 的 OpenSpec 技能和命令
openspec/        产品规则、设计、需求和任务契约

部署产物为 dist/;生产环境不需要 Bun daemon 或后端服务。

许可证

MIT

About

Deterministic Brilliant Sort core, Harness & playable web demo / 确定性核心、Harness 与可玩 Web Demo

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages