
1. 一场失眠夜里的像素跳动项目的起心动念18 个月前的一个凌晨两点我躺在床上刷手机看到一段 30 秒的游戏视频。画面里一个方块小人在一块一块的像素平台上起跳、翻越、连跳节奏干净利落配上电子音效莫名有种让人上瘾的韵律感。评论区有人问这是哪家工作室做的作者回复就我一个人。我关掉手机在黑暗里躺了十分钟然后重新打开电脑。那一晚我就是睡不着。白天我是写业务代码的后端工程师用编辑器写了快八年程序但从来没碰过游戏。那会儿我连贴图和精灵图的区别都说不利索。可那个叫像素跳动的想法像根刺一样扎在心里我要自己做一个游戏从零做一个人做不组队、不外包、不用现成的大型模板资源。游戏名字我都想好了就叫像素跳动——一个方块在像素风格的世界里不断跳跃前行。核心玩法极其简单就是把跳这个动作做成有节奏感、有手感、有深度的体验。为什么非得是像素风格原因很务实。第一我一个人时间有限像素美术是我能在艺术表达和工程量之间找到的最好平衡点。一个 16x16 的方块角色我能自己画一张 32x32 的瓦片草地我也能自己磨。换成写实 3D光建模就够我学一年。第二像素游戏有一个独特优势玩家对像素的容忍度极高画面是风格而不是瑕疵这给了独立开发者很大的试错空间。第三平台跳跃Platformer这个品类对人力的要求相对集中核心是手感和关卡不需要做庞大复杂的 RPG 系统特别适合单人完成。而一个编辑器这个说法在项目里其实有两层意思。第一层我确实几乎只用一个代码编辑器写了这个项目的全部逻辑代码——没有用那种装了十几个插件的重型 IDE就是一个轻量的、够快的、能让我专注写代码的编辑器第二层到了开发后期我甚至亲手写了一个关卡编辑器——一个真正属于像素跳动这个游戏自己的编辑器。所以标题里的一个编辑器既是起点也是终点从一个人的工具到为一个梦想而造的专门工具。这个游戏真正开始成型是从我意识到编辑器才是核心生产力那一刻起。这篇分享不是要教你怎么做一款成功的游戏而是想老老实实记录一个没有任何游戏开发经验的人如何只靠一个人的时间、一个顺手的编辑器、一个不切实际的梦把一个方块从能跳起来打磨到跳得舒服最后 18 个月做完了整个项目。如果你也想一个人做点什么希望我的弯路和笨办法能给你一点参考。2. 工具链极简主义我最终依赖的五个编辑器先说结论我最终用的工具加在一起不超过五个每一个都是非它不可才换上去的。很多个人项目死在开始不是因为没有好工具恰恰是因为工具太多、太重、太完美——搭建工作流本身变成了逃避做正事的借口。我给自己定了一个原则每个环节只保留一个主力工具其他的一律砍掉。用途我选用的工具为什么是它写代码VS Code轻量、插件够用、Lua 支持好游戏框架LÖVE (Love2D)用 Lua 驱动非常适合快速做 2D 原型关卡编辑自研像素跳动编辑器引擎和商业关卡编辑器都满足不了我的需求像素美术Aseprite专门为像素画而生导出的精灵表格式干净开发日志Markdown 文件 预览一个编辑器同时装下设计文档和开发记录2.1 主编辑器选型争论Vim 还是 VS Code我最终的取舍开发前有个朋友强烈建议我用 Vim理由是效率高、省内存、程序员图腾。我试了一周结果大部分时间都花在背命令和配置文件上了。我的判断是Vim 适合把编辑本身当手艺的人而我要的是把脑子里的游戏逻辑快速落到代码里对编辑器越无感越好。所以最终选了 VS Code。更关键的是我给它配置了一组自己真正用得上的快捷键和扩展而不是和网上教程一模一样。比如我把保存并运行游戏绑定到 F5把重新加载当前关卡绑定到 F6。开发中我的流程始终是改代码 → F5 跑起来 → 测试 → 改代码。一个编辑器一个按键闭环不折腾。很多人分不清编辑器和编译器的区别我在这个项目里也被问过不少次。简单说编辑器是写字的地方编译器是把你写的字翻译成机器能听懂的命令的工具。在 LÖVE 这个框架里Lua 代码甚至不需要显式编译——它是解释执行的你保存完代码重新运行游戏就看到变化。这意味着我可以把编辑器、运行调试、预览都控制在极短反馈环内这对一个人做游戏来说太重要了。2.2 自研关卡编辑器的诱因引擎内置编辑器不够用的地方像素跳动开发到第 6 个月我开始犯愁了。游戏不是只有一块空地乱跳我需要设计很多平台、陷阱、移动地板、重力反转区、可碎砖块……如果所有关卡都靠手写坐标数组来拼几百个物体的位置、大小、属性堆在代码里根本没法维护。我试过 Tiled一个很流行的 2D 地图编辑器用它编辑地图图层完全是够的。但我的游戏有一个特殊需求——每一个平台都可以挂一个自定义行为脚本比如站在上面会下坠踩到后 3 秒碎裂双向平台只允许从上方穿越。Tiled 能放自定义属性但属性一多每次写属性名都像是在做表格数据录入眼睛都要花掉。更重要的是我的场景运行在 LÖVE 里最自然的关卡表现方式是一张 Lua 表结构而不是 Tiled 导出的 JSON。JSON 和 Lua 表来回转换多了我总觉得有一层隔阂。于是我决定自己做关卡编辑器。当时身边有人劝我——你游戏都没做完还要费劲做编辑器 我心里也嘀咕过但最后还是干了。这个编辑器只有两个核心窗口左边一个可以拖拽、缩放、对齐像素网格的 2D 视图右边一个属性面板选中哪个物体就显示哪个物体的参数。一切操作最终保存为一个.level文件其实就是一个封装好的 Lua 表文本。做这个编辑器花了我大概一个半月的时间但后面九个月的关卡设计效率至少翻了三倍。对于一个强空间感的游戏可视化编辑带来的不仅是效率提升更是设计思维的整体升级。你能肉眼看到一块平台是不是跳得过去距离是不是符合手感而不需要凭空在脑中做 3D 模拟。2.3 像素素材管线从 Aseprite 到脚本批处理像素美术部分我从头到尾只用 Aseprite。它的图层帧动画功能非常直观还能直接导出精灵表Sprite Sheet省掉了我手动切图的痛苦。做到第 8 个月我给角色画了大概 40 帧的动画待机、跑动、跳起、下落、冲刺、受伤、死亡、重生、二段跳特效……这些帧拼在一张精灵表里由代码里的动画状态机来切换。素材多了以后一个麻烦出现了每次角色调整尺寸我都得手动重新切图、更新坐标数组。后来我写了一个 Python 脚本读取 Aseprite 导出的 JSON 数据自动生成 Lua 的动画定义表直接放进项目里。虽然这只是一个小脚本但它教会我一个道理编辑器不只是代码编辑器所有能自动化生成内容的工作都值得花时间搭一条管线。这条管线让我后来做不同风格的 BOSS 动画时省下了大量体力劳动。3. 十八个月拆成四个阶段每个阶段只做一件事18 个月听起来很长但拉出来看真正能用的整块时间并没有想象中多。我是晚上下班后开发偶尔周末整天投入平均下来每周大约 15 到 20 个小时。如果换算成全职工作这 18 个月大概只相当于四到五个月的工时。正因为时间稀缺我更不敢乱来每个阶段只给自己定一个主要目标。阶段时间范围核心目标当时的关键产出第 1 阶段第 1-3 个月一个能跳的原型灰白色方块在空房间跳跃、落下、二段跳第 2 阶段第 4-9 个月把手感调到上瘾跳跃物理参数表、动画状态机、操作反馈第 3 阶段第 10-15 个月做出值得玩的内容20 个关卡、3 个主题世界、敌人和 BOSS第 4 阶段第 16-18 个月让游戏能交付性能优化、音效、Steam / itch.io 发布3.1 前三个月用周末搭建可玩原型第 1 个月我干了件很多人觉得浪费时间的事没有先去学什么大型引擎、没去看游戏开发入门课而是直接拿 LÖVE 写了一个 200 行的方块移动脚本。屏幕上出现一个能用方向键移动、空格起跳的白色方块时那种兴奋感是支撑我后面 17 个月的最大动力。第 2 个月我在原型里加了重力、加速度和简单碰撞。那会儿经常出现一个 bug方块掉到平台边缘卡住或者跳到半空被看不见的墙弹回去。我那时还不知道这叫碰撞体边界问题纯粹靠调试日志一点点找原因。第 3 个月结束我的原型除了一个方块和一堆平台还有一个很重要的东西——一套可配置的跳跃参数文件。我把重力、初速度、跳跃缓冲这些值都拎出来放在配置里每调一个数字跑一次游戏看感觉。这个习惯后来帮了大忙。这个阶段最容易犯的错是想太多。我刚开始甚至设计了一个背包系统和商人 NPC后来意识到这和像素跳动的核心乐趣毫无关系。砍掉的时候有点心疼但回头看原型阶段唯一的 KPI 是这个跳跃好不好玩不是系统多不多。如果你也在做 prototype我建议你写一个极简的爽点清单——先搞清楚这个游戏最核心的几个瞬间是什么感觉然后再往里加东西。3.2 第 4 到第 9 个月手感打磨是最磨人的沼泽做了一个能跳的方块后我才发现能跳和跳起来舒服之间的距离大概隔了一个马里奥。所谓手感在代码里其实是一堆数字的组合重力有多大跳跃初速度有多快空中能不能转向掉下平台边缘的瞬间还能不能跳这个机制业界叫土狼时间按跳跃键的瞬间如果已经在空中能不能缓冲跳跃缓冲……这些数字单独拿出来都不难调难的是它们互相之间有极强的耦合。重力变大了跳跃高度就变矮跳跃初速度变大了滞空时间就变长缓冲时间开的太长玩家会觉得按了没反应太短按早一点点就跳不出来判定很硬。我把这些参数做成了一张巨大的测试记录表。拿最核心的三组参数来说重力加速度从 800 px/s² 一路加到 2000 px/s²跳跃初速度从 500 px/s 一路加到 900 px/s跳跃缓冲从 0 ms 到 200 ms 每次 20 ms每调一组就跑一遍同一个测试关卡记录起跳瞬间的反馈感最高点悬停时间下落时的节奏三个主观指标。那段时间我最像的不是程序员而是一个帮游戏试味道的品酒师。我试了 71 组参数组合后锁定了一组手感最干脆的参数再用这组参数去调二段跳和冲刺。为什么要这么较真因为平台跳跃游戏的乐趣就来自精确控制的快感。一个玩家操纵一个小方块如果每一次起跳、每一次落点都在他的预期之内他就会觉得自己变强了这就是心流的来源。反过来如果起跳总是慢半拍玩家会非常愤怒而且他说不清为什么只会觉得这游戏不舒服。这半年的手感打磨让我明白了什么叫细节即游戏。3.3 第 10 到第 15 个月内容量才是独立游戏的天花板手感稳住之后游戏的框架基本定了。但从手感好到值得玩中间还隔着一道巨大的坎内容。这五个月我在做三件事。第一关卡设计。我利用自研的关卡编辑器搭建了 3 个主题世界第一个世界是绿色草地的起跳平原教玩家基础跳跃第二个世界是阴冷洞穴的重力迷窟引入重力反转和移动平台第三个世界是霓虹电子城像素都市挑战二段跳连跳和精确落点。每个世界 6 到 8 个常规关卡加上一个 BOSS 关总共 20 个关卡。第二敌人和机关。我给游戏加了三类基础敌人巡逻小兵、尖刺球、飞行眼。它们的 AI 都很简单但每类敌人都能和主角的跳跃能力形成良性互动——你永远可以跳过去而不是被迫攻击。这就是平台跳跃的默契敌人的作用不是杀死你而是让你的跳跃更有挑战性。第三音频和反馈。我找了开源的音效素材库给跳跃、双段跳、踩敌人、吃金币、死亡、重生都配了不同的音效。配合轻微的屏幕震动和像素粒子特效这个小方块立刻活了。这个阶段最常见的心理挑战是你会在某个星期三突然觉得整个游戏是个垃圾。我自己就经历过某天测试到自己第 10 关时突然觉得所有关卡都长得差不多特别想全部推翻重做。后来我学会了一个办法不当天做决定先把想法写进改进清单过一周再看哪些意见是真的需要改哪些只是一时的情绪。事实证明清单里大约只有三分之一值得动手。3.4 最后三个月性能、发布与那一刻的忐忑第 16 个月开始游戏内容基本冻结不再加新玩法了。我的任务变成让游戏流畅跑起来并且在三个平台上都能发布。LÖVE 框架本身很轻但我在粒子特效上过度放飞导致一个 BOSS 倒地时满屏像素碎片中端电脑能掉到 30 帧。我用 Profiler 查了热点把粒子数量上限从 2000 砍到 600加了对象池复用瞬间稳定到 60 帧。这个教训很典型独立游戏最先被砍的通常不是功能而是粒子特效。第 17 个月我搭构建脚本自动打包 Windows、macOS、Linux 三个平台的版本。中间踩了一个很无语的坑Windows 下 Lua 读取中文路径的存档文件会乱码排查了一个通宵才发现是文件编码问题。最后还是老老实实用 UTF-8 无 BOM 格式统一所有文件并在代码里做了容错。第 18 个月上旬我提交了 Steam 的审核申请上架了 itch.io 的免费试玩版。发布前我在本地反复模拟了十几次从零开始下载安装并进入游戏确认任何一个陌生玩家都能顺滑打开。当你真的按下发布按钮的那一刻你会发现自己竟然有点不敢看后台数据——那种忐忑和做游戏时破解难题的快感完全不一样但同样真实。4. 像素跳动的核心难关物理手感与关卡设计的数据化如果说一个人 18 个月是这个项目的外壳那么真正撑起像素跳动的内核是两件事物理手感的数据化调优以及关卡结构的编辑器化设计。这两部分如果只说慢慢调或者凭感觉读者很难复现。我尽量把背后的逻辑摊开讲。4.1 跳跃物理为什么我试了 71 组重力参数平台跳跃的物理公式其实特别简单因为我不做空气阻力、不做斜坡摩擦纯粹就是-- 每帧更新垂直速度 velocityY velocityY gravity * dt -- 应用位移 positionY positionY velocityY * dt -- 地面判定 if positionY groundY then velocityY 0 isGrounded true end一句gravity一个jumpSpeed就是整个跳跃的核心。不同的取值组合会让手感千差万别重力小 初速度大 高而绵软有点像在月球走路重力大 初速度小 低而脆快落地非常果断重力大 初速度大 高耸且节奏快刺激但有压迫感我最终锁定的参数是重力 1500 px/s²跳跃初速度 620 px/s二段跳初速度 550 px/s。这组参数下单跳最高约 128 像素滞空全程大约 0.83 秒。为什么是 128因为我的基础平台高度是 64 像素正好两倍——跳两格高、不太费力这个比例让玩家视觉上觉得我能轻松跳过一块砖但连续跳三块是有难度的。至于土狼时间和跳跃缓冲简单说就是给玩家发福利土狼时间玩家离开平台后的 80ms 内仍然可以起跳跳跃缓冲玩家落地前的 120ms 内按下跳跃键落地后会立刻起跳这两个机制在职业术语里叫手感宽容度。真正的硬核玩家可能不会感知到它们的存在但没有了它们游戏会莫名僵硬。我在 71 组测试里把缓冲时间按 20ms 一档从 0 加到 200最终落到 120ms 是因为它恰好是玩家感觉不到延迟和能拯救误触的平衡点。4.2 像素级判定从碰撞体到感觉对的微调游戏是像素风格但碰撞检测并没有真正精确到像素级别那样成本太高了。我用的是网格碰撞把整个关卡划分成 16x16 的格子角色占据一个或多个格子区域移动时先检测水平方向再检测垂直方向避免对角线穿透。这套方案在纯平台跳跃游戏里已经是标准的可靠做法。但真正手感对的秘诀不在碰撞检测的精度而在碰撞盒的形状。一个角色看似只有 16x16 像素大但他的碰撞盒不应该占满整个身体。我把玩家的碰撞盒设成了 12x14 像素缩水了一圈。为什么因为玩家在跳跃时觉得能过去的一瞬间往往是因为视觉边缘已经擦到了目标如果碰撞盒完全等于视觉效果那些极限跳跃会被严苛地拦截。给碰撞盒缩小一点就好像给玩家发了一张视觉误差豁免卡游戏瞬间变得宽容而友好。这个思路也可以用在敌人身上敌人的碰撞盒略大于视觉尺寸这样玩家被判定碰到敌人的情况更多一点但踩到敌人头顶的判定略微缩小——两头都适当收紧让跳过敌人变得更安全。4.3 关卡结构如何被编辑器驯服像素跳动的关卡文件结构是这样的return { width 40, height 20, tilemap { ... }, -- 每一格是地板/墙面/空白 entities { { type player_spawn, x 2, y 14 }, { type spike, x 10, y 15 }, { type moving_platform, x 15, y 8, range_x 3, range_y 0, speed 2 }, { type coin, x 8, y 8 }, { type goal, x 38, y 5 }, }, }我自研编辑器的工作模式极其朴素左边是网格画布右上是属性面板右下是层级列表。在网格上点一下就能放一个平台拖拽调整位置右侧改属性搞定。最关键的一点是热重载——在游戏运行中我按 F6当前关卡立刻重新加载玩家位置保留在原来的地方。这样我可以反复测试同一小段关卡不需要从关卡开头一步步跳过去测试效率提升了非常多。举个小例子第 7 关有一处非常极限的连续移动平台跳跃。我为了微调第二块平台的移动速度在编辑器里把它从 2.5 改到 3.2按 F6 重新加载立刻就能站在起点尝试手感。这个动作一分钟能循环十几次。如果不用编辑器、直接改代码里的坐标数字一次循环可能要两分钟而且容易改错坐标。编辑器带来的不仅是视觉直观更是试错成本的指数级下降。5. 从零到一的过程中我踩过的那些坑一个人做项目坑几乎是等比例增长的——系统越多坑越深。这里选四个我在开发里印象最深、也最典型的教训。如果你正准备一个人启动自己的项目这几个坑大概率你也会遇到。5.1 过早优化和过晚备份是捆在一起的第 4 个月的时候游戏还只有一个能在空地跳的方块我却已经开始折腾通用敌人 AI 框架想着以后敌人的状态机肯定很复杂。结果那个框架写了一千多行占满了我每天晚上 3 个小时的精力而游戏本身一个敌人都没有。后来我决定全删重写删完的那一刻人清爽了但时间已经浪费了两个星期。更痛的是另一个晚上。我的 Aseprite 工程文件不小心被误删——准确地说是编辑器崩溃连带写坏了文件头。那里面是我花了两周画的主角动画帧部分帧连参考图都没有第二份。那天我对着空荡荡的回收站发了好一会儿呆。从那时起我立下两条死规矩每天结束开发前必须 Git 提交一次提交信息哪怕只写add spikes也行美术原始文件每天做一次自动快照放到另一个硬盘目录这些备份在最后三个月帮了我大忙——至少有三次我在调 BOSS 战的时候改出了奇怪的 bug全靠回滚到前一天版本才恢复。备份不是让你避免犯错而是让你敢犯错。对独立开发者来说敢犯错的心态比什么都重要。5.2 一个人也需要代码评审给自己当陌生人的经验没有同事没有 code review这是单人开发最危险的陷阱之一。我写过太多当时觉得天才能看懂、一个月后自己看像天书的代码。尤其是 Lua 这种动态类型语言函数参数传错了类型不会立刻报错往往是运行到某个边界条件才炸。中期我给自己做了一个强制流程每两周一次重构日把最近两周写的代码从头读一遍凡是出现以下特征的代码全部处理函数超过 40 行拆命名含义含糊的变量改名注释和代码不一致以代码为准改注释同一个算法出现两次抽成公共函数这个流程救了我非常多。有一次在重构日的阅读中我发现跳跃缓冲的实现漏掉了玩家在落地瞬间才按跳跃键的情况而这个 bug 在正式测试时几乎不可能被发现但会导致玩家在特定节奏下跳跃失灵——这正是感觉这游戏有问题但说不清哪里有问题的元凶。一个人不能总依赖别人帮你发现问题做自己的陌生人反而更能看清短板。5.3 当我发现编辑器比游戏还大时自研编辑器前期帮我提效但做到第 12 个月我犯了一个典型的工具沉迷错误。编辑器本来只需要支持放平台、放敌人、调属性我却开始给它加图层混合模式撤销历史的可视化时间轴自动生成某类关卡的参数模板等功能。每次打开编辑器都有一种我真厉害的错觉——但仔细一想游戏本身的关卡才做了 7 关而编辑器快 5000 行了。那个月我终于清醒了我是在用做编辑器逃避做关卡内容。做一个新功能很容易带来成就感但把 20 关一个个设计完需要的是持续而枯燥的专注。我给自己定下铁律新功能必须满足当前做关卡时立刻会用到这一条才能加入编辑器。那一堆花哨的未来可能会用到的功能全部砍掉。砍完之后编辑器瘦了一圈关卡产量反而上来了——因为我没有借口再折腾工具了。5.4 一人团队的进度崩溃当连续三周没有写出一个漂亮的关卡时还有一种坑不是技术问题是情绪问题。做到第 14 个月我连续三周没写出一个自己满意的关卡每天晚上在编辑器里拖来拖去存了删删了又存最后的产出是负的。那段时间我变得特别不想打开项目甚至想过原地放弃。后来我怎么出来的我做了一个特别蠢的决定不再造新关卡而是把已经做好的第 1 关到第 8 关重新玩一遍每玩一关只改一个我觉得最不爽的小问题——比如某块平台的间距过大某颗金币的位置太偏。连续一周我不追求大突破只追求每天让游戏好一点点。一周后信心回来了第 14 关的灵感也冒出来了。对单人开发来说进度低谷是必然的但你不必用硬扛去熬过它。把目标缩小到今天只改进一个像素的间距也行只要还在接触编辑器、还在和项目保持连接低谷总有一天会过去。6. 上线前两天我为像素跳动收尾时的一些心里话发布前两天我没有在做功能而是在做减法。我把所有标题界面的文案重新念了一遍删掉所有我自认为幽默但玩家根本看不懂的梗把操作说明从三页压缩成一页用一张图加六个字讲清楚方向键移动空格跳跃Shift 二段跳还重新设计了存档界面的默认命名——直接给玩家一个推荐名字而不是让他们面对一个空输入框发呆。当时旁边有人问我你怎么不搞个新手教程关卡我说平台跳跃游戏的新手教程应该藏在第一关里让玩家不知不觉学会跳跃而不是逼他先读一段说明书。所以我砍掉了专门的教学关卡改成把基础操作融进第 1 关的地形里。这个决定需要一点勇气因为教学缺失确实是很多独立游戏的败笔但好的关卡本身就是最好的说明书。上线后我收到的第一条玩家评论不是评价画面也不是说什么手感而是我把你游戏里的编辑器玩明白了自己做了一关全是移动平台的结果发现我跳不过去。 那一刻我特别高兴——因为这说明有人比我更早意识到像素跳动这个项目最大的隐藏玩法其实是让玩家自己编辑关卡。有人用内置编辑器做出了整屏的像素跳板迷宫传到了社区有人开始研究不同平台的移动速度该怎么搭配才好玩这让我的游戏意外地多了一层无穷内容的可能性。最后想跟所有打算一个人出来做点什么的读者说几句实在话第一别一上来就追求大作一个好点子加上扎实的核心机制远比一张宏大但空洞的路线图靠谱第二做一个能结束的东西——哪怕它很小有头有尾才能让你获得完整的正反馈而不是永远在开发第一个系统第三工具够用就行但值得你亲手为项目的核心需求做一个专属工具真正的效率提升往往不是来自更快地打字而是来自更少的重复劳动。我在 18 个月里没有一天是不焦虑的但我坚持每天打开编辑器哪怕只写一行代码、摆一个平台、调一个参数也算今天没有白过。量变到质变靠的就是这种笨拙而持续的重复。一个人一个编辑器一个梦——正是这份微小但确定的日拱一卒最终让像素跳动从一个失眠夜的念头变成了一款真真切切可以下载、可以玩、可以让人开心的游戏。你要是也有那个一直放不下的念头别等辞职别再想太多今晚就试着在编辑器里敲下第一行代码吧。