主題
廢土傳承 — 隨機事件機制
概述
事件是遊戲的核心內容載體。玩家的所有體驗——探索、戰鬥、交易、社交、劇情——都透過事件呈現。事件機制負責:決定什麼時候觸發什麼事件、怎麼呈現、玩家怎麼做選擇、選擇帶來什麼結果。
事件編碼規則
編碼格式
EVT_[情境]_[類型][編號]| 片段 | 格式 | 說明 |
|---|---|---|
| 情境 | 2 字母 | 事件發生的情境(見下表) |
| 類型 | 1 字母 | 事件類型(見下表) |
| 編號 | 3 位數 | 流水號,001 起 |
情境代碼
| 代碼 | 情境 | 說明 |
|---|---|---|
EX | 探索 | 派遣成員在外出探索時遭遇 |
HB | 家園 | 在庄園/家園中發生 |
SN | 季節 | 每季結算時自動觸發 |
LF | 生命 | 角色生命週期事件(出生、成年、老化、死亡) |
QT | 主線 | 與主線劇情相關 |
類型代碼
| 代碼 | 類型 | 說明 |
|---|---|---|
C | 戰鬥 (Combat) | 需要 D20 戰鬥檢定 |
E | 遭遇 (Encounter) | 與 NPC 或勢力的互動 |
D | 發現 (Discovery) | 發現新地點、資源或知識 |
H | 危機 (Hazard) | 環境危險:輻射、災害、疾病 |
T | 交易 (Trade) | 商業互動 |
S | 故事 (Story) | 純敘事或角色發展 |
F | 家族 (Family) | 家族內部事件:傳承、衝突、慶典 |
編碼範例
| 編碼 | 含義 |
|---|---|
EVT_EX_C001 | 探索中遭遇的第 1 個戰鬥事件 |
EVT_EX_D003 | 探索中的第 3 個發現事件 |
EVT_HB_F001 | 家園中的第 1 個家族事件 |
EVT_SN_H002 | 季節結算的第 2 個危機事件 |
EVT_LF_S001 | 生命週期的第 1 個故事事件 |
EVT_QT_S001 | 主線的第 1 個故事事件 |
事件鏈編碼
事件可以串成連鎖。後續事件在原編碼後加 _[分支][序號]:
EVT_EX_C001 ← 遭遇強盜(主事件)
EVT_EX_C001_A1 ← 選擇 A 的第 1 個後續
EVT_EX_C001_A2 ← 選擇 A 的第 2 個後續
EVT_EX_C001_B1 ← 選擇 B 的第 1 個後續事件觸發時機
每回合(季)的事件流程
回合開始
│
├─ 1. 季節事件(SN)
│ 系統自動檢查季節條件,觸發對應事件
│ 例:冬季糧食消耗加倍、春季疫病爆發
│
├─ 2. 生命週期事件(LF)
│ 檢查所有族人的年齡和健康狀態
│ 例:幼兒長大成少年、老人壽命到期、傷病惡化
│
├─ 3. 家園事件(HB)
│ 在庄園中隨機觸發 0–1 個事件
│ 例:外來者求助、內部衝突、設施損壞
│
├─ 4. 探索事件結算(EX)
│ 每位「派遣中」的成員結算探索進度
│ 若本回合返回,生成探索日誌(含多個事件的結果摘要)
│ 若仍在外,可能觸發途中事件
│
├─ 5. 主線事件檢查(QT)
│ 檢查是否滿足主線推進條件
│
└─ 6. 玩家行動階段
玩家安排族人的下一步行動探索日誌的事件生成
探索成員外出後,系統在背景為每回合生成 1–3 個探索事件。成員歸來時,這些事件彙整為一篇「探索日誌」呈現給玩家。
派遣出發
│
├─ 第 1 回合(移動中)
│ └─ 抽取 1 個路途事件(較低難度)
│
├─ 第 2 回合(抵達目的地)
│ └─ 抽取 2 個目的地事件(正常難度)
│
├─ 第 3 回合(返回途中)
│ └─ 抽取 1 個路途事件
│
└─ 歸來 → 生成探索日誌
日誌包含:每個事件的文字描述 + 自動結算結果探索事件的結算是自動的(不像家園事件需要玩家選擇)。系統根據角色屬性、技能和 D20 檢定自動判定結果。玩家閱讀的是「已經發生的故事」。
事件池與抽取機制
事件池分類
事件按情境分成獨立的事件池,抽取時只從對應池中選取:
| 事件池 | 觸發時機 | 每回合抽取數 |
|---|---|---|
| 探索池 (EX) | 成員外出探索時 | 每回合 1–3 個 |
| 家園池 (HB) | 每回合家園階段 | 0–1 個 |
| 季節池 (SN) | 每回合開始 | 0–1 個 |
| 生命池 (LF) | 角色狀態變化時 | 依角色數量 |
| 主線池 (QT) | 條件達成時 | 0–1 個 |
抽取規則
步驟 1:篩選可用事件
從對應池中,過濾出滿足所有條件的事件:
condition欄位的條件全部為 trueregion欄位匹配當前區域(探索事件)season欄位匹配當前季節(或為空表示不限)once為 true 的事件,若已觸發過則排除cooldown回合數未到的事件排除
步驟 2:稀有度加權隨機
從篩選後的事件中,按稀有度權重隨機抽取:
| 稀有度 | 權重 | 說明 |
|---|---|---|
common | 60 | 日常遭遇,最頻繁出現 |
uncommon | 25 | 偶爾出現的特殊情況 |
rare | 12 | 少見且有重大影響 |
legendary | 3 | 極稀有,改變命運的事件 |
步驟 3:防重複機制
- 同一個事件在 4 回合(一年)內不重複出現
- 同類型事件(相同類型代碼)不在同回合內連續出現
- 「已清除」的地點事件池縮小,但不完全消失
事件結構
events.csv 欄位定義(更新版)
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
| id | string | 是 | 事件編碼,如 EVT_EX_C001 |
| name | string | 是 | 事件名稱(內部用,不顯示給玩家) |
| context | string | 是 | 情境代碼:EX/HB/SN/LF/QT |
| type | string | 是 | 類型代碼:C/E/D/H/T/S/F |
| rarity | string | 是 | 稀有度:common/uncommon/rare/legendary |
| region | string | 否 | 限定區域,如 R01 或 R01_L03,空值表示不限 |
| season | string | 否 | 限定季節:spring/summer/autumn/winter,空值表示不限 |
| condition | string | 否 | 觸發條件表達式(見條件語法) |
| script_file | string | 是 | 對應 Markdown 劇情檔案,如 events/EVT_EX_C001.md |
| choices | string | 否 | JSON 格式的選項陣列(探索事件通常無選項,自動結算) |
| auto_check | string | 否 | 自動檢定設定(探索事件用),如 {"attr":"strength","dc":12} |
| once | boolean | 否 | 是否只觸發一次,預設 false |
| cooldown | number | 否 | 冷卻回合數,預設 4 |
| tags | string | 否 | 標籤,逗號分隔 |
| chronicle | string | 否 | 觸發時寫入族誌的事件類型,如 exploration/injury/disease |
條件語法
事件的 condition 欄位使用以下語法:
基本條件
| 語法 | 範例 | 說明 |
|---|---|---|
| 屬性比較 | strength > 10 | 角色的力量屬性大於 10 |
| 資源比較 | res:food > 20 | 家族糧水資源大於 20 |
| 時間比較 | year >= 3 | 遊戲進行到第 3 年以上 |
| 季節判斷 | season == winter | 當前是冬季 |
| 地點狀態 | discovered:R02_L03 | 已發現西部沿海的第 3 個地點 |
| 家族階段 | stage >= settled | 家族已達到定居階段 |
| 人口數量 | population >= 5 | 家族人口 5 人以上 |
| 角色狀態 | has_tag:wounded | 角色帶有受傷標籤 |
| 技能檢查 | skill:combat >= 2 | 角色戰鬥技能 2 級以上 |
| 基因檢查 | has_gene:night_vision | 角色擁有夜視基因 |
| 設施檢查 | has_facility:medical | 庄園有醫療站 |
| 族誌檢查 | chronicle:disease_survived | 族誌中有康復記錄 |
邏輯組合
strength > 10 AND skill:combat >= 2 ← AND 邏輯
season == winter OR res:food < 10 ← OR 邏輯
NOT has_tag:wounded ← NOT 邏輯不支援巢狀括號,保持簡單。多個條件時優先順序:NOT > AND > OR。
選項與選擇
家園事件(玩家手動選擇)
家園事件和部分特殊事件會呈現選項,讓玩家做出決策。
choices JSON 格式
json
[
{
"id": "A",
"text": "收留這個流浪者",
"condition": "res:food > 10 AND population < max_population",
"check": {
"attr": "charisma",
"skill": "leadership",
"dc": 12
},
"success": {
"effects": [
{ "target": "res:food", "op": "add", "value": -5 },
{ "target": "population", "op": "add", "value": 1 },
{ "target": "res:reputation", "op": "add", "value": 3 }
],
"text": "流浪者感激地加入了你的家族。",
"next": "EVT_HB_F001_A1"
},
"failure": {
"effects": [
{ "target": "res:food", "op": "add", "value": -5 }
],
"text": "流浪者留下幾天後悄悄離開,帶走了一些食物。",
"next": null
}
},
{
"id": "B",
"text": "給他一些食物讓他離開",
"effects": [
{ "target": "res:food", "op": "add", "value": -2 }
],
"text": "你遞出一小包乾糧。他接過,點了點頭,轉身消失在灰塵裡。",
"next": null
},
{
"id": "C",
"text": "把他趕走",
"effects": [
{ "target": "res:reputation", "op": "add", "value": -2 }
],
"text": "你指向遠方。他沒說話,沿著來路走了。",
"next": null
}
]選項結構說明
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
| id | string | 是 | 選項代碼(A/B/C/D) |
| text | string | 是 | 選項顯示文字 |
| condition | string | 否 | 此選項的顯示條件,不滿足時隱藏 |
| check | object | 否 | D20 檢定設定(有此欄位表示此選項有成敗之分) |
| check.attr | string | 是 | 檢定用的屬性 |
| check.skill | string | 否 | 檢定用的技能(可疊加) |
| check.dc | number | 是 | 難度等級 |
| success | object | 否 | 檢定成功時的結果(配合 check 使用) |
| failure | object | 否 | 檢定失敗時的結果(配合 check 使用) |
| effects | array | 否 | 無檢定時的直接效果 |
| next | string | 否 | 後續事件 ID,null 表示事件結束 |
探索事件(自動結算)
探索事件不提供選項,系統自動用角色屬性 + D20 結算:
json
{
"auto_check": {
"attr": "strength",
"skill": "combat",
"dc": 14
},
"success_effects": [
{ "target": "res:material", "op": "add", "value": 5 },
{ "target": "res:reputation", "op": "add", "value": 2 }
],
"failure_effects": [
{ "target": "health", "op": "add", "value": -15 },
{ "target": "tag", "op": "add", "value": "wounded" }
]
}效果系統
effect 格式
json
{ "target": "目標", "op": "運算", "value": "值" }支援的 target
| target | 說明 | 範例 |
|---|---|---|
res:food | 糧水資源 | { "target": "res:food", "op": "add", "value": -10 } |
res:material | 材料資源 | |
res:knowledge | 知識資源 | |
res:reputation | 聲望資源 | |
health | 角色健康值 | |
radiation | 角色輻射累積 | |
tag | 角色標籤 | { "target": "tag", "op": "add", "value": "wounded" } |
tag | 移除標籤 | { "target": "tag", "op": "remove", "value": "wounded" } |
skill:[name] | 技能經驗 | { "target": "skill:combat", "op": "add", "value": 10 } |
location | 地點狀態 | { "target": "location", "op": "discover", "value": "R02_L03" } |
chronicle | 族誌記錄 | { "target": "chronicle", "op": "add", "value": "exploration" } |
population | 人口增減 | { "target": "population", "op": "add", "value": 1 } |
lifespan | 壽命修正 | { "target": "lifespan", "op": "add", "value": -2 } |
status | 角色狀態 | { "target": "status", "op": "set", "value": "resting" } |
支援的 op(運算)
| op | 說明 |
|---|---|
add | 加值(可為負數) |
set | 直接設定 |
multiply | 乘以倍率 |
discover | 發現(地點專用) |
remove | 移除(標籤專用) |
事件與其他系統的銜接
事件 → 族誌
事件的 chronicle 欄位指定觸發時是否寫入族誌。事件引擎在執行完效果後,自動呼叫族誌系統記錄。
事件 → 探索日誌
探索事件的結果文字(成功/失敗的 Markdown 段落)按時間順序串接,生成一篇完整的探索日誌。日誌格式:
markdown
# 探索日誌:[成員名] 前往 [地點名]
## 出發 — [年]年[季]季
[路途事件描述]
## 抵達 [地點名]
[目的地事件 1 描述]
[目的地事件 2 描述]
## 歸途
[回程事件描述]
## 收穫與損失
- 獲得:材料 +5、知識 +2
- 損失:健康 -15
- 狀態:受傷(需靜養 2 回合)事件 → 季節影響
季節會修正事件的觸發權重和效果數值:
| 季節 | 影響 |
|---|---|
| 春 | 疫病事件權重 +20%、採集資源 +10% |
| 夏 | 輻射危害加劇、戰鬥事件權重 +10% |
| 秋 | 交易事件權重 +20%、食物收穫 +20% |
| 冬 | 糧食消耗加倍、自然災害權重 +30%、探索移動多 1 回合 |
事件 → D20 檢定
所有帶有 check 或 auto_check 的事件都走 D20 檢定系統:
擲 D20 + 屬性修正值 + 技能加成 + 裝備加成 + 季節修正 ≥ DC → 成功Markdown 劇情腳本格式
每個事件對應一個 .md 檔案,存放在 public/scripts/events/ 目錄。
檔案命名
public/scripts/events/EVT_EX_C001.md
public/scripts/events/EVT_HB_F001.md檔案結構
markdown
# [事件名稱]
[開場描述文字。所有玩家都會看到這段。]
> [條件: strength > 12] [力量夠高時額外顯示的描述段落。]
> [條件: has_gene:night_vision] [有夜視基因時額外顯示的段落。]
---
## 結果:成功
[D20 檢定成功時顯示的文字。]
## 結果:失敗
[D20 檢定失敗時顯示的文字。]
---
## 選項 A 結果
[選擇 A 後顯示的文字。]
## 選項 B 結果
[選擇 B 後顯示的文字。]條件文字語法
markdown
> [條件: 表達式] 條件成立時顯示的文字事件引擎在載入 Markdown 後,解析所有 > [條件: ...] 區塊,根據角色當前狀態決定是否顯示。
事件範例
範例 1:探索戰鬥事件
events.csv 資料:
| 欄位 | 值 |
|---|---|
| id | EVT_EX_C001 |
| name | 路邊埋伏 |
| context | EX |
| type | C |
| rarity | common |
| region | R01 |
| season | |
| condition | |
| script_file | events/EVT_EX_C001.md |
| auto_check | {"attr":"strength","skill":"combat","dc":12} |
| tags | combat,bandit |
| chronicle | exploration |
EVT_EX_C001.md:
markdown
# 路邊埋伏
灌木叢後面有動靜。三個人影從土坡後站起來,手裡握著削尖的鋼管。
> [條件: skill:combat >= 2] 你的身體比意識更快反應,手已經摸到了腰間。
> [條件: has_gene:night_vision] 你在他們動作之前就看到了他們的位置。
---
## 結果:成功
鋼管砸下來的時候你已經不在原地。三次交手之後,他們丟下武器跑了。地上留了一個布袋,裡面有幾塊金屬片和半壺水。
## 結果:失敗
你反應慢了半拍。鋼管擊中肩膀,痛感讓視線模糊了一瞬。等你重新站穩,他們已經帶著你的背包消失在廢墟後面。範例 2:家園選擇事件
events.csv 資料:
| 欄位 | 值 |
|---|---|
| id | EVT_HB_E001 |
| name | 流浪者來訪 |
| context | HB |
| type | E |
| rarity | common |
| condition | stage >= settled AND population < max_population |
| script_file | events/EVT_HB_E001.md |
| choices | (見上方完整的 choices JSON 範例) |
| tags | social,newcomer |
範例 3:季節危機事件
events.csv 資料:
| 欄位 | 值 |
|---|---|
| id | EVT_SN_H001 |
| name | 冬季糧荒 |
| context | SN |
| type | H |
| rarity | uncommon |
| season | winter |
| condition | res:food < 15 |
| script_file | events/EVT_SN_H001.md |
| choices | [{"id":"A","text":"減少配給","effects":[{"target":"health","op":"add","value":-5}]},{"id":"B","text":"緊急派人狩獵","condition":"population >= 3","check":{"attr":"strength","skill":"survival","dc":14},"success":{"effects":[{"target":"res:food","op":"add","value":8}]},"failure":{"effects":[{"target":"health","op":"add","value":-10},{"target":"tag","op":"add","value":"wounded"}]}}] |
| tags | crisis,winter,food |
事件數量規劃
最小可玩原型(MVP Phase 1)所需事件數
| 事件池 | 數量 | 說明 |
|---|---|---|
| 探索 (EX) | 15–20 個 | 每區域 2–3 個基礎事件 |
| 家園 (HB) | 8–10 個 | 基礎的家園日常 |
| 季節 (SN) | 4–8 個 | 每季 1–2 個 |
| 生命 (LF) | 5–6 個 | 出生、成年、死亡等必要事件 |
| 主線 (QT) | 2–3 個 | 序章和第一個線索 |
MVP 最少需要約 35–45 個事件,之後持續擴充。
長期目標
| 事件池 | 目標數量 |
|---|---|
| 探索 (EX) | 150+ |
| 家園 (HB) | 50+ |
| 季節 (SN) | 20+ |
| 生命 (LF) | 30+ |
| 主線 (QT) | 30+ |
| 總計 | 280+ |