游戏 · 音乐 · 硬件 · 工具Games · Music · Hardware · Tools

Zhenhan Li

欢迎浏览我的个人站,小站里放了一点 vibe coding 的半成品。Welcome. This little site holds a few half-finished things I vibe-coded.

作品Works

MUSICA 01 MUSICAMUSICA 海鸥模拟器:整点薯条 02 海鸥模拟器:整点薯条GULL: FRY HEIST 煎饼果子 · 早餐摊 03 煎饼果子 · 早餐摊BREAKFAST CART 芯路 SILICON PATH 04 芯路 SILICON PATHSILICON PATH SINGER 05 SINGERSINGER ROUTINE-WORKS 06 ROUTINE-WORKSROUTINE-WORKS IF · 如果机器 07 IF · 如果机器IF — WHAT IF MACHINE 长雨 08 长雨THE LONG RAIN

我利用到了什么技术Tech I Used

右侧编号是论据:这项技术用在了哪几件作品里,点击可跳转。The numbers are the evidence: which works used this. Click to jump.

01

MUSICAMUSICA

会弹琴,但不知道下一句弹什么You can play. You just do not know what comes next.

桌面应用 · 作曲Desktop app · Composition

看点The Hook

弹一段进去,它先把你的乐句变成能读的谱子,然后给三条刻意不同的续写:稳住、加张力、转个色再回家。每条都带下一个和弦、一条 1 到 8 小节的和弦路径、一段承接你动机的旋律,点一下就能听。右栏会逐条说清它为什么成立——落到具体音级和和弦功能上,不是玄学。挑中一条接受后,可以继续编配成多乐器总谱导出。Play a phrase and it becomes a readable score, then three deliberately different continuations: settle, build tension, turn and come home. Each carries the next chord, a chord path of one to eight bars, and a melody that picks up your motif — audible with one click. The right rail says why each works, in scale degrees and harmonic function rather than vibes. Accept one and you can arrange it into a full multi-instrument score and export.

怎么用How To Use

接一个 MIDI 键盘,录一句,挑方向。创造度、动机保留、节奏活跃度都能调;和声或旋律骨架可以锁死后再重生成。Plug in a MIDI keyboard, record a phrase, pick a direction. Creativity, motif retention and rhythmic activity are adjustable, and harmony or melody can be locked before regenerating.

细节Details

  • 录音保留原始演奏数据——时值、力度、踏板,另生成一份可读的量化谱,两套分开存Recording keeps the raw performance — timing, velocity, pedal — separately from a readable quantized score
  • 系统识别调性、拍号、和声语境、音程轮廓、节奏比例与终止式The system identifies key, meter, harmonic context, interval contour, rhythmic proportions and cadence
  • 每条续写带下一个和弦、1/2/4/8 小节的和弦路径、承接动机的旋律与可试听预览Each continuation carries the next chord, a 1/2/4/8-measure chord path, a motif-aware melody and an audible preview
  • 创造度、动机保留、节奏活跃度可调;和声或旋律骨架可锁死后重生成Creativity, motif retention and rhythmic activity are adjustable; harmony or melody can be locked before regenerating
  • 「为什么成立」落到具体音级与和弦功能上,不是一段漂亮话The "why it works" panel lands on concrete scale degrees and harmonic functions, not prose

技术栈Stack Tauri · CoreMIDI · 五线谱渲染 · 本地和声引擎Tauri · CoreMIDI · staff notation · local harmony engine · github.com/dabaitudiu/musica 私有 · 邮件申请协作者private · email for access

02

海鸥模拟器:整点薯条GULL: FRY HEIST

鸥生只有一个任务A seagull has exactly one job

浏览器 3D · 沙雕休闲Browser 3D · Silly action 浏览器可玩Playable in browser

看点The Hook

你是一只海鸥,默认在天上滑翔,永不坠地。按住俯冲把高度换成速度,贴着栈道掠过端着薯条的游客,一口叼走,再用攒下的速度火箭般拉起。栈道上老少游客各色,有的散步有的坐在长椅沙滩椅上,人人手里端着一盒薯条;你抢完他们会暴怒挥手追打。可以嘎嘎叫,也可以拉屎。一三人称随时切。You are a seagull, soaring by default and never falling. Hold dive to trade altitude for speed, skim the boardwalk past tourists holding chips, snatch one, then rocket back up on the speed you banked. The boardwalk is full of people of all ages, some strolling, some on benches and deck chairs, every one of them holding a box of chips — and they swat at you in fury once you strike. You can squawk. You can also poop. First and third person swap any time.

怎么玩How To Play

鼠标瞄准即航向,空格俯冲,靠近后准星点亮,按 E 叼走。偷够 5 根通关,混乱值 CHAOS 一路升高。The mouse aims and steers, space dives, and E snatches once the reticle lights. Five chips clears it, and the chaos meter climbs the whole way.

细节Details

  • 滑翔按能量守恒:俯冲把高度换成速度,拉起再换回去,所以永不坠地Gliding conserves energy: dive trades altitude for speed, pulling up trades it back — the gull never falls
  • 操控是 pointer lock + 准星钉死屏幕中心:相机看向瞄准方向,视角和瞄准是一件事Controls are pointer lock with the reticle pinned to screen centre: the camera looks down the aim, so view and aim are one thing
  • 逻辑层完全不依赖 three.js,13 项单测直接在 node 下跑The logic layer has no three.js dependency; its 13 unit tests run under node
  • 资产走图生 3D + Tripo 绑骨管线;缺资产时自动用几何体占位,任何就绪度下都能玩Assets come from an image-to-3D + Tripo rigging pipeline, with primitive fallbacks so it plays at any readiness
  • 游客有散步、坐长椅、坐沙滩椅等状态,被抢后暴怒挥手追打Tourists stroll, sit on benches and deck chairs, and swat at you in fury once robbed

技术栈Stack three.js · 图生 3D 资产管线 · Tripo 绑骨three.js · image-to-3D pipeline · Tripo rigging · 尚未建仓 · 可现场演示no repo yet · live demo on request

03

煎饼果子 · 早餐摊BREAKFAST CART

压力不来自倒计时,来自你只有一双手The pressure is not a timer. You have two hands.

浏览器 3D · 经营手感Browser 3D · Cooking sim 浏览器可玩Playable in browser

看点The Hook

清晨街边的三轮车煎饼摊。面糊一落铛就开始烧,你得转圈摊匀、盯着金黄窗口翻面,同时还要蓄豆浆、捞油条、按顾客要求撒葱花香菜刷酱放薄脆。指针只有一个:去蓄豆浆就顾不了刮子。顾客头顶有耐心条,等太久扭头就走。天数往后单量渐增、耐心渐紧,雨天和美食博主会改当天的规则,收摊后拿钱升级摊位。A breakfast cart on a morning street. The batter starts burning the moment it lands, so you circle to spread it and flip inside the golden window while also filling soy milk, fishing out fritters, and dressing each order with scallion, coriander, sauce and crisps. You have one pointer: filling a cup means dropping the scraper. Customers have patience bars and walk off if you stall. Later days bring more orders and less patience; rain or a food blogger rewrites the rules; earnings buy upgrades.

怎么玩How To Play

鼠标在饼铛上转圈摊面糊,火候到点翻面——早生晚糊,完美翻面触发慢镜头。出锅和配餐齐活才能出餐,麻利有速度小费。Circle the mouse on the griddle to spread, then flip on cue — early is raw, late is burnt, and a perfect flip triggers slow motion. Plate only when crepe and sides are both done; speed earns tips.

细节Details

  • 摊面糊实时计算覆盖率;火候从面糊落铛就开始走,金黄窗口翻面,完美触发慢镜头Batter coverage is measured live; heat starts the instant batter lands, with a golden flip window and slow motion on perfect
  • 六个配餐站在烤饼全程随时可做,但指针只有一个——去蓄豆浆就顾不了刮子Six side stations can be worked at any point, but there is one pointer — filling a cup means dropping the scraper
  • 顾客绑定固定 persona,点单、催单、感谢、生气始终同一个声音;共 11 条真人吆喝Each customer binds a persona: ordering, rushing, thanking and fuming always come from the same voice; 11 recorded street cries
  • 天数推进单量渐增、耐心渐紧;雨天、美食博主、早高峰随机事件改当天规则Days escalate orders and tighten patience; rain, a food blogger or a rush hour rewrites the day
  • 台面是 U 形任务流:可辨识的豆浆机和滚油大锅占左右主锚点,判据是「扫一眼能认出来」The counter is a U-shaped task flow anchored by an unmistakable soy-milk machine and a wok of rolling oil
  • 升级配置表驱动,进度存 localStorage;一键打包成静态站发行Upgrades are config-driven, progress persists in localStorage, and the game packages into a static site

技术栈Stack three.js · Blender 手工资产 · 生成式贴图与吆喝语音three.js · Blender assets · generated textures & street cries · github.com/dabaitudiu/jianbing 私有 · 邮件申请协作者private · email for access

04

芯路 SILICON PATHSILICON PATH

从点亮一颗 LED 到造一颗会跑机器码的 CPUFrom one LED to a CPU that runs machine code

浏览器 3D · 硬件教学Browser 3D · Hardware teaching 浏览器可玩Playable in browser

看点The Hook

一张 3D 实验桌摆在你面前:左边是实验手册,中间是能旋转缩放的开发板和面包板,右边是 Verilog 编辑器。流程永远是改代码、综合并烧录、在板子上手动验证、跑测试台过关。你可以拨动拨码开关、按按键、点排针再点数码管引脚拉一根杜邦线,还能暂停时钟单步走。13 关从点亮第一颗 LED 一路走到一颗自己写的 8 位 CPU 跑真实机器码。A 3D lab bench: the manual on the left, a rotatable dev board and breadboard in the middle, a Verilog editor on the right. The loop is always edit, synthesise and program, verify on the board by hand, then run the testbench. You flip DIP switches, hold buttons, draw a jumper wire by clicking a header pin then a seven-segment pin, and pause the clock to step it one cycle at a time. Thirteen levels take you from lighting one LED to an 8-bit CPU of your own running real machine code.

怎么玩How To Play

第 10 关你补全控制器的指令译码,烧录后 LED 会依次亮出 1、1、2、3、5、8、13… 那是你亲手造的 CPU 在跑斐波那契。In level 10 you complete the controller's instruction decode; after programming, the LEDs count out 1, 1, 2, 3, 5, 8, 13 — that is a CPU you built running Fibonacci.

细节Details

  • 编译器与仿真器都是自己写的:assign、always @(posedge)/@(*)、case、模块实例化层级展平、非阻塞赋值语义、组合环检测、reg 数组Both compiler and simulator are in-house: assign, always @(posedge)/@(*), case, hierarchical flattening, non-blocking semantics, combinational loop detection, reg arrays
  • 报错带真实行号;综合日志里的信号、LUT、FF 数字来自真实展平网表Errors carry real line numbers; the signal, LUT and FF counts in the synthesis log come from the actual flattened netlist
  • 3D 实验桌:拨码开关、按键、点排针再点数码管引脚拉杜邦线、时钟暂停/单步/调速A 3D bench: DIP switches, buttons, jumper wires drawn pin to pin, and a clock you can pause, step and throttle
  • 13 关:点亮 LED → 逻辑门 → 加法器 → 译码器 → 计数器 → ALU → 寄存器堆 → 8 位 CPU → 裸写内存 CPU → 指令扩展 → 三级流水线13 levels: one LED → gates → adders → decoder → counter → ALU → register file → an 8-bit CPU → a bare-metal memory CPU → ISA extension → a three-stage pipeline
  • 第 10 关在你写的 CPU 上跑真实机器码,LED 依次亮出斐波那契数列Level 10 runs real machine code on the CPU you wrote; the LEDs count out Fibonacci
  • 45 个测试覆盖编译器语义、CPU 集成与全部关卡可解性;第 13 关带反作弊测试45 tests cover compiler semantics, CPU integration and the solvability of every level; level 13 ships anti-cheat tests

技术栈Stack 自研 Verilog 子集编译器 · 周期精确仿真器 · three.jsIn-house Verilog compiler · cycle-accurate simulator · three.js · 尚未建仓 · 可现场演示no repo yet · live demo on request

05

SINGERSINGER

上传一首歌,换一个歌手Upload a song, swap the singer

自建服务 · 歌声转换Self-hosted service · Voice conversion

看点The Hook

上传一首歌,选一个歌手的声线,等着。它先把人声和伴奏拆开,换掉音色,自动对上音高,再过一条 EQ、混响、响度归一化的后处理链混回伴奏。想加一个新声线也是丢进一段那个人的音频就行,去伴奏、预处理、训练全自动走完,网页上能实时看到 loss 曲线和剩余时间。两个引擎可切:RVC v2 和 so-vits-svc 浅扩散。Upload a song, pick a voice, wait. It splits vocals from backing, swaps the timbre, matches the pitch automatically, then mixes back through a chain of EQ, reverb and loudness normalisation. Adding a new voice is just dropping in audio of that person: separation, preprocessing and training all run themselves, with the loss curve and remaining time live on the page. Two engines to choose from: RVC v2 and so-vits-svc with shallow diffusion.

怎么用How To Use

变调、音色逼真度、辅音保护都摆在页面上;男女声互换会自动升降调。跑在我自己的一台 V100 上。Transpose, index rate and consonant protection are all on the page, and male-to-female swaps transpose themselves. It runs on a V100 of my own.

细节Details

  • Demucs htdemucs_ft 分离人声与伴奏;RVC v2 或 so-vits-svc 4.1 浅扩散换音色;RMVPE 提 F0 自动匹配Demucs htdemucs_ft separates vocals from backing; RVC v2 or so-vits-svc 4.1 with shallow diffusion swaps the timbre; RMVPE matches F0
  • 后处理链:双参考 EQ + 条件混响 + LUFS 归一化,混回伴奏The post chain: dual-reference EQ, conditional reverb, LUFS normalisation, mixed back over the backing
  • 训练全自动:上传音频 → 去伴奏 → 预处理 → 训主模型与扩散模型,支持断点续训Training is hands-off: upload audio → separate → preprocess → train the main and diffusion models, with checkpoint resume
  • 只有一块 V100 16GB:所有任务进同一个 asyncio 优先级队列,单线程 GPU worker 串行消费,试听永远优先于训练One V100 16GB: every job enters a single asyncio priority queue consumed serially, and auditioning always outranks training
  • WebSocket 实时推训练 loss 曲线与 ETALive loss curves and ETA over WebSocket

技术栈Stack RVC v2 · so-vits-svc 4.1 · Demucs · FastAPI · V100 16GBRVC v2 · so-vits-svc 4.1 · Demucs · FastAPI · V100 16GB · 尚未建仓 · 可现场演示no repo yet · live demo on request

06

ROUTINE-WORKSROUTINE-WORKS

让无人值守的开发过程可审计Make unattended development auditable

开发工具 · 质量流水线Dev tooling · Quality pipeline

看点The Hook

一套给自动化开发流程加装质量门与审计留痕的服务。把一个目标拆成若干待办交给它无人值守执行,次日可在观测台回放每条任务的全过程:设计被打回几版、每版的具体意见、代码审查经过几轮、审查器给出什么结论、哪些问题真正修复、哪些被有据否定。偏离目标的任务会被搁置,实测未达标的会被要求诚实结案。A service that fits quality gates and an audit trail onto an unattended development loop. Hand it a goal split into todos, let it run, and the dashboard replays each task the next day: how many times the design was rejected and on what grounds, how many review rounds the code took, what the reviewer concluded, which findings were genuinely fixed and which were refuted with evidence. Off-goal tasks are shelved; work that misses the bar on a real run must close honestly.

怎么用How To Use

一条命令即可接入任意仓库;此后全过程写入账本,观测台可逐轮回放。本作品集其余项目的开发过程均由它监管。One command onboards any repository; from then on the whole process is written to a ledger the dashboard can replay round by round. It supervised the other projects in this portfolio.

细节Details

  • MISSION 是锚:不服务目标的待办直接搁置,执行方只能提议改目标、改不了MISSION is the anchor: off-goal todos are shelved, and the executor may only propose changing the mission, never change it
  • 实质任务必须先封存设计、通过服务端对抗审查,才放行动手Substantive work must seal a design and survive server-side adversarial review before implementation unlocks
  • 质量门由服务端亲自跑真实测试;证据只收 id,再由服务端回读账本——伪造进不了门Quality gates run the real tests server-side; evidence is accepted only as ids the server reads back from its own ledger
  • 真跑未达标必须诚实结案,并拒绝重开同一方向A run that misses the bar must close honestly, and reopening the same direction is refused
  • 全程账本留痕:设计打回几版、每版意见、审查几轮、什么被真修、什么被有据否定,观测台可回放Everything is on the ledger — design rejections, review rounds, what was fixed, what was refuted — replayable in the dashboard
  • 一条命令接入任意仓库;它自身的变更也走同样的门One command onboards any repository; its own changes pass the same gates

技术栈Stack Python · 服务端强制门 · 账本留痕 · 独立 LLM 审查器Python · server-enforced gates · audit ledger · independent LLM reviewer · github.com/dabaitudiu/routine-works 私有 · 邮件申请协作者private · email for access

07

IF · 如果机器IF — WHAT IF MACHINE

把一句「如果…会怎样」变成能进去看的地方Turn a what-if into a place you can enter

浏览器 3D · 反事实推演 · 进行中Browser 3D · Counterfactuals · in progress 浏览器可玩Playable in browser 进行中In progress

看点The Hook

问一个反事实问题,它把地球一分为二:左边是现实,右边是假设,同一套世界模型跑两组参数,中间一条缝可以来回比。从太空一路缩放到地球、城市、街道四个尺度,五个时间透镜看不同时间尺度上的变化。右边观测站按大气、海洋、地质、生物圈、物种、人类系统六类给出能推导的量——重力减半后深水波速从 12.5 掉到 8.84 m/s,旁边就写着那条闭式公式。Ask a counterfactual and it splits the Earth in two: reality on the left, the hypothesis on the right, one world model running two parameter sets with a seam you can drag across. Zoom from space through globe, city and street, with five time lenses for different horizons. The observatory on the right reports derivable quantities across atmosphere, ocean, geology, biosphere, species and human systems — halve gravity and deep-water wave speed drops from 12.5 to 8.84 m/s, with the closed form printed beside it.

怎么用How To Use

「重力减半」这个情景已经能完整走通,月球距离、48 小时制还在做。地球是自己用 three.js 搭的,地理资产离线生成,不依赖任何地图服务。The halved-gravity scenario runs end to end; a nearer Moon and a 48-hour day are still in progress. The globe is hand-built in three.js on offline geoassets, with no map service involved.

细节Details

  • 地球是自己用 three.js 搭的:离线生成的高程格网、海岸线、城市点位,不依赖任何地图服务The globe is hand-built in three.js from offline geoassets — elevation grid, coastlines, populated places — with no map service
  • 反事实是同一套世界模型跑两组参数,中间一条缝可以拖着来回比A counterfactual is one world model running two parameter sets, with a draggable seam between them
  • 太空 / 地球 / 城市 / 街道四个尺度连续缩放;五个时间透镜(现在 / 1 天 / 1 年 / 10 年 / 100 年)Four continuous scales — space, globe, city, street — and five time lenses from now to 100 years
  • 观测站按大气、海洋、地质、生物圈、物种、人类系统六类给出可推导的量,闭式公式印在旁边The observatory reports derivable quantities across six systems, with the closed-form formula printed beside each
  • 重力减半的完整情景:深水波速 12.5 → 8.84 m/s(↓29%)、浪高 ×1.41、洋流 ×0.71The halved-gravity scenario runs end to end: deep-water wave speed 12.5 → 8.84 m/s (−29%), wave height ×1.41, currents ×0.71
  • 中英双语;「月球距离近一倍」「一天 48 小时」两个情景在做Bilingual; the nearer-Moon and 48-hour-day scenarios are in progress

技术栈Stack three.js · 离线地理资产 · 中英双语three.js · offline geoassets · bilingual · 尚未建仓 · 可现场演示no repo yet · live demo on request

08

长雨THE LONG RAIN

雨下了三十天,避难所里的人们还在等天亮Thirty days of rain. They are still waiting for morning.

浏览器 · 合作生存桌游 · 进行中Browser · Co-op survival board game · in progress 浏览器可玩Playable in browser 进行中In progress

看点The Hook

暴雨把城市一点点泡进水里。你带着一群幸存者守在避难所,在行尸、断粮和不断上涨的水位之间撑到救援来。每回合掷行动骰去移动、砸行尸、搜物资、筑路障、清垃圾;抉择事件会塞给你两个都不太好的选项——在走廊拢个炉子烧热水,还是想想煤气中毒的新闻宁可挨冻。机制上致敬《Dead of Winter》,规则全部原创重制。The rain sinks the city block by block. You hold a shelter with a handful of survivors against the walking dead, dwindling food and a rising waterline until rescue comes. Each round you spend action dice to move, fight, search, barricade and clear rubbish, while crossroads events hand you two options that are both bad — light a stove in the corridor for hot water, or remember the gas-poisoning headlines and stay cold. It nods to Dead of Winter with rules rebuilt from scratch.

怎么玩How To Play

开局先选主目标(固守待援 / 撤离行动 / 修复电台)和难度,然后顶着士气、回合数和水位撑下去。UI 面板与地点视频都是生成式管线做的。Pick a main objective (hold out, evacuate, repair the radio) and a difficulty, then survive against morale, the round clock and the waterline. The panels and location videos come from a generative pipeline.

细节Details

  • 单人操作多名幸存者的合作生存桌游:行动骰驱动移动、攻击、搜索、筑路障、清垃圾A co-op survival board game driven by action dice: move, fight, search, barricade, clear rubbish
  • 三个主目标可选(固守待援 / 撤离行动 / 修复电台),难度改变初始士气、回合与行尸数Three objectives — hold out, evacuate, repair the radio — with difficulty setting morale, rounds and walker counts
  • 抉择事件给两个都不太好的选项,选择有后果Crossroads events offer two options that are both bad, and choices have consequences
  • 压力来自四个方向:士气、回合数、不断上涨的水位、六个入口的行尸Pressure comes from four directions: morale, the round clock, the rising waterline, and walkers at six entrances
  • UI 面板与图标是 Seedream 生成的九宫格素材;七段地点循环视频由 Seedance 图生视频Panels and icons are Seedream-generated nine-slice assets; seven looping location videos come from Seedance
  • 机制致敬《Dead of Winter》,规则全部原创重制;平衡用 balance-probe 脚本实测It nods to Dead of Winter with rules rebuilt from scratch, balanced against a probe script

技术栈Stack TypeScript · Vite · Seedream UI 素材 · Seedance 图生视频TypeScript · Vite · generated UI art · image-to-video · 尚未建仓 · 可现场演示no repo yet · live demo on request