跳轉到

Game Item Exemption Resource Architecture

概念概覽

ExemptResourceType 集中式架構

核心知識

ExemptResourceType 集中式架構

道具是否豁免資源消耗(如體力、金幣)的判斷邏輯,不應分散在各 API 呼叫點,而應集中於配置層:

  • ItemConfig(Luban 生成)加入 ExemptResourceType 枚舉欄位,明確宣告此道具豁免哪種資源
  • PlayerService 啟動時呼叫 InitExemptMapping(),將 ItemConfig 掃描一次建成 map
  • 所有需要判斷的 API 統一透過 HasXxxPass() 查詢,禁止各自實作掃描邏輯
// 啟動時一次建立 mapping
func (s *PlayerService) InitExemptMapping() {
    for _, item := range itemConfigs {
        if item.ExemptResourceType != ExemptNone {
            s.exemptMap[item.ExemptResourceType] = append(...)
        }
    }
}

// O(1) 查找
func (s *PlayerService) HasStaminaPass(playerID string) bool {
    return s.exemptMap[ExemptStamina].HasActive(playerID)
}

擴充性設計

未來新增豁免類型(如「3分鐘無限體力」、「不消耗金幣通行證」),只需在 Luban ItemConfig 設定對應的 ExemptResourceType 值,不需修改程式碼,符合 Open-Closed 原則。

經驗教訓

  • 多個服務入口共用同一判斷邏輯時,應集中在配置層 + 啟動期 mapping,而非分散呼叫

  • 啟動期 O(1) mapping 的代價是 ItemConfig 與豁免邏輯耦合,但對遊戲後端通常可接受

  • Luban 重新生成配置代碼的成本需納入架構決策,但不應阻礙正確設計

常見陷阱

  • 各 API 各自掃描 ItemConfig 判斷豁免:邏輯分散、難以維護且性能差

  • 未在 PlayerService 啟動時初始化 mapping 就接收請求,會導致豁免判斷空值錯誤

  • 未來通行證邏輯複雜化(跨服務、多條件)時,此單層 mapping 可能需重構為獨立模組

相關概念

相關視角

以下頁面與本概念共享主題,但從不同角度切入。保留獨立視角同時提供交叉參考:

來源 Sessions

日期 Session 貢獻摘要

| 2026-03-18 | fb39b34e-2ba6-4c2c-9f93-26e1e73d0371 | 確立了以 ItemConfig.ExemptResourceType 欄位 + PlayerService 啟動 mapping 實現 O(1) 豁免查找的集中式架構模式 |


本概念頁面由 Semi-Brain Wiki 系統自動維護

最後更新: 2026-03-18