跳轉到

MatchRPG Bot 開發(續):BooleanBackpack 語義澄清、好感度 Bug、前端 Dungeon 404 與體力恢復測試

文檔資訊

  • 分類: debugging
  • 難度: advanced
  • 預估閱讀時間: 30 分鐘
  • 標籤: postgresql, migration, pg_partman, docker, game-design, hero-unlock, formation, bot-testing, dirty-migration, publisher-schema, resource-system, admin-cmd, gamedata, boolean-backpack, stamina-recovery, affection-level, grafana, loki, dungeon-front-item, boolean-auto-open, teach-chapter-flow, fsnotify

摘要

延續上一 session,本次完成 BooleanBackpack 語義澄清與修正(關鍵:BooleanBackpack=false 只是不顯示在背包,與自動領獎無關,自動領獎由 BooleanAutoOpen 控制)、好感度升級 Bug A 方案修正(teach_progress create 寫死 relation_level=0 vs DB default 問題)、前端 GetDungeonDetail 404 根因診斷(前端未使用 server response)、Docker bind mount fsnotify 不觸發導致 config 無法熱載入的體力恢復測試策略,以及前置道具(DungeonFrontItem)限時道具情境補全。另記錄 MaxStackQuantity 與 BooleanBatch 欄位尚未實裝。

關鍵學習

  • BooleanBackpack=false 的語義是「道具不顯示在玩家可見背包」,NOT 控制自動領獎。自動領獎行為由 BooleanAutoOpen 控制,誤判根因會修錯方向

  • 英雄解鎖第 3 階段獎勵失敗的正確根因:BooleanAutoOpen 設定問題,而非 BooleanBackpack

  • 前端 GetDungeonDetail 404 根因:前端沒有使用 server 回傳的 response,而是自己組 dungeonId(10110000001),問題在前端側

  • teach_chapter_flow SKIP 根因:teach service create 邏輯在 Go code 裡寫死 relation_level=0,沒用 DB default(migration 040 改成 1)

  • 體力恢復 bot 測試:Docker bind mount 上 fsnotify 不觸發,config 改不了。解法是 setup/teardown 中直接修改記憶體中的 config 值,測試完自動還原

  • 前置道具(DungeonFrontItem)與局內道具是兩種不同機制,需要分別測試;限時戰前道具不應扣到背包裡的普通道具

  • Migration 035 三項修正(CREATE SCHEMA IF NOT EXISTS partman、detach/drop 舊 partition、移除 run_maintenance_proc)是正確方向,035 確認尚未在任何環境執行,可安全直接修改

  • MaxStackQuantity 和 BooleanBatch 兩個 gamedata 欄位目前尚未實裝,已記錄待後續補

  • admin 指令可直接對特定 player ID 配置道具,支援前端測試臨時需求

  • Grafana Loki 查詢:{container="matchrpg-twirpserver"} |= "user_id" 可過濾特定玩家 log

技術細節

英雄解鎖機制(PD 確認)

PD 確認目前版本**無預設英雄**,玩家須打關卡解鎖英雄。影響範圍:

  • startBattle 需正確處理空 heroIDs
  • hero_formation 欄位改為 nullable(Migration 039)
  • Bot 情境不能假設玩家有初始英雄

BooleanBackpack vs BooleanAutoOpen 語義(重要澄清)

企劃(Jerry Sun)確認正確語義:

  • BooleanBackpack=false:道具不顯示在玩家可見背包,但仍然存在且可被使用
  • BooleanAutoOpen:控制道具被領取時是否自動開啟/發放內容物

舊版理解錯誤:原本認為 BooleanBackpack=false 導致英雄解鎖第 3 階段獎勵失敗。 正確根因:應檢查 BooleanAutoOpen 欄位設定,item 10210000023 的自動開啟行為由此控制。

teach_chapter_flow SKIP 根因與修正

teach service 的 create teach_progress row 時,Go code 裡**寫死 relation_level=0**,沒有用 DB default(migration 040 已將 default 改成 1)。修正方式:移除 Go code 中的寫死值,讓 DB default 生效。

前置道具(DungeonFrontItem)vs 局內道具

兩種完全不同的機制:

  • 前置道具(DungeonFrontItem):玩家在進入副本前選擇攜帶,進入後自動釋放的道具(cross-battle 配備)
  • 局內道具:戰鬥中使用的消耗品
  • 限時戰前道具:不應扣到背包裡的普通道具,需要獨立情境驗證

StartBattle 回傳 item not owned in backpack(error code 15)的根因是前端傳入的 frontItem 玩家未持有。

體力恢復 Bot 測試策略

核心問題:Docker bind mount 上 fsnotify 不觸發,config 檔案修改後 server 無法熱載入。

A 方案解法:setup/teardown 中直接修改記憶體中的 config 值(加快恢復速率),測試完自動還原,不影響前端環境。此方案不依賴檔案系統事件,可在 Docker 環境穩定運作。

Migration 035 修正

migrations/postgres/035_partman_changelog_auto_management.up.sqlpostgres:16-alpine 會失敗(無 pg_partman / pg_cron)。

三項修正內容(已驗證正確):

-- 1. 確保 schema 存在
CREATE SCHEMA IF NOT EXISTS partman;

-- 2. 先 detach/drop 015 建立的舊手動 partition(命名衝突)
ALTER TABLE changelog DETACH PARTITION changelog_old;
DROP TABLE changelog_old;

-- 3. 移除以下行(不可在 migration transaction 內執行)
-- CALL partman.run_maintenance_proc();

035 確認尚未在任何環境執行,直接修改 SQL 安全可行。

尚未實裝的 Gamedata 欄位

- MaxStackQuantity  // 最大堆疊數量(已在 schema,server 未實裝)
- BooleanBatch      // 批量處理標記(已在 schema,server 未實裝)

資源系統重構

確認 player.set_currency / AdminSetCurrency 無任何引用後直接刪除,不保留向下相容包袱。新增 internal/modules/admin/cmd_player_set_resource.go,命名反映新架構(簡單資源 + 體力 pool)。

What Changed

BooleanBackpack 根因分析從「錯誤理解」修正為「正確語義」: 舊版認為 BooleanBackpack=false 導致英雄解鎖第 3 階段失敗,本次 session 企劃確認正確語義後,根因修正為 BooleanAutoOpen 欄位設定問題。這是重要的認知更新,影響後續 gamedata 問題的診斷方向。

teach_chapter_flow 根因確認並修正: Go code 寫死 relation_level=0 導致好感度無法升級。修正為移除寫死值,讓 migration 040 的 DB default(值為 1)生效。此修正需重建 server 才能驗證,tunnel 環境下暫為 A 方案待驗。

體力恢復測試新增 Docker fsnotify 限制的認知: Docker bind mount 上 fsnotify 不觸發是關鍵技術限制,導致 config 熱載入策略失效。正確解法是在記憶體層面修改 config 並在 teardown 還原,而非依賴檔案系統事件。Bot 情境從初始三種擴充至覆蓋三月交付版本所有核心場景,含限時戰前道具情境。

So What

本 session 最重要的價值是修正了對 BooleanBackpack 語義的錯誤理解。這類 gamedata flag 的語義誤判非常危險:如果按舊版理解修程式碼,會修錯方向並引入新 bug。企劃澄清後的正確理解(BooleanBackpack=外觀控制,BooleanAutoOpen=行為控制)是未來處理類似 gamedata 問題的關鍵參考。

前端 Dungeon 404 的診斷展示了一個重要模式:server 回傳正確但前端未使用 response,這類問題需要前後端協作確認,不能只看 server log。Docker bind mount fsnotify 不觸發的發現也是未來設計 Docker 環境測試策略時的重要限制條件。

Trade-offs

  • 體力恢復測試:記憶體改 config vs 真實等待:記憶體方案可控、不影響前端,缺點是測試的不是真實 config 路徑;選此方案因為 Docker fsnotify 不觸發且真實等待在 CI 不可行
  • 好感度 A 方案 vs 重建 server:使用者確認選 A,接受工程上的妥協以避免影響前端測試進行中的環境
  • Migration 035 直接修改 vs 新增 migration:035 確認未在任何環境執行,直接修改安全;若已部署則必須新增 migration
  • admin 指令配置道具 vs 測試 fixture:admin 指令靈活可支援前端臨時需求,但不如 fixture 可重複且有版本控制

Try It Fast

# 清掉 DB 重建,驗證所有 migration 乾淨通過
docker compose down -v && docker compose up -d

# 確認 035 不再卡住,partition 衝突已解
docker compose logs db-migrate | grep -E "035|partman|error"

# 確認 formation 欄位允許 null
docker compose exec postgres psql -U postgres -d game \
  -c "\d player_heroes" | grep formation

# 確認舊命名完全刪除
grep -r "set_currency\|AdminSetCurrency" --include="*.go" .

# 確認 BooleanAutoOpen 欄位在 gamedata item 中設定正確
# item 10210000023 的 BooleanAutoOpen 應為 true(第 3 階段獎勵需自動開啟)

# 對特定玩家配置道具(支援前端測試)
# admin cmd 指定 player ID: 019d0664-81d3-711a-a9b7-7d5ad394e234

# Grafana Loki 查詢特定玩家 log
# http://localhost:3000
# Query: {container="matchrpg-twirpserver"} |= "user_id"

# Bot 測試(tunnel 環境,不重啟 server)
go test ./internal/bot/... -v

Recommendation

  1. 【優先】 確認 item 10210000023 的 BooleanAutoOpen 欄位設定正確,驗證英雄解鎖第 3 階段流程完整跑通
  2. 【優先】 MaxStackQuantity 和 BooleanBatch 兩個未實裝欄位,需在後續 sprint 補實裝並補測試
  3. 好感度 A 方案修正(teach_progress relation_level DB default)在可重建 server 時完整驗證並補 unit test
  4. 確認 teach_chapter_flow 在好感度修正後可從 SKIP 改為 PASS
  5. 前端確認 GetDungeonDetail 已改用 server response 的 dungeonId(非自組)
  6. 前置道具(DungeonFrontItem)bot 情境需分別驗證「普通道具」和「限時道具」兩種狀態,確認限時道具不扣背包庫存
  7. 體力恢復 bot 測試的 setup/teardown config 還原邏輯需驗證不影響其他並行測試
  8. 進 DEV 前執行 docker compose down -v && docker compose up -d 完整驗證 migration(game + publisher)
  9. 補充 startBattle 空 heroIDs 的 unit test(P2,不阻擋 DEV)
  10. 未來若需要完整 pg_partman,應在 Docker compose 使用支援 extension 的自建 image

本文檔由 Semi-Brain 自動生成

Session ID: d9903c52-a136-4d3b-b5d9-99c8d0c4d1c1

分析信心度: 97%