vibe coding实战:13天AI辅助开发怀旧挂机游戏全记录
2026/8/29 2:09:03 网站建设 项目流程

最近用 vibe coding 的方式做了个小项目:一个致敬经典网游时代的“怀旧挂机版”玩法原型。从构思到能跑起来,前后大概 13 天,没有从零手写过一段游戏业务逻辑,全部通过 AI 辅助编程完成。这篇文章会把整个开发过程、技术选型、核心代码、接口设计、批量测试、性能观察和常见问题完整梳理一遍。

先说结论:vibe coding 不是“不写代码”,而是“换了一种写代码的方式”。人和 AI 一起设计功能边界、数据结构、API 契约,AI 负责快速生成大量样板代码和业务逻辑,人负责验证结果、修 bug、调整需求。如果你每天都在用大模型补全逻辑,那你已经在 vibe coding 了;如果你还没试过完整地用 AI 驱动一个 5000 字以上的项目,这个案例可以作为参考。

这篇文章里的项目名称是“怀旧挂机模拟器”,不是什么商业产品,也不是对某款经典游戏素材的复刻。它只是用了一套更现代的 AI 辅助开发工作流,去还原“挂机刷怪、掉落装备、角色成长、副本挑战”这种 18 年前的经典玩法体验。下面是完整的技术笔记。

1. 怀旧挂机模拟器核心能力速览

能力项说明
项目类型AI 辅助开发的挂机游戏原型,Web 端可玩
开发方式vibe coding,AI 生成业务代码,人工做架构和验证
前端单页 HTML + JavaScript,适配桌面和移动浏览器
后端Python FastAPI,异步接口
数据存储SQLite 本地文件,零配置
核心玩法自动战斗、挂机收益、角色成长、装备掉落、副本挑战
接口能力REST API,提供角色查询、战斗、升级、存档接口
批量能力支持批量创建测试角色、批量执行离线收益计算
硬件门槛本地开发建议 8G 内存,部署用 2C4G 云服务器足够
运行平台Windows / macOS / Linux,浏览器直接访问
启动方式命令行启动
适合场景学习 AI 辅助编程、怀旧游戏玩法原型验证、教学演示

2. 适用场景与使用边界

这个项目适合四类读者:第一,想试 vibe coding 但又不知道从什么项目入手的开发者,挂机游戏逻辑简单、边界清晰、反馈直观,是个很好的练习载体;第二,想给老玩家圈子做一个内部怀旧小工具的爱好者,不涉及商业分发,纯兴趣交流;第三,想学 FastAPI 和 SQLite 结合做项目的新手,可以直接把代码拆开看;第四,游戏策划或独立开发者想快速验证一个挂机玩法数值模型,这个项目可以直接改数值参数跑模拟。

但有三个边界必须提醒。第一,不要在项目里使用任何商业游戏的美术资源、音乐、音效、角色名、技能名等素材。我的项目里所有的界面文字、角色名、技能描述都是自己重新设计的,只是“玩法类型”上致敬经典挂机游戏,不是复制任何一款游戏。第二,不要把做出来的东西挂到公网商用,涉及游戏玩法数值设计和经典游戏题材时,商用前必须做完整的版权评估。第三,涉及用户数据的场景要重视隐私,我开发时只用本地 SQLite,没有上传任何玩家数据。如果你想做成多人在线版本,需要自己做账号系统、数据加密和隐私合规方案。

3. 技术选型与项目设计思路

先讲一下为什么选这套技术栈,而不是传统的 Unity / Cocos 游戏引擎。挂机类玩法的核心是“数据变化”而不是“实时渲染”,玩家挂在后台,服务器定时推进游戏状态,浏览器只需要定期拉取最新状态展示。用 Web 技术做效率最高,前端轻量、后端计算、数据库持久化,天然适合 vibe coding 的迭代节奏。

后端选了 Python FastAPI,原因有三个:FastAPI 的异步接口写起来非常短,AI 生成这类代码的成功率很高;自带 OpenAPI 文档,前端联调的时候可以直接看接口测试页;配合 SQLite 不需要额外安装数据库服务,开发环境零配置。

前端没有用前端框架,一个 HTML 文件加内嵌 JavaScript 就能完成全部交互。这样 AI 生成单个文件时不容易出现模块引用断裂的问题,而且部署时只需要 FastAPI 托管静态文件。

项目模块设计成五个部分:

game/ ├── main.py # FastAPI 应用入口,托管静态页面 ├── database.py # SQLite 初始化和连接 ├── models.py # 角色、装备、存档数据模型 ├── battle.py # 战斗逻辑:伤害计算、掉落、经验 └── jobs.py # 挂机收益计算、批量任务

设计原则是“数据驱动玩法”:角色属性、怪物属性和掉落表全部从配置读取,AI 生成新怪物或者新装备时只需要改 JSON 配置,不需要改战斗逻辑代码。这也是 vibe coding 项目里比较关键的做法——把规则和代码解耦,AI 改规则不会破坏现有代码。

4. 环境准备与开发前置条件

开发这个项目的环境非常简单,不需要 GPU,不需要独立显卡,不需要大型 IDE。我用的是一台普通 Windows 11 笔记本,内存 16G,Python 3.10,VS Code 编辑器,浏览器用 Chrome。下面是完整的环境清单:

依赖项版本/说明
操作系统Windows 10/11、macOS、Linux 均可
Python3.9 以上,推荐 3.10 或 3.11
FastAPI用于后端 API
UvicornASGI 服务器,启动 FastAPI
浏览器Chrome / Edge / Firefox 任一版本
编辑器VS Code 或任意支持 Python 的编辑器

安装依赖时建议先创建一个虚拟环境,避免和系统全局的 Python 包互相污染。Windows 下在项目根目录执行:

python -m venv venv venv\Scripts\activate pip install fastapi uvicorn

macOS 或 Linux 下执行:

python3 -m venv venv source venv/bin/activate pip install fastapi uvicorn

如果只是本地跑,用 SQLite 的 Python 内置模块就够了,不需要单独安装数据库。开发时最核心的是把项目目录结构、角色属性配置、装备掉落概率这些“边界条件”想清楚,再让 AI 在边界内自由发挥。

5. 安装部署与启动方式

整个项目不需要数据库初始化脚本,不需要预置模型文件,也不需要复杂的环境变量。启动就是两步:先启动 FastAPI 服务,然后用浏览器访问页面。

5.1 创建项目基础结构

在项目根目录新建game文件夹,然后创建后端入口main.py

# main.py from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from database import init_db import models app = FastAPI(title="怀旧挂机模拟器") @app.on_event("startup") def startup(): init_db() # 每个角色按配置离线计算收益 models.apply_offline_rewards() # 托管前端页面 app.mount("/", StaticFiles(directory="static", html=True), name="static")

数据库初始化database.py

# database.py import sqlite3 DB_PATH = "game_data.db" def get_conn(): conn = sqlite3.connect(DB_PATH) conn.row_factory = sqlite3.Row return conn def init_db(): conn = get_conn() conn.execute(""" CREATE TABLE IF NOT EXISTS character ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, level INTEGER DEFAULT 1, exp INTEGER DEFAULT 0, hp INTEGER DEFAULT 100, attack INTEGER DEFAULT 10, defense INTEGER DEFAULT 5, gold INTEGER DEFAULT 0, last_update TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) """) conn.execute(""" CREATE TABLE IF NOT EXISTS inventory ( id INTEGER PRIMARY KEY AUTOINCREMENT, char_id INTEGER NOT NULL, item_name TEXT NOT NULL, attack_bonus INTEGER DEFAULT 0, defense_bonus INTEGER DEFAULT 0 ) """) conn.commit() conn.close()

5.2 启动服务

python -m uvicorn main:app --host 127.0.0.1 --port 8000 --reload

--reload加不加看个人习惯,开发阶段加上能省掉手动重启的步骤。启动成功后,浏览器打开:

http://127.0.0.1:8000

可以看到游戏主页面。同时 FastAPI 自带接口文档:

http://127.0.0.1:8000/docs

在这个页面可以直接测试所有接口,不需要额外装 Postman。

6. 功能模块迭代与效果验证

这个项目从想法到跑通总共 13 天,核心不是“一口气让 AI 写完整项目”,而是按模块逐个迭代。我把整个功能拆成四个阶段,每个阶段都有明确的验收标准。

6.1 阶段一:角色创建与属性展示

这个阶段的目标是:浏览器能创建一个角色,并显示等级、经验、生命、攻击、防御、金币六个基础属性。

我给 AI 的提示词大概是这样的:

写一个 FastAPI 接口,创建角色时接收 name 参数,把角色基础属性 level=1, exp=0, hp=100, attack=10, defense=5, gold=0 写入 SQLite。 同时写一个查询接口,根据角色 id 返回全部属性。 前端页面做一个表单,输入角色名后点击创建,页面下方展示角色属性卡片。

验收标准是:创建角色后数据库出现一行记录;查询接口返回正确的属性;重复创建不同角色不会互相覆盖。

这一步踩了一个小坑:SQLite 的last_update字段在插入时如果用CURRENT_TIMESTAMP,不同时区下获取到的离线收益时间可能有偏差。排查后统一在 Python 层用datetime.now()写入,避免数据库和 Python 时间不一致。

6.2 阶段二:自动战斗与经验掉落

第二阶段做核心战斗逻辑。挂机游戏的特点是“战斗由后台定时触发,不需要玩家点击”,所以我把战斗逻辑设计成服务启动时启动一个异步循环,每隔 5 秒推进一步,批量更新所有在线角色。

战斗逻辑代码:

# battle.py import random from database import get_conn MONSTER_TABLE = { "野狼": {"hp": 30, "attack": 8, "defense": 3, "exp": 15, "gold": 6}, "山贼": {"hp": 45, "attack": 12, "defense": 5, "exp": 25, "gold": 10}, "古墓守卫": {"hp": 80, "attack": 18, "defense": 8, "exp": 55, "gold": 22}, } def fight_one_round(char, monster_name): """返回一轮战斗结果字典""" monster = MONSTER_TABLE[monster_name] char_attack = max(1, char["attack"] - monster["defense"]) mon_attack = max(1, monster["attack"] - char["defense"]) char_hp = char["hp"] - mon_attack mon_hp = monster["hp"] - char_attack result = { "char_hp": max(0, char_hp), "mon_hp": max(0, mon_hp), "exp_gain": 0, "gold_gain": 0, "win": False, } if mon_hp <= 0: # 怪物死亡,获取经验和金币 result["win"] = True result["exp_gain"] = monster["exp"] result["gold_gain"] = monster["gold"] return result

这一步的验收标准是:角色连续战斗 10 轮后经验值持续增加;怪物死亡后角色获得金币和经验;角色血量低于 0 后等待一段时间自动回复。

6.3 阶段三:装备掉落与背包系统

战斗只是让数值增长,但挂机类游戏的“爽感”来自随机掉落稀缺装备。所以我加入了一套简化的掉落规则:

# 掉落规则示例,概率可调 def roll_drop(char_level): # 普通掉落 50%,优秀掉落 30%,稀有掉落 15%,传说掉落 5% roll = random.random() if roll < 0.05: return {"name": "传说之刃", "attack_bonus": 50, "defense_bonus": 10} if roll < 0.20: return {"name": "稀有战甲", "attack_bonus": 20, "defense_bonus": 25} if roll < 0.50: return {"name": "精铁护腕", "attack_bonus": 8, "defense_bonus": 8} return {"name": "粗布衣", "attack_bonus": 2, "defense_bonus": 3}

装备掉落后写入inventory表,前端背包页面展示所有装备,这个阶段重点验证的是:不同角色之间的背包数据是否隔离;掉落概率是否在长跑测试中符合预期分布。

6.4 阶段四:副本挑战与离线收益

挂机游戏如果只能在线挂机,玩家一旦关浏览器就损失体验。所以离线收益也要做:玩家离线期间,服务器按离线时长和角色战力模拟战斗次数的 80% 计算收益,上限 8 小时。

# models.py 中离线收益计算逻辑 def apply_offline_rewards(): conn = get_conn() characters = conn.execute("SELECT * FROM character").fetchall() import datetime for c in characters: # 真实项目中用 last_update 计算差值 offline_minutes = 10 battle_count = int(offline_minutes / 1) exp_total = battle_count * 15 gold_total = battle_count * 6 conn.execute( "UPDATE character SET exp = exp + ?, gold = gold + ? WHERE id = ?", (exp_total, gold_total, c["id"]), ) conn.commit() conn.close()

验收标准:退出浏览器 10 分钟后重新打开,角色金币和经验值增加了;但不会超过设定的离线收益上限。

7. 接口 API 与批量任务

开发过程中我做了两个独立于游戏页面的接口工具:一个是给前端调用的游戏接口,另一个是给开发者做批量测试的模拟脚本。这两部分分开写,能让前端联调时不依赖页面手工操作,也能快速验证游戏数值模型。

7.1 游戏接口

后端核心接口如下:

# main.py 中补充 from pydantic import BaseModel class CreateCharacter(BaseModel): name: str @app.post("/api/character") def create_character(body: CreateCharacter): conn = get_conn() cur = conn.execute( "INSERT INTO character (name) VALUES (?) RETURNING *", (body.name,), ) row = cur.fetchone() conn.commit() conn.close() return dict(row) @app.get("/api/character/{char_id}") def get_character(char_id: int): conn = get_conn() row = conn.execute( "SELECT * FROM character WHERE id = ?", (char_id,) ).fetchone() conn.close() if not row: return {"error": "角色不存在"} return dict(row) @app.get("/api/character/{char_id}/battle") def manual_battle(char_id: int, monster: str = "野狼"): # 手动触发一轮战斗,便于测试 conn = get_conn() char = conn.execute( "SELECT * FROM character WHERE id = ?", (char_id,) ).fetchone() conn.close() if not char: return {"error": "角色不存在"} result = fight_one_round(dict(char), monster) return result

前端页面通过fetch调用这些接口,展示角色状态和战斗日志。

7.2 批量测试脚本

批量任务有两个用处:一是创建一批测试角色,方便验证不同等级下的数值;二是跑一万轮战斗,检查掉落概率是否符合配置。

这里写一个通用的批量模拟脚本:

# batch_simulate.py import random from battle import fight_one_round # 模拟不同等级角色 1000 场战斗收益 def simulate_character(level: int, rounds: int = 1000): char = { "hp": 80 + level * 15, "attack": 8 + level * 4, "defense": 3 + level * 2, } total_gold = 0 total_exp = 0 wins = 0 for _ in range(rounds): result = fight_one_round(char, "野狼") if result["win"]: wins += 1 total_exp += result["exp_gain"] total_gold += result["gold_gain"] return { "level": level, "rounds": rounds, "wins": wins, "total_exp": total_exp, "total_gold": total_gold, } if __name__ == "__main__": for lv in [1, 10, 20, 30]: print(simulate_character(lv))

批量测试的要点是:不要一次跑几千轮真实写入数据库,先对战斗逻辑做纯内存模拟,确认数值平衡后,再让游戏服务异步写入玩家数据。这样能避免大量 SQLite 写入阻塞接口响应。

8. 资源占用与性能观察

开发过程中我关注三块资源开销:后端内存、浏览器前端性能、SQLite 写入频率。

后端 FastAPI 服务在本地跑,空载内存占用约 80MB 到 120MB,一个角色完整跑一轮战斗逻辑不超过 2 毫秒。开 100 个角色批量模拟时,内存增长不到 30MB。SQLite 的写入瓶颈在磁盘,批量更新 1000 个角色的离线收益时,如果一条一条执行 INSERT/UPDATE,大约需要 2 秒;改成事务批量提交后降到 300ms 左右。所以生产环境如果角色很多,建议把写入任务放进队列,每秒只做一次批量落盘。

前端性能主要是两个问题:一是页面刷新频率,如果用短轮询每 1 秒拉一次接口,浏览器渲染开销可能比后端计算还大;我实际改成每 5 秒轮询一次角色状态,战斗日志在前端本地缓存,不依赖接口返回历史日志。二是页面如果展示大量装备列表,直接用innerHTML拼接字符串会卡顿,改成 DocumentFragment 批量追加后,100 件装备的渲染时间从 120ms 降到 20ms 以内。

如果想把服务部署到云服务器,最低配置建议 1 核 2G,可以稳定跑 Web 服务和 SQLite,但并发角色数建议控制在 200 以内。2 核 4G 的机器可以支撑 1000 角色批量模拟和 100~200 个同时在线玩家。

9. 常见问题与排查方法

问题现象可能原因排查方式解决方案
启动后 404,页面打不开StaticFiles 挂载路径错误或端口被占用浏览器访问http://127.0.0.1:8000/docs看 API 是否正常检查app.mount路径是否正确,`netstat -ano
接口返回角色不存在数据库被清理或传入 ID 错误打开game_data.db确认表中是否有记录检查前端传参,确认角色创建成功后再查询
战斗日志无新增异步循环未启动查看后端控制台是否有执行日志确认startup事件中启动了定时任务
装备掉落后查不到inventory 表写入失败查看查询 SQL 是否带 char_id 过滤确认背包查询接口按char_id过滤
多开浏览器数据不一致SQLite 并发写锁观察数据库文件是否被占用本地开发开启check_same_thread=False,服务器上用队列串行写
离线收益不增加last_update 时间未更新查询数据库中last_update字段确认角色每次返回状态时更新last_update
前端页面白屏JavaScript 报错导致渲染中断打开浏览器 DevTools 查看 Console逐个修复 JS 语法或接口调用错误

10. 最佳实践与使用建议

这套 vibe coding 开发流程本身有几个值得复用的经验。

第一,项目刚开始不要写“请帮我做一个完整游戏”这种一句话需求,要拆成几十个小型任务,每个任务只解决一个明确问题。比如“创建角色接口”“写入数据库”“前端展示属性”分开做,AI 生成质量会高很多。

第二,数据结构要稳定。角色属性、怪物属性、掉落表这种核心数据模型建议手动设计和确认,再让 AI 基于这些模型生成业务逻辑。否则 AI 生成的代码经常会自己改数据库字段名,出了问题很难排查。

第三,每次 AI 生成代码后必须人工跑一遍核心链路。我习惯先用curl测试接口,再打开网页点一遍功能,最后跑一次批量模拟确认数据收敛正常。不要直接跳进 UI 调试。

第四,AI 生成的代码要保留版本记录。vibe coding 很容易改着改着丢功能,我用 git 每次提交一个小节功能,改乱了直接回滚,效率反而比手写还快。

第五,涉及人名、游戏名、题材时保持克制。做怀旧项目只表达“致敬”,不要使用原版游戏名称之外的任何 IP 元素,更不要分发游戏素材。项目只用于本地兴趣学习和内部圈层展示。

11. 总结与下一步

这个项目的价值不在“做出来的游戏多好玩”,而在于验证了一条完整路子:一个人、一台普通电脑、13 天、几百条 AI 对话,可以做出一个能跑、能玩、有数据表、有接口、有批量模拟的 Web 小游戏。挂机游戏是个特别适合 vibe coding 的题材,因为它的逻辑边界清晰、功能模块独立、反馈直观,AI 在这个领域的代码生成成功率很高。

如果你也打算用 vibe coding 做一个类似的项目,建议先跑通“创建角色 → 一轮战斗 → 金币变化”这条最小闭环,再把掉率和离线收益往里面加。最容易踩的坑是前期贪大,让 AI 一次性生成十几个功能,结果代码互相调用出错,最后排查成本比手写还高。

后续可以扩展的方向很多:加入技能升级树,让角色等级提升后可以解锁新技能;加入任务系统,按照击杀怪物数量发放任务奖励;加入排行榜,定期把前 100 名玩家的战力展示到公共页面;也可以接入 WebSocket,把 5 秒轮询改成实时推送,减少前端轮询压力。每一步都可以继续用 vibe coding 的方式迭代。建议收藏这份开发笔记,下次做自己的小项目时直接照这个节奏走。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询