Files
echo-nexus/docs/11-放置系统-v0.14.md

310 lines
12 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 回响星核 v0.14 — 放置系统(Idle Operations)设计文档
> 版本:v0.14 · 日期:2026-01-25
> 核心目标:让玩家打开游戏 **5 秒内** 就能看出这是个 idle game
---
## 1. 设计动机
### 1.1 用户反馈
> "你的这个我没有看到任何可放置的功能" —— 玩家反馈
虽然 v0.8 已有 `crystalsPerSec` 在后台自动累积,但 **没有任何 UI 元素明示这一事实**
- 没有「放置中」徽章
- 没有可视化自动采矿机
- 没有定时工程项目
- 离线收益弹窗只在重新加载页面时触发,玩家日常游玩看不到
放置游戏的灵魂是「关掉也在进步」。如果玩家看不到这一点,就等于没有放置玩法。
### 1.2 设计目标
1. **可见性**:5 秒内让玩家意识到 idle 属性
2. **决策性**:放置不只是数字增长,要有玩家选择
3. **节奏感**:3 层 idle 节奏(被动产能 / 放置工程 / 离线收益)协同
4. **健康性**:避免 24h 挂机的极端沉迷
---
## 2. 三层 Idle 节奏
### 节奏 1:被动产能(Passive Generation
- **载体**:采矿无人机舰队(Miner Fleet
- **来源**:每解锁一个采矿分支技术节点 → 加入一架无人机
- **行为**:24h 持续产出晶体,无需任何操作
- **限制**:受 `crystalCap` 限制,仓库满后停止
- **离线**:按 `offlineEff`(默认 50%)持续累积,上限 8h
#### 采矿分支技术 → 无人机映射
| 技术节点 | 无人机名 | 输出/s | 解锁成本(洞见) |
|---------|---------|--------|-----------------|
| `min_1` | ⛏️ 谐振钻头 | +0.6 | 5 |
| `min_2` | 🌋 深层矿脉 | +1.6 | 24 |
| `min_3` | 🤖 自治机群 | +5 | 120 |
| `min_4` | 💠 量子采掘矩阵 | +12 | 400 |
| `min_5` | ☀️ 戴森星核 | +30 | 1200 |
无采矿技术时显示「谐振钻头(休眠中)」占位卡片,引导玩家解锁采矿分支。
---
### 节奏 2:放置工程(Idle Projects
#### 2.1 工程列表
| ID | 名称 | 时长 | 奖励 | 解锁条件 | 图标 | 色 |
|----|------|------|------|---------|------|-----|
| `idle_scan` | 深空勘探扫描 | 60s | ✦ +8 洞见 | 产能 ≥ 0.5/s | 🛰️ | emerald |
| `idle_refine` | 晶体精炼阵列校准 | 180s | ⇪ +0.3/s 永久 | 产能 ≥ 1/s | ⚙️ | rose |
| `idle_archive` | 遗迹碎片整理 | 600s | ✦ +20 洞见 + 📜 随机碎片 | 飞升 ≥ 1 OR 产能 ≥ 5/s | 📜 | amber |
| `idle_anchor` | 维度锚点部署 | 1200s | ⚡ +2 能量 + ☄ +5 接触进度 | 飞升 ≥ 1 | ⚓ | fuchsia |
| `idle_drones` | 无人机群扩编 | 1800s | 💎 +500 晶体 + ⇪ +2/s 永久 | 产能 ≥ 10/s | 🛸 | emerald |
| `idle_resonance` | 跨维度谐振标定 | 3600s | ✦ +100 洞见 + ☄ +15 接触 + ⇪ +8/s 永久 | 飞升 ≥ 2 | 🌌 | fuchsia |
#### 2.2 槽位机制
- **3 个并行槽位**:可同时运行 3 个工程
- **不重复**:同一工程不能在多个槽位同时运行
- **完成需手动领取**:避免"打开就有奖励"的条件反射
- **取消不退时间**:误取消的代价
- **离线推进**:关闭浏览器后工程继续倒计时
#### 2.3 奖励类型说明
| 奖励 | 含义 | 设计意图 |
|------|------|---------|
| 晶体 | 立即加到 `crystals` | 短期反馈 |
| 洞见 | 立即加到 `insights` | 用于解锁技术 |
| 能量 | 加到 `energy`(受 `energyMax` 上限) | 探险资源 |
| 接触进度 | 加到 `contact`0-100 | 推进飞升 |
| **永久产能加成** | 加到 `idlePermanentBonus`,影响 `recomputeStats` | 长期投资 |
| 随机碎片 | 从 `FRAGMENTS` 中随机解锁一个未拥有 | 叙事推进 |
---
### 节奏 3:离线收益(Offline Gains
#### 3.1 公式
```
gain = crystalsPerSec × elapsed × offlineEff
elapsed = min(realElapsed, 8h)
```
#### 3.2 解锁路径
- 初始 `offlineEff = 0.5`50% 离线效率)
- 通过技术树 `offlineEff` 类效果提升
- 通过星图天赋 `offlineEffBonus` 提升
- 上限 100%
#### 3.3 8h 上限理由
- 参考 GDC 2016 Anthony Pecorella "Quest for Progress"Egg Inc 2h 硬 cap 导致玩家流失
- 但完全无 cap 会导致 24h 挂机成为最优策略,破坏短会话体验
- 8h 折中:覆盖一个工作日/一夜,但不鼓励全天挂机
#### 3.4 离线报告弹窗
重新加载页面时,若 `elapsed > 60s`,弹出 `OfflineReportDialog`
- 「你离开了 X 小时 Y 分」
- 「星核为你产出 Z 颗晶体」
- 「产能 /s · 离线效率 N%」
- 「是否触达 8h 上限」标志
---
## 3. UI 设计
### 3.1 始终可见的 Idle 徽章(Header
位置:顶部 Header,紧邻「巡航」按钮左侧
状态:
- 产能 > 0`● 放置中 +X.X/s`(绿点脉动)
- 产能 = 0`○ 休眠中`(灰点静止)
悬停 Tooltip 显示明细:
```
基础产能 8.2/s
永久加成 +1.5/s
离线效率 75%
完成工程 12 次
```
点击徽章 → 切换到「放置」标签。
### 3.2 默认标签页 = 放置
首次打开游戏,默认 tab 是「放置」(v0.13 前是「探险」或「技术」)。
返回玩家若有进行中探险或待选天赋,自动切回原默认。
### 3.3 放置标签页四段式布局
```
┌─────────────────────────────────────────┐
│ Section 1: 放置收益概览 │
│ [放置产能] [永久加成] [完成工程] │
│ [━━━━━━━ 离线效率 50% · 上限 8h ━━━━━━] │
├─────────────────────────────────────────┤
│ Section 2: 采矿无人机舰队 │
│ [⛏️ 钻头] [🌋 矿脉] [🤖 机群] ... │
├─────────────────────────────────────────┤
│ Section 3: 放置工程槽位 │
│ [槽位1: 运行中 47s ▓▓▓░] [槽位2: 空] [槽位3: 空] │
├─────────────────────────────────────────┤
│ Section 4: 可派遣工程 │
│ [🛰️ 深空勘探扫描 1m +8] [⚙️ 精炼校准 3m +0.3/s] │
│ [📜 碎片整理 10m +20] │
│ │
│ 未解锁工程(3): │
│ ⚓ 维度锚点部署 · 需 飞升≥1 │
│ 🛸 无人机群扩编 · 需 产能≥10/s │
│ 🌌 跨维度谐振标定 · 需 飞升≥2 │
└─────────────────────────────────────────┘
```
### 3.4 IdleProjectBar(晶体球下方)
位置:左侧晶体球区,`CrystalYieldPanel` 下方
显示:当前运行的工程迷你 pill
```
🛰️ 深空勘探扫描 47s ▓▓▓░░░░░
⚙️ 晶体精炼校准 2m 13s ▓▓░░░░░░
```
无运行工程时返回 `null`(不占位)。
---
## 4. 技术实现
### 4.1 数据结构
```typescript
// types.ts
interface IdleProjectDef {
id: string;
name: string;
desc: string;
durationSec: number;
reward: { crystals?; insights?; energy?; contact?; crystalsPerSecPermanent?; randomFragment?; };
minAscensions?: number;
minCrystalsPerSec?: number;
icon: string;
color: "emerald" | "rose" | "amber" | "fuchsia";
order: number;
}
interface IdleProjectSlot {
projectId: string;
startedAt: number;
finishesAt: number;
remainingSec: number;
completed: boolean;
}
// GameState 新增 4 字段
idleProjectSlots: (IdleProjectSlot | null)[]; // 3 槽
idleProjectHistory: { projectId: string; finishedAt: number }[]; // 最近 50 条
idlePermanentBonus: number;
idleStats: { projectsCompleted: number; crystalsFromIdle: number };
```
### 4.2 Store actions
- `startIdleProject(slotIndex, projectId)` — 校验 + 创建槽位
- `cancelIdleProject(slotIndex)` — 置空槽位
- `claimIdleProject(slotIndex)` — 应用奖励 + toast + 置空槽位
- `tickIdleProjects(now)` — 推进剩余时间,标记完成
### 4.3 引擎集成
`recomputeStats()` 末尾添加:
```typescript
crystalsPerSec += state.idlePermanentBonus ?? 0;
```
这让永久产能加成真正生效。
### 4.4 飞升处理
`performPrestige()` 重置 `idleProjectSlots = [null, null, null]`(不跨周目继承进行中工程),但保留 `idlePermanentBonus` / `idleProjectHistory` / `idleStats`(跨周目永久)。
### 4.5 存档迁移
persist 添加 `version: 1` + `migrate` 函数,为旧存档补全 4 个新字段:
```typescript
idleProjectSlots: (s.idleProjectSlots as unknown[]) ?? [null, null, null],
idleProjectHistory: (s.idleProjectHistory as unknown[]) ?? [],
idlePermanentBonus: (s.idlePermanentBonus as number) ?? 0,
idleStats: (s.idleStats as unknown) ?? { projectsCompleted: 0, crystalsFromIdle: 0 },
```
旧存档零崩溃风险。
### 4.6 主循环集成
`useGameLoop` 每 250ms tick
1. `tick(now)` — 产能 + 自动产晶体
2. `autoDecodeTick()` — 自动解码
3. `tickTide(now)` — 星潮事件
4. **`tickIdleProjects(now)` — v0.14 放置工程进度**(新增)
5. `checkAchievements()` — 每秒一次
页面可见性切回时也调用 `tickIdleProjects(now)`
---
## 5. 平衡考虑
### 5.1 永久产能加成可能过强
- `idle_resonance` +8/s 永久,多次完成可能让玩家飞快积累
- **v0.15 待办**:加飞升次数 softcap,例如 `effectiveBonus = idlePermanentBonus × sqrt(ascensions + 1) / (ascensions + 1)`
### 5.2 工程时长曲线
- 60s / 180s / 600s / 1200s / 1800s / 3600s
- 短工程奖励低但灵活(适合短会话)
- 长工程奖励高但需等待(适合过夜挂机)
- 玩家自主选择节奏
### 5.3 解锁条件
- 0 飞升 + 0.5/s:新手 5 分钟内可解锁第一个
- 1 飞升:玩家完成首次飞升后解锁中段
- 2 飞升 + 10/s:长线目标
---
## 6. 验证记录
### 6.1 Lint
- ✅ 零错误零警告
### 6.2 Dev 服务器
- ✅ HTTP 200
- ✅ 无运行时错误
### 6.3 Agent Browser 端到端测试
1. ✅ 默认 tab 是「放置」
2. ✅ Header 显示「放置中 +0.4/s」徽章
3. ✅ 4 段面板完整渲染
4. ✅ 买 min_1+min_2 后产能 2.6/s,解锁 idle_scan + idle_refine
5. ✅ 点击「派遣至槽位 1」→ 槽位显示运行中 60s + 进度条 + 取消按钮
6. ✅ IdleProjectBar 同步显示迷你 pill
7. ✅ 快进完成后标记 completed=true
8. ✅ 领取后 insights +8、projectsCompleted 0→1、槽位清空
### 6.4 Sticky Footer 验证
- ✅ Header `position: sticky; top: 0`
- ✅ Footer `position: sticky; bottom: 0; margin-top: auto`
- ✅ 内容超出视口时 footer 被自然推下(无浮动空隙)
---
## 7. 未解决问题 / 后续
- 🟡 `crystalsFromIdle` / `idleProjectHistory` 已在 store 累加但 UI 未展示——v0.15 可在统计 tab 补
- 🟡 永久产能加成可能需要飞升次数 softcap
- 🟡 缺「批量领取全部」按钮(玩家有 3 个槽位都完成时方便)
- 🟡 缺工程完成 toast 通知(目前只能在面板内看到「待领取」标志)
- 🟢 v0.15 可加 Dark Souls 式 loreFragments 多层文本,让"遗迹碎片整理"工程的随机碎片奖励更有叙事感
---
## 8. 设计哲学总结
> "Incremental games are very raw. They're about relating to a process and becoming obsessed with its growth, like watching something you planted in the ground, through a time-lapse camera, grow into a tree." —— Clark (via Frank Lantz, New Yorker 2019)
回响星核 v0.14 的放置系统不只是把数字挂机增长,而是让玩家**看到**这个过程:
- 采矿无人机像植物在土里生长
- 放置工程像种子在发芽
- 离线收益像收获时节
玩家不再只是「数字变大」,而是「亲手布置了一个会自动运转的考古基地,然后离开,让它在自己不在的时候继续工作」。
这是 idle game 的本质:**让玩家信任系统会在他不在时为他工作**。