# occ-game **Repository Path**: aowind/occ-game ## Basic Information - **Project Name**: occ-game - **Description**: OCC �������� �� Three.js + Node.js ����������������������������������AEGIS-07 ����������������������cannon-es �������� - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-13 - **Last Updated**: 2026-10-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # OCC · 星球文明 > 一个跑在浏览器里的**星球探索 / 基地养成 / 机甲战斗**多人在线原型。 > 七颗可以互相穿越的星球、一条 6 章 71 步的完整任务引导、一套「**打 → 拿 → 造 → 更强**」的循环。 > 服务端权威(Node.js + WebSocket),客户端是 Three.js 的单页视窗,两边共用同一份地形与矿物数学。 ![主界面:左列是雷达 / 任务引导 / 今日委托,中部是战斗视野,右下是面板入口](docs/readme/01-hud.png) **技术栈**:Node.js ≥ 20 · Express · ws · Three.js 0.184 · cannon-es · 原生 ES Module(**无打包器**) **内容量**:76 种物品 · 59 个配方 · 43 项科技 · 22 个模块 · 20 座建筑 · 6 种敌人 · 7 颗星球 · 71 步引导 **规模**:`server/` 18 个文件 · `public/src/` 65 个模块 · 118 个自动化测试脚本 / 19 个分组 **许可**:[MIT](LICENSE)(代码)· 美术 / 音频 / 设计文档版权另计 --- ## 目录 - [这是什么](#这是什么) - [画面](#画面) - [快速开始](#快速开始) - [操作](#操作) - [玩法一览](#玩法一览) - [技术架构](#技术架构) - [目录结构](#目录结构) - [测试与验收](#测试与验收) - [发布与部署](#发布与部署) - [文档](#文档) - [最近更新](#最近更新) - [运行环境](#运行环境) - [许可](#许可) --- ## 这是什么 你被投放到一颗**球形的程序化星球**上:挖矿、砍树、把原料搬回基地、造出第一台冶炼厂, 然后顺着科技树解锁更大的建筑、更远的星球,最后带上模块走进战场打 NPC、精英、世界 Boss 与远征节点。 它的设计目标很具体 —— **一个能一直被玩下去的循环**: ``` 采集(矿 / 树 / 掉落)→ 背包 → 制造(冶炼 / 装配)→ 科技解锁 → 更强装备与模块 ↑ ↓ 基地产线(采矿机 / 物流无人机 / 储物仓) ←—— 战场与远征(掉落 / 图纸 / 材料) ``` - **单人可玩,但世界是共享的**:焦土等战场星域是公共世界,能看见别的玩家、一起打 Boss; 苗圃(家园星)是**每人一份的私有分片**,只有这里能盖基地。 - **服务端权威**:伤害、血量、矿量、背包、建造、科技、任务与日常进度全部由服务端记账, 客户端只负责"我移动 / 我瞄准 / 我开火"这些即时表现。 - **桌面优先**:操作模型是键鼠(右键拖视角 + 准星),窄屏 / 触屏只给一层「请用桌面浏览器」提示。 ## 画面 | 基地与建筑 | 产线与物流 | |---|---| | ![基地](docs/readme/02-base.png) | ![产线](docs/readme/03-production.png) | | **星图与远征节点** | **任务总览面板(Enter)** | | ![星图](docs/readme/04-starmap.png) | ![任务](docs/readme/05-missions.png) | ![护盾兵:正面有实心能量罩,要从侧后方打](docs/readme/06-enemy.png) ## 快速开始 ```bash npm install npm start # = node server/server.js,监听 127.0.0.1:8790 # 浏览器打开 http://127.0.0.1:8790 ``` - 首次进入会要求**创建角色**(昵称 / 形象 / 机甲 / 配色),头像与机甲可在之后更改。 - 游戏内提示一律中文;所有界面都有键盘入口(见下面的操作表)。 - 存档在 `_data/state.json`。**别删这个文件**(等于清空所有账号); 想开一份独立存档就设 `OCC_DATA=<别的目录>`(测试 runner 就是这么隔离的)。 Windows 上想让它常驻(脱离终端、无窗口、有日志): ```bash python scripts/svc.py start # 启动 python scripts/svc.py status # 状态 + 进程链 + HTTP 探活 python scripts/svc.py logs # 生命周期日志 + 服务日志 python scripts/svc.py stop # 停止 ``` > ⚠️ **改了 `server/` 下的代码必须重启服务**;改 `public/` 只要硬刷新浏览器(没有打包步骤)。 ### 两种登录方式 | 场景 | 走哪条 | |---|---| | 部署在 AIGPart 平台(`/play//`) | **平台账号 SSO**:无本地 token 自动跳 `/sso`,平台已登录就自动授权回来,没登录由平台登录页接手 | | 自己的机器 / 根路径部署 | 保留**邮箱 + 密码**入口(邮箱不存在即注册);平台异常时可用 `?local=1` 走本地入口 | ## 操作 | 按键 | 作用 | |---|---| | `W A S D` / 方向键 | 移动(以镜头为基准,自动转向移动方向) | | `Shift` | 加速奔跑(走速 10 / 跑速 52) | | `Space`(按住) | 起飞 / 上升,松开缓降(最高 34,树高约 26) | | **鼠标左键(按住)** | 采矿光束(对准矿物,松开即停) | | **`E`** | 采集开关:按一下持续采,再按一下停;鼠标移开资源自动断开 | | **`F`** / 左键轻点 | 朝准星发射纸飞机 | | 左键 / 右键拖拽 · 滚轮 | 转视角 · 拉近拉远(右键 = 1:1 跟手) | | `T` / `R` | 自动前进 / 停车并回正镜头(建造模式下 `R` = 旋转 90°) | | **`Tab`** | 背包(含模块装配区) | | **`J`** | 随身制造 | | **`U`** | 研究所 / 科技树(`Shift+U` = 补给信标) | | **`Y`** | 星门往返(苗圃 ⇄ 焦土) | | **`Enter`** | 任务总览面板(节点 / 今日委托 / 队列,只读) | | **`X`** | 远征撤离(站进信标圈、窗口开启时有效) | | `Q Z V N` | 模块:冲刺 · 屏障 · 弱点标记 · 相位闪避 | | `B K M O P` | 模块:哨戒炮台 · 诱饵 · 护盾墙 · 悬停 · 短跃迁 | | `; / .` | 模块:钩索 · 雷达脉冲 · 资源扫描 | | `1`~`0` · `Esc` · `H` · `G C L I` | 快捷栏 · 关浮层 · 操作说明 · 网格 / 云层 / 阴影 / 反转 Y 轴 | 鼠标补充:悬停建筑出标签、点标签开面板(储物仓直接开仓库、星门直接开星图); 背包格右键出菜单,双击 = 默认动作。右下角还有「操作说明 / 游戏文档 / 信息 / 音量」按钮。 ## 玩法一览 ### 一条完整的任务引导(6 章 71 步) 主线 **45 步**(基础操作 → 基地生产 → 科技扩张 → 星门战场 → 星图远征 → 构筑循环)+ 支线 **26 步** (20 座建筑各一条 + 6 个战术系统)。推进模型是**服务端权威的依赖图不动点**: - 有前置的步骤严格按 `requires` 串成链,没依赖的支线随便顺序做; - 可做且**非核心**的步骤可以「暂时跳过」(记 `skipped`,不算完成、也不挡后面); - 核心步(放星门 / 去战场 / 撤离等 10 条)不可跳过; - 每章主线全完成发一次章末奖励,全部完成发毕业礼(含 1 张未拥有的模块图纸)。 ### 七颗星球 七颗星球是**同一套确定性数学 + 不同参数**(`server/world-config.js`),切星域 = 整页重载 + 星门过渡层。 | 星域 | worldId | 半径 | 特点 | |---|---|---|---| | 焦土 | `battle` | 820 | 公共战场:NPC / 精英 / 世界 Boss | | 苗圃 | `home` | 520 | **私有分片**,唯一能建基地的地方 | | 灰烬荒原 | `ash` | 700 | 暖灰 + 暗红余烬 | | 永冻冰原 | `ice` | 660 | 冷蓝白 + 青雾 | | 遗迹带 | `ruin` | 760 | 土黄 + 青铜 + 灰绿 | | 裂隙 | `rift` | 820 | 深紫 + 品红辉光,有 Boss | | 铁锈荒原 | `wasteland` | 720 | 锈橙 + 氧化钢灰 | **星区节点不是新世界**:每个星域下挂 1~6 个任务节点(全服共享、按星图顺序开放), 地形完全复用所属星域 —— 这是"内容量 ×N、成本≈0"的关键。 ### 基地 · 产线 · 物流 20 座可建造建筑:指挥中心(基地核心)、储物仓、冶炼厂、石料厂、采矿机、伐木机、太阳能、电池组、 装配机、研究所、星门…… 能源、生产、物流由服务端 1Hz 模拟(`server/sim.js`), 采集机产出 → 物流无人机搬运 → 冶炼成锭 → 装配成更复杂的东西。 ### 远征 · 每日委托 · 构筑 - **远征**:星图节点分"清剿 / 坚守 / 破袭 / Boss"等类型,进节点、完成目标、站进信标圈撤离结算, 首通给图纸、重复给材料。 - **每日委托**(左列常驻看板):每天 3 条,从 5 条任务池按日期种子抽(同一天所有人一样,跨天自动换), 进度只在服务端累加、领奖原子防重。 - **科技与模块**:43 项科技解锁建筑与增益;22 个模块插在槽位上,按键释放(冲刺 / 屏障 / 炮台 / 护盾墙…), 容量与套装加成由服务端聚合。 ## 技术架构 ``` 浏览器(public/) Node.js 服务(server/) ┌──────────────────────────────┐ ┌────────────────────────────────┐ │ Three.js 场景 + 地形/植被 │ │ Express:REST(19 条)+ 静态资源 │ │ 输入 → 本地即时移动/瞄准/开火 │ ws /ws │ ws:位姿广播 + 全部权威状态 │ │ HUD 面板(原生 DOM) ├─────────>│ store.js:账户/背包/仓库/建筑/ │ │ 共用纯数学层(地形/矿脉/常量)│<─────────┤ 科技/引导/远征/日常/模块 + 落盘 │ └──────────────────────────────┘ │ sim.js 1Hz:能源/生产/物流/任务 │ └────────────────────────────────┘ ``` | 关键点 | 说明 | |---|---| | **共享纯数学层** | 地形、矿脉、植被掉落、物流常量、地貌 style 都是**一份代码前后端同时跑** ⇒ 两端对"哪是陆地、哪有矿"的判断必然一致 | | **服务端权威** | 伤害 / 血量 / 矿石储量 / 背包 / 建造 / 科技 / 远征 / 日常 / 模块全部服务端说了算,只有移动、转向、开火是本地即时 | | **球面几何** | 位置一律「单位方向 × 半径」,距离一律算**弧长**;`+Y` = 法线、`+Z` = 前方 | | **帧循环容错** | `setAnimationLoop` 抛一次错就冻结整局,所以主循环里每个模块调用都包一层 `safe()` | | **数据驱动内容** | 星域在 `world-config.js`、节点在 `missions.js`、敌人在 `enemies.js`、模块在 `modules.js`、引导在 `guide-steps.js` —— 加内容 = 加表项 | | **材料口径统一** | 研究 / 随身制造 / 制造队列的付料**统一按「背包 + 仓库」总量判定**,缺的从仓库自动搬;仓库里也没有就整单拒绝,不会凭空造物 | | **存档加固** | 保存有耗时/体积告警,写盘走 tmp→rename 原子替换,`destroyed` 账本有容量上限;可选分片后端(`OCC_STORE_SHARD=1`) | | **移动端** | 不做触屏操作层(键鼠模型没有等价物),窄视口 / 触屏只显示提示层 | 协议速查(完整清单见 [`docs/接口与协议.md`](docs/接口与协议.md)): | 方法 路径 | 说明 | |---|---| | `GET /api/health` | 健康检查 | | `GET /api/world/config` | 世界参数(7 星域) | | `POST /api/auth/register` · `POST /api/auth/login` | 访客注册 · 邮箱密码(邮箱不存在即注册) | | `GET /sso` · `POST /api/auth/sso/exchange` | AIGPart 平台 SSO(OAuth2 授权码 + PKCE) | | `GET /api/auth/me` · `GET /api/me/wallet` | 名片 · 能力与战绩 | | `GET/POST /api/world/spawn` · `GET /api/world/npcs` · `GET /api/world/destroyed` | 出生点 · NPC · 已摧毁物件 | | `WS /ws` | 位姿 / 背包 / 建造 / 采集 / 科技 / 掉落 / NPC / Boss / 远征 / 日常 / 模块与召唤物 | ## 目录结构 ``` OCC-Game/ ├─ public/ 前端(纯 ES Module,无需打包) │ ├─ index.html importmap 指向 vendor;HUD 结构 │ ├─ styles.css 全站样式(含浮层 z-index 阶梯表) │ ├─ src/ ★ 65 个模块(入口 main.js) │ ├─ vendor/ three 0.184 构建产物(离线可用,不走 CDN) │ └─ assets/ 音效 / LOGO / 首屏载具 GLB ├─ server/ ★ 18 个 js(HTTP + WS + SSO + 全部权威状态) │ ├─ server.js HTTP + WS 主服务 │ ├─ store.js 账户 / 背包 / 仓库 / 建筑 / 科技 / 引导 / 任务 / 日常 / 落盘 │ ├─ bag.js 背包与仓库模型(含「背包+仓库」统一付料 payFromBagOrStorage) │ ├─ items.js 物品 76 / 配方 59(单一定义源) │ ├─ tech.js 科技树 43 节点 + 效果汇总 │ ├─ build.js · sim.js 家园建筑数据层 · 基地生产模拟(1Hz) │ ├─ guide.js 任务引导 v2 服务端推进(依赖图 / 跳过 / 章末奖励) │ ├─ npc.js · enemies.js NPC / 精英 / 炮台 / 巢穴 / 护盾兵(6 种 archetype) │ ├─ missions.js 远征节点定义与纯函数 │ ├─ modules.js 模块系统(22 条 / 容量 / 套装 / 效果聚合) │ ├─ daily.js 每日委托(日期种子 / 服务端进度 / 原子领奖) │ └─ world-config.js 服务端权威世界参数(7 星域) ├─ assets/ 美术资产源文件(模型 / 图标 / 设计稿;发布只发瘦身版) ├─ docs/ 文档源(18 篇 md)+ 生成后的文档站(/docs/) ├─ tools/e2e/ ★ 118 个自动化脚本 + 串行 runner(run.mjs) ├─ scripts/svc.py 本机服务起停(支持 OCC_DATA 隔离) ├─ deploy/prod/ 生产发布:push.sh / PM2 / nginx ├─ _logs/ 运行日志、验收截图、runner 汇总(不入库) └─ _data/state.json 存档(⚠️ 删了等于清空所有账号) ``` ## 测试与验收 ```bash node tools/e2e/run.mjs unit # 7 个纯逻辑单测,不碰服务(含背包/仓库付料契约 31 条) node tools/e2e/run.mjs smoke # 冒烟 + 后端 API + 性能 + 文档页 node tools/e2e/run.mjs guide ui # 任意分组组合(串行执行) node tools/e2e/run.mjs all # 全部 118 个(很慢,默认隔离存档) node tools/e2e/run.mjs --groups # 列出 19 个分组与条数 ``` - **自建 runner**(`tools/e2e/run.mjs`)负责:分组、串行 + 全局锁、8790 探活/自动拉起、 **存档隔离**(`OCC_DATA` + 老脚本重定向)、`KNOWN_RED`、逐脚本日志、汇总与退出码。 - 口径:**118 个可执行脚本 · 纯逻辑 11 · 需要服务 107 · 19 个分组**。 完整清单、判读陷阱与"假红 / flaky"区分见 [`docs/测试指南.md`](docs/测试指南.md)。 - 浏览器侧验收全部走 Playwright:开真实服务、真 WS、真渲染,截图落在 `_logs/`。 ## 发布与部署 ```bash # 本机常驻(Windows 计划任务) python scripts/svc.py start # 生产(阿里云):本地打包 → scp → 解包 → npm install → PM2 重载 → nginx 重载 → 探活 bash deploy/prod/push.sh OCC_SYNC_NGINX=1 bash deploy/prod/push.sh # 顺带覆盖服务器上的 nginx 配置 ``` 生产布局:代码在 `/opt/occ-game`,应用只绑 `127.0.0.1:8790`,nginx `:8090` 对外,PM2 单实例 fork; 发布前远端自动备份、失败时打印回滚命令。完整流程与硬约束见 [`docs/部署与发布.md`](docs/部署与发布.md)。 ## 文档 文档站与游戏**同端口**:`http://127.0.0.1:8790/docs/`。 | 想了解 | 看这篇 | |---|---| | 代码怎么搭起来的、有哪些禁区 | [系统架构](docs/系统架构.md) | | 每个玩法系统现在是什么样、数值多少 | [玩法系统现状](docs/玩法系统现状.md) | | REST 与 WS 协议的完整清单 | [接口与协议](docs/接口与协议.md) | | 怎么改代码、怎么调试、常见坑 | [开发指南](docs/开发指南.md) | | 118 个测试脚本怎么跑、怎么判读 | [测试指南](docs/测试指南.md) | | 本机常驻与生产发布 | [部署与发布](docs/部署与发布.md) | | 资产怎么来的、发布怎么瘦身 | [美术资产管线](docs/美术资产管线.md) | | 设计意图(方案原文) | [玩法方案](docs/玩法方案-星球文明-v1.md) · [背包与物品](docs/背包与物品系统方案-v1.md) · [后续内容](docs/后续内容方案-战斗与关卡-v1.md) | | 网络同步 / 性能的对照与实测 | [网络同步方案](docs/网络同步方案.md) · [性能优化方案](docs/性能优化方案.md) | | **每轮拍板记录与原因** | [决策台账](docs/game-design-decisions.md) | | **还没做完、不一致的** | [未完成清单](docs/未完成清单.md) | 改完 Markdown 要重建文档站(三条链,顺序不能变): ```bash node docs/_build/md2html.mjs && node docs/_build/build-md-viewer.mjs && node docs/_build/inline.mjs ``` ## 最近更新 - **任务引导 v2**:6 章 71 步(依赖图推进 / 可跳过 / 章末奖励 / 毕业礼),引导面板与「今日委托」同列同皮肤。 - **战斗与关卡**:三套真模型(哨戒炮台 / 坚守信标 / 骚扰无人机)、巢穴与护盾兵两种敌人、 22 个模块图标、能量护盾半球罩。 - **经济与付料**:研究 / 随身制造 / 制造队列统一按「背包 + 仓库」总量付料,仓库缺料时整单拒绝, 修掉了"空仓库也能搬进背包"的凭空造物缺陷。 ## 运行环境 | 项 | 要求 | |---|---| | Node | ≥ 20 | | 运行时依赖 | `three` / `express` / `ws` / `cannon-es`(就这 4 个) | | 浏览器 | **桌面**现代浏览器(WebGL2 + 键鼠);窄屏 / 触屏会显示「请用桌面浏览器游玩」提示层 | | 系统 | Windows / Linux 均可;生产跑在 Linux + PM2 + nginx | ## 许可 代码采用 **MIT**,全文见仓库根目录 [`LICENSE`](LICENSE): ``` MIT License · Copyright (c) 2026 aowind ``` `assets/`(模型 / 贴图 / 图标)、`public/assets/`(音效 / LOGO)、`docs/`(美术与设计文档)下的 美术、音频与设计资产**版权另计**,不自动跟随代码的 MIT 许可;二次使用或商用前请先联系作者。 (`public/vendor/` 里的 three.js 等第三方构建产物遵循其各自许可。)