Handmade Hero 学习路线 Rust · Arch Linux · 全 667 集

从零到 Handmade Hero

用 Rust + 跨平台库,完整跟做 Casey Muratori 的 667 集游戏引擎教科书
✨ 增强版 — 每个 Phase 附带三层递归心智模型讲解(鸟瞰 → 原理 → 推导)
0%
已完成
0
/ 0
剩余
0
预估剩余
周(每周 5.5 集)
连续天数
0
下一集
最近完成
还没有完成的集数,从 Day 001 开始吧!

这份路线在做什么

Handmade Hero 是 Casey Muratori 历时两年,从空文件夹到一个完整可玩游戏,每行代码都在视频里讲清楚的项目。原作是 C/C++ + Win32 + DirectSound + OpenGL,但你讨厌平台特定 API,所以这份路线把所有平台相关代码翻译成 Rust 的跨平台等价物——winit 管窗口、softbuffer 显示后缓冲、cpal 输出音频、gilrs 读手柄、libloading 做热重载、glutin+glow 在 Day 235 后接管 OpenGL。

学习目标不是「记住 winit 怎么用」,而是吃透每一行代码背后的原理——为什么 Casey 要把游戏代码做成 cdylib、为什么实体系统用索引不用指针、为什么 SIMD 必须 aligned、为什么光照要在 linear 空间计算、为什么 Casey 最后把 Minkowski 碰撞改成体素化方案。所有可以「用库」的地方(PNG、WAV、字体光栅、声音混音、内存分配器)Casey 都是从零写的,你也得从零写。

这是约 2.3 年的工程(每周 10–15 小时)。每一集配一个 checkbox,看完一集打勾,进度自动保存;可以用三个存档槽(左侧栏)把进度外化到同目录的 JSON 文件,就像游戏的存档/读档。每个 Phase 里有保姆级的中文讲解,每集配中文翻译 + 难度 + 类型 + 「本集你将学到」。下面还有 37 张概念卡,把 HH 用到的所有黑话(sRGB、Minkowski、depth peeling、SIMD...)都讲清楚。

🧠 递归式心智模型:从总图到细节

这份路线不是只让你“看懂代码”,而是让你不断建立可在脑中运行的系统模型。每一集都先问四个层次的问题:我现在处在系统的哪一层?这一层解决什么问题?这一层背后的原理是什么?我能不能不看代码就复述它怎么工作?

1

总图层

先知道整套系统的边界:输入从哪里来,状态放在哪,输出到哪里去,平台层和游戏层怎么分工。

  • 关注“数据流”而不是“函数名”
  • 先记住模块之间的关系
  • 先回答“它为什么存在”
2

流程层

把一帧的执行顺序画出来:初始化 → 读取输入 → 更新游戏状态 → 生成渲染命令 → 显示/播放/同步。

  • 关注“先后顺序”
  • 把主循环想成一条流水线
  • 问自己“下一步为什么必须先做这个”
3

原理层

理解视频背后的理论:为什么要双缓冲、为什么要热重载、为什么要用索引而不是指针、为什么要做线性空间光照。

  • 每次只抓一个核心原理
  • 先理解“问题”,再理解“方案”
  • 补上视频默认你已经会的背景知识
4

实现层

最后才进入代码细节:具体 API、结构体字段、生命周期、unsafe 边界、错误处理、调试方法。

  • 把代码当成“原理的落地”
  • 每段实现都写一句自己的解释
  • 能脱离源码复述,才算真的懂

🧭 这份路线的使用方式

看任何一集之前,先用一句话回答:这一集属于哪个层级、它在整个系统里补上了什么缺口。看完后,再用自己的话把“总图 → 流程 → 原理 → 代码”复述一遍。复述不出来的地方,就回到更高层补课,而不是直接死磕细节。

🛠️ 起步指南(保姆级)

在开始 Day 001 之前,先按这 8 步把环境搭好。每一步都给了可以复制粘贴的命令。如果你是 Linux/Rust 新手,不要跳步——后面跟 HH 的时候出问题,90% 都是基础环境问题。

🔧 技术栈对照表

原作的 Win32/C++ 翻译成下面的 Rust 跨平台方案。所有「原作手写」的部分(PNG/WAV/字体/mixer/分配器/软渲染器/debug 系统)继续手写——这才是 Handmade Hero 的核心价值。

原作 (Win32/C++)Rust 跨平台等价用在哪
CreateWindowEx + message loopwinit窗口与事件循环
StretchDIBits(后缓冲显示)softbufferDay 1–234 软渲染阶段
wglCreateContext + wgl 扩展glutin + glowDay 235+ OpenGL 阶段
QueryPerformanceCounterstd::time::Instant帧时间
__rdtscstd::arch::x86_64::_rdtscCPU 周期计数
DirectSoundcpal(原始流)音频输出,mixer 自己写
XInputgilrs手柄输入
CRITICAL_SECTION / CreateThreadstd::sync + std::thread线程与同步
LoadLibrary + 动态重载libloadingDay 21–23 热重载
Win32 File APIstd::fs + std::io文件 I/O
手写 PNG/WAV/字体光栅/声音 mixer/分配器全部手写跟 Casey 一致

明确不用: SDL2(藏太多细节)、minifb(切换 OpenGL 成本高)、rodio(藏 mixer)、image/hound/rusttype(违背「自己写」原则)、wgpu(太现代,与 HH 教学路线不符)。

💡 核心概念卡(37 张)

HH 全剧反复用到的核心概念。点击卡片看详细解释 + Casey 哪几集用到 + 深入学习资源。建议在跟到对应 Phase 前先扫一遍该 Phase 用到的卡。

⏱️ 每集工作流(单集 1.5–3 小时)

  1. 看视频 — 用 guide.handmadehero.org 看 Casey 自己做的逐行注释版。Q&A 和 Bug-fix 集可以 1.5–2x 速听。
  2. 读源码 diffgithub.com/HandmadeHero/cpp 的 commit,或本地 git log -p --follow
  3. 笔记:在项目的 notes/day-NNN.md 记录:Casey 这集讲了什么、哪些是 Win32-ism 翻译成什么 Rust 等价物、涉及的 CS 概念。也可以在每集下方的「笔记」框里写。
  4. 实现:严格跟着 Casey 的代码结构,不要发挥。Rust 学习者最大的诱惑是「用更 Rusty 的方式重写」——这会让你和 Casey 的代码偏离,后面调试就麻烦了。
  5. 验证:运行后看画面是否与 Casey 当天的截图一致。声音、输入、性能都要对得上。
  6. 提交:git commit -m "Day NNN: <title>"。强制自己每天一个 commit,长期下来就是完整学习记录。
  7. 每周日复盘:在 journal.md 写这周学了什么、卡在哪里、下周重点。
  8. 回来打勾:回到这份 HTML,把对应 Day 的 checkbox 打勾,进度自动保存。建议每集打勾时顺手存档到 Slot 1。

🎯 关键里程碑(庆祝点)

  • M1 (Day 25): 平台层完成,屏幕上有会动的方框,热重载生效。
  • M2 (Day 70): 完整可玩 2D 关卡,有怪物、攻击、投射物。
  • M3 (Day 121): 🔥🔥🔥 SIMD 软渲染 tiled marathon 完成。
  • M4 (Day 175): 字体能渲染,内存分配器完工。
  • M5 (Day 234): Debug 系统完成,有自己的 profiler。
  • M6 (Day 260): OpenGL 迁移完成。
  • M7 (Day 435): 光照系统完工(此时已是 Handmade Hero 高手)。
  • M8 (Day 575): 光探针完工,有 in-game 编辑器、世界生成器。
  • M9 (Day 667): 🎉 全剧终——体素碰撞、k-d tree raycaster、octahedral 光照、实体存储简化收官。

⚠️ 风险与应对

风险应对
卡在某个 Day 几天没进展notes/day-NNN-stuck.md 记录卡点,跳过去做下一集,周末回头
跟着跟着忘了前面的概念每个 Phase 末尾花 1 周复习 + 整理 notes/index.md
Day 235 切 OpenGL 时炸了这周专门停下来,先把 glutin+glow 单独跑通三角形,再回来
Day 112+ SIMD 学不动提前补 CS:《Computer Systems: A Programmer's Perspective》第 5 章
Day 436+ PNG 解码太难官方 PNG spec (w3.org/TR/png) 一节一节对照,Casey 也是这么讲的
Day 590+ k-d tree/grid raycaster 转不过弯把 Handmade Ray 系列(ray00–ray04,5 集)作为前置热身
Day 638+ 体素碰撞重构工程量太大Casey 自己也花了 8 集才搞定,允许自己慢
半途而废找学习伙伴或社区(Handmade Network 论坛、r/HandmadeHero、B 站跟做群),每周汇报进度

🧠 游戏引擎的全局心智模型

在看第一行代码之前,先在脑子里建立这个可运行的模型。能把下面三层说清楚,整个 HH 就不会迷失方向。

L0 最顶层:游戏主循环(60 次/秒)
// 每 1/60 秒执行一次:
1. 读输入    ← 键盘 / 手柄 / 鼠标状态
2. 更新状态  ← 物理 / AI / 碰撞 / 游戏逻辑
3. 渲染      ← 状态 → 一帧像素(写 framebuffer)
4. 播音频    ← 状态 → 音频样本(写 audio buffer)
// 回到 1
L1 架构层:平台 / 游戏 彻底分离
平台层(不变的)
• 创建窗口 / 事件循环
• 帧缓冲 → 屏幕
• 音频回调 → 声卡
• 输入设备轮询
• 热重载游戏 .so
• 内存分配(大块)
游戏层(你的创作)
• 读输入 → 更新实体状态
• 碰撞检测 / 物理
• AI / 游戏逻辑
• 生成渲染命令
• 生成音频样本
完全不知道自己在什么 OS 上
L2 数据流层:一帧内字节的完整旅程
输入设备OS 驱动平台层轮询GameInput 结构体游戏更新函数Push Buffer(渲染命令列表)软渲染器/OpenGL像素数组buffer.present()屏幕
✅ 开始 Phase 1 之前的自检
如果你能不看任何资料,向另一个人完整解释上面三层,并回答这个问题——
「为什么热重载(Day 21-23)不需要重启程序?游戏状态存在哪里?」
——你就已经建立了足够的全局心智模型,可以开始 Phase 1 了。

Intro to C on Windows(穿插)

10 集 · 可选

这是 Casey 在开始 Handmade Hero 之前录的 C 语言入门,主要面向从 C#/Java/Python 转过来的人。既然你用 Rust,这 10 集主要价值是对照 C 与 Rust 的内存模型——指针 vs 引用、malloc/copy vs ownership、define vs const/macro。可以 1.5x 速听,不写代码。

    Handmade Ray(穿插,Phase 8 前热身)

    5 集 · 强烈推荐

    这是 Casey 在主项目之外的支线,5 集讲完一个简单的 raycaster。重点是 SIMD raycast 和多线程——Phase 8(Day 590+)k-d tree/grid raycaster 之前的最佳热身材料。建议在跟到 Day 580 左右时停下来,花一周把这 5 集做了。

      Handmade Chat(穿插,深度话题)

      17 集 · 可选

      Casey 与嘉宾深谈特定话题的系列:cache、UB、CRTP、imposter syndrome、IK、shader 分析……不写代码,纯讨论。可以在等编译、跑步机、通勤路上听。