← 回首頁

LOOP VILLAGE / ENGINEERING FIELD NOTES

Loop Village 系統架構導覽

一個 tick、一趟交付、一次政策表決:畫面上的變化有後端依據。這裡呈現目前 0.3.1 的真實鏈路,不把規劃中的能力當成已完成的系統。

一筆交易,兩條讀取與發布路徑

瀏覽器命令
Cloudflare → Kong
VillageController
SimulationService
DB 交易

世界狀態、此次領域事件與對應 Outbox row 在同一個 MariaDB transaction 內寫入。公開入口由 Kong 限定 Village API;2026-09-03 實測主站流量未經 gate-proxy,不能把它當作公開安全邊界。

畫面分支 · DB → Snapshot → 地圖

buildSnapshot() 彙整居民、地點、資源、最近 30 筆事件與治理狀態。瀏覽器每 3 秒讀取 /api/village/snapshot,也在命令成功後使用回傳快照。

3D 地圖與說明卡投影後端座標與決策理由;不是 Kafka consumer,也不是 WebSocket 推播。

發布分支 · Outbox → Publisher → Kafka

Publisher 預設每 2 秒讀取最多 100 筆 PENDING;Kafka 確認後標記 PUBLISHED。失敗會記錄次數與錯誤,保留 PENDING 供下次嘗試。

發布成功但尚未標記時若程序中斷,事件可能重送;這不是端到端 exactly-once 保證。地圖不等待 Kafka 才更新。

展開一條真實旅程

這些是靜態程式導覽,不會發送命令或改變公開共用世界。

01 · 推進一個 tick
  1. 前端送出 POST /api/village/control,action 為 STEP
  2. VillageSimulationService.control() 進入交易,依固定 tick、角色與時間表執行 advanceOneTick()
  3. 居民的位置、活動、體力與決策理由持久化;觸發領域動作時,recordEvent() 同時保存 world event 與 Outbox。
  4. 成功回傳快照後,地圖呈現新狀態。固定初始世界與相同命令順序可重現規則結果;不是逐位元一致的時間戳重播。
02 · 資源從產地交付到倉庫
  1. 工作與交付時段由 tick 決定;農夫、林務員與搬運者使用各自的明確規則。
  2. 一次交付先扣來源,再加目的地;庫存不足就只搬實際可用數量。交付不會憑空生產資源。
  3. RESOURCE_DELIVERED 保存來源、目的與數量,事件 ID 由 tick、居民與動作識別組成,同 ID 寫入 Outbox。
  4. 整合測試逐角色比較交付前後數量,確認來源減量=目的增量。這是資源守恆,不是已實作的複式帳本。
03 · 政策表決,然後承擔後果
  1. POST /api/village/governance/proposals/{id}/convene 讓八位規則型居民依角色產生選票及理由;非 READY 的提案拒絕重複召開。
  2. 通過的政策排到下一個 24-tick 邊界生效;被否決的政策不改變資源產出。
  3. 生效滿一天後,各居民保存一次回饋與 wellbeing 變化;既有 feedback 作為一次性評估的防重依據。
  4. 投票、生效與評估各有持久化事件及 Outbox 證據。公開世界的歷史 wellbeing 殘留仍待擁有者決定補償方式,這次沒有重寫歷史。

能力邊界,也是工程事實

居民是確定性規則角色,不是有意識或 LLM 驅動的 AI。村莊是公開共用世界,控制與 RESET 仍會影響其他訪客;請勿輸入真實個資。

目前以單一程序的 synchronized 協調呼叫,並非分散式鎖或 Village 樂觀鎖保證。事件不是完整 event-sourcing 重建日誌;Outbox 尚未建立完整下游 consumer 投影。這些限制不能用技術名詞掩蓋。

公開來源與模擬邊界 →