做一款 AI 公司题材的 tycoon 游戏,表面上是在设计一串数字增长,实际上是在模拟一家技术公司的资源分配过程。玩家手里有现金、算力、数据、工程师和声誉五类资源,需要不断做出选择:是先买数据训练模型,还是先做市场投放;是尽快上线一个效果一般的产品,还是攒资源训练一个高质量模型。下面用一个最小可运行的工程,把这条路走通:后端使用 FastAPI,存储使用 SQLite,前端只保留一个简易操作页。最终会得到一个可以点击、可以验证、可以继续扩展的 AI 公司经营游戏原型。
这个项目对开发者来说,真正的价值不是“做一个游戏”,而是练习后端状态管理、时间系统、数据持久化和数值平衡。对想接触 AI 工程实践的开发者,它也能帮你理解模型训练、资源消耗和产品化之间的成本关系。需要先说明一点:这里说的“训练模型”只是游戏里的数值模拟,不是真实的大模型训练。这样设计是为了先把经营循环跑起来,后面再按需替换成真实技术栈。
文章会给出完整的数据表结构、核心引擎代码、API 接口和前端交互片段。代码不一定是最优实现,但每个选择都有明确原因,尤其是“为什么使用懒更新而不是后台循环”和“为什么把经济系统放到后端而不是前端”。
1. 先拆解游戏核心:AI 公司经营到底模拟什么
1.1 玩家目标和核心循环
tycoon 游戏,或者说经营模拟游戏,最核心的循环是:赚钱,投入,产出,再投入。AI 公司题材只是把“生产”环节替换成 AI 行业特有的动作。
AI 公司题材的循环可以拆成五步:
- 玩家用现金购买数据和算力。
- 雇佣工程师作为生产资源。
- 工程师消耗数据和算力,训练出一个模型。
- 玩家将模型发布成产品,产品持续产生收入。
- 收入继续用于购买数据、扩充算力、招聘工程师和做市场投放。
如果收入长期覆盖不了工资和采购成本,公司就会破产。所以玩家的目标不是“训练出最好的模型”,而是在现金流约束下,让每条决策都更接近可循环的增长。
1.2 五类资源与经营动作
游戏里的资源不能设计得太复杂,否则新手玩家很难理解。建议第一版只保留五类资源:现金、算力、数据、工程师、声誉。
| 资源 | 作用 | 初始值 | 主要变化来源 |
|---|---|---|---|
| 现金 | 支付所有采购和工资 | 100000 | 产品收入增加,招聘、买数据、市场投放减少 |
| 算力 | 训练模型时消耗 | 50 | 每 tick 自动恢复一部分,训练时消耗 |
| 数据 | 训练模型时消耗 | 100 | 购买数据集增加,训练时减少 |
| 工程师 | 训练任务必需的生产力 | 0 | 招聘增加,工资按 tick 扣除 |
| 声誉 | 放大产品收入倍率 | 0 | 市场投放增加 |
对应地,第一版只需要五个经营动作:
- 招聘工程师:消耗现金,获得一个技能值随机但稳定的工程师。
- 购买数据:消耗现金,增加数据量。
- 训练模型:占用一个空闲工程师,消耗算力和数据,经过一段时间后生成一个模型。
- 发布产品:选择最新训练完成的模型,开始产生每 tick 收入。
- 市场投放:消耗现金,增加声誉。
这五个动作已经足够覆盖“资源投入、生产等待、产品变现、再投入”的闭环。后续要加特殊事件、研究树、竞品系统,都是在这个闭环之上扩展。
1.3 数值设计要回答的三个问题
写代码之前,要先把数值规则想清楚。否则会出现“每天收入很高但工资更高”“训练成本永远无法收回”“产品上线后收益没有感知”等情况。
第一版需要回答三个问题:
- 每个 tick 有多长?这里定义 1 tick = 1 秒,方便本地观察。生产环境可以改成 2 秒、5 秒或 10 秒。
- 产品收入是否覆盖维护成本?产品收入必须明显高于单个工程师的工资,否则公司规模越大越容易破产。
- 训练等待是否值得?训练需要消耗数据、算力和时间,所以模型质量上限要能带来显著收入提升,玩家才愿意等待。
这些数值不需要一开始完美,但要有调参入口。全部集中在引擎文件顶部,不要分散在代码里。
2. 技术选型与整体架构:用 FastAPI 和 SQLite 跑通最小闭环
2.1 为什么选 FastAPI + SQLite + 原生前端
选技术栈时,第一版的目标是“能快速验证玩法”,而不是“支撑十万玩家”。
FastAPI 适合做这类原型,因为它的接口定义简单,可以直接返回 JSON,开发体验接近写普通 Python 函数。SQLite 是零配置数据库,文件即数据库,适合本地开发和单机测试。前端使用原生 HTML + JavaScript,不需要 Webpack、Vite 等构建工具,打开浏览器就能操作。
需要说明的是,这个组合适合学习和验证,不代表生产环境也要这么选。真实项目通常会引入 PostgreSQL、Redis、异步任务队列和前端框架。如果后续规模扩大,FastAPI 的接口层可以保留,但存储和实时推送都需要替换。
2.2 用懒更新来代替后台循环
经营游戏最常见的技术问题是“时间怎么推进”。最简单的做法是启动一个后台线程或异步任务,每 tick 更新一次数据库。但这个方案有三个问题:
- 服务重启后,后台循环可能丢失。
- 多个 worker 同时推进状态,容易产生重复扣费或重复发工资。
- 离线时间里,状态无法自动推进。
这里采用懒更新,也叫 tick-on-read。做法是:数据库里保存last_tick_at字段,每次玩家请求状态时,根据当前时间和上次更新时间的差值,计算出应该推进多少个 tick,然后一次性推进。
这样不需要后台任务,服务重启也能通过时间差继续推进,也更容易控制单个请求的计算量。为了防止玩家离线很久后一次性循环几万次,需要设置一个最大 tick 上限,例如最多推进 120 个 tick,超出部分直接丢弃或按上限结算。
2.3 项目目录结构
项目文件不多,保持扁平即可:
ai-tycoon/ ├── main.py # FastAPI 入口和接口定义 ├── engine.py # 游戏引擎:状态推进、经营动作、初始化 ├── schema.sql # SQLite 建表脚本 ├── requirements.txt # Python 依赖 └── static/ └── index.html #