装备合成系统开发文档

装备合成系统服务端+客户端实现,含合成算法、消耗品扣减、数据库写入

最后编辑时间:yaohua

装备合成系统开发文档

一、需求概述

玩家消耗武器碎片 + 金币,合成完整武器

  • 碎片来源:抽奖系统产出
  • 武器归属:入库 character_inventory.items(weaponId → 1)

二、数据结构

配置文件

Synthesis.csv/Volumes/2TAPFS/UnityProject/NinjaFall/Table/Synthesis.csv

字段 类型 说明
id int 合成配方ID
resultId int 合成结果物品ID(武器,2000+)
resultCount int 合成结果数量(均为1)
materials string 材料数组,格式 碎片ID碎片ID#flag(多材料用 # 分隔,如 1000#0
quantities string 材料数量数组,与 materials 一一对应
goldCost int 金币消耗(均为100)

CSV 示例:

id|int,resultId|int,resultCount|int,materials|int|1,quantities|int|1,goldCost|int|1
1,2000,1,1000#0,30#100,100
...
13,2012,1,1012#1,100#1,100   ← 需碎片×100 + 金×1
14,2013,1,1013#1,100#1,100
15,2014,1,1014#1,100#1,100
16,2015,1,1015#1,100#1,100

#flag 语义:

  • #0 — 仅碎片,无额外材料
  • #1 — 碎片 + 金币(quantity 列第二值 1 = 金币数量)

材料消耗规则:

配方ID 结果 碎片ID 碎片数量 金币消耗 #flag
1-12 武器 2000-2011 碎片 1000-1011 30 或 50 100 #0
13-16 武器 2012-2015 碎片 1012-1015 100 100 + 金×1 #1

物品ID对照

物品 ID
金币 0
宝石 1
碎片 1000-1011 1000-1011
武器 2000-2015 2000-2015

三、Proto 消息

// 合成请求
message C2S_SynthesisRequest {
    int32 synthesis_id = 1;   // 配方ID(1-16)
}

// 合成结果
message S2C_SynthesisResult {
    int32 code = 1;           // 0=成功,其他=错误码
    string msg = 2;
    int32 result_id = 3;      // 获得的武器ID(resultId)
    int32 result_count = 4;   // 获得数量(均为1)
    bool is_new = 5;          // 是否新获得(背囊中原本没有该武器)
}

// 物品变化同步(服务端主动推送,与抽奖共用)
message S2C_InventoryChanged {
    int32 currency_delta = 1;
    int32 gems_delta = 2;
    map<int32, int32> items_delta = 3;   // itemId → delta
}

四、错误码

code 说明
0 成功
1 角色不存在
2 配方不存在
3 碎片不足
4 金币不足(#flag=1 时)
5 背包不存在

五、完整流程

客户端                         服务端
   |                              |
   |--- C2S_SynthesisRequest --->|
   |    (synthesis_id=1)         |
   |                              | 1. 读取 Synthesis.csv 配方
   |                              | 2. 验证碎片余额(inventory.items[碎片ID])
   |                              | 3. 若 #flag=1,验证金币余额(currency)
   |                              | 4. 扣碎片 + 扣金币(如有)
   |                              | 5. 发放武器(inventory.items[resultId]++)
   |                              |
   |<-- S2C_SynthesisResult ------|
   |    (code=0, result_id=2000)  |
   |                              |
   |<-- S2C_InventoryChanged ----|
   |    (currency_delta=-100,     |
   |     items_delta={1000:-30,   |
   |                 2000:+1})   |

六、服务端实现

新增文件

server/SynthesisService.cs

职责:

  1. 启动时加载 Synthesis.csv 到内存(Dictionary<int, SynthesisRecipe>
  2. 合成核心逻辑:bool CanSynthesize() / SynthesisResult Synthesize()
  3. 扣费 + 发奖

关键接口:

public class SynthesisRecipe {
    public int Id;
    public int ResultId;
    public int ResultCount;
    public int FragmentId;      // 材料碎片ID
    public int FragmentCount;    // 材料碎片数量
    public int GoldCost;        // 金币消耗
    public bool HasExtraGold;   // #flag=1 时为 true
}

public Task<(int code, string msg, int resultId, int resultCount, bool isNew)> 
    HandleSynthesisAsync(long characterId, int synthesisId);

server/SynthesisController.cs

职责:

  • WebSocket 消息处理(MsgId.C2S_SynthesisRequest
  • 调用 SynthesisService
  • 构造 S2C_SynthesisResult 返回
  • 推送 S2C_InventoryChanged

数据库操作

使用现有 character_inventory 表:

  • 碎片扣减:UpdateInventoryItemAsync(characterId, fragmentId, -count)
  • 武器增加:UpdateInventoryItemAsync(characterId, resultId, +1)
  • 金币扣减:调用 UpdateCurrencyAndGems(characterId, -goldCost, 0)

七、客户端实现

WebSocketService.cs

新增处理:

case MsgId.S2C_SynthesisResult:
    var msg = _decoder.DecodeS2C_SynthesisResult(pkg.Data);
    MainThreadDispatcher.Invoke(() => OnSynthesisResult?.Invoke(msg));
    break;

事件:

public event Action<S2C_SynthesisResult> OnSynthesisResult;

InventoryService.cs

UpdateByDelta 已支持增量更新,无需额外改动(碎片扣减、武器入库均走 items_delta)。

客户端数据表

client/Assets/Scripts/GameConfig/CSynthesis.cs(已有,仅含碎片ID和数量,不区分 #flag


八、注意事项

  1. #flag 语义:服务器需独立解析 #0/#1,客户端 CSynthesis.cs 已简化为只读第一个材料,不处理 flag
  2. 碎片不足判断:需从 inventory.items 中读取实际持有量,而非直接扣减
  3. 原子性:碎片扣除和武器发放应在同一事务或连续 DB 操作中完成,避免碎片扣了但武器未发的状态
  4. isNew 判断inventory.items[resultId] == 0 时为新获得

九、已完成清单

  • [x] 更新 Ninjiafall1Proto.proto(添加 C2S_SynthesisRequest / S2C_SynthesisResult)
  • [x] 重新编译 protobuf(build.sh)
  • [x] 服务端:SynthesisService.cs — CSV 加载、#flag 解析、原子合成
  • [x] 服务端:SynthesisController.cs(WebSocket)— C2S_SynthesisRequest → S2C_SynthesisResult + S2C_InventoryChanged
  • [x] 服务端:WebSocketServer.cs — 注册 MsgC2SSynthesisRequest 分支
  • [x] 服务端:Program.cs — DI 注册 SynthesisService
  • [x] 客户端:ProtobufTypes.cs — 添加 C2S_SynthesisRequest / S2C_SynthesisResult
  • [x] 客户端:ProtobufCodec.cs — 编解码支持
  • [x] 客户端:WebSocketService.cs — OnSynthesisResult 事件 + RequestSynthesis(int synthesisId)
  • [ ] 测试:碎片不足 / 金币不足 / 正常合成 / isNew 判断(待联调)
  • 留下精彩的评论吧~(0条)

所有内容仅供学习与交流,转载须标明链接。未经同意,禁止作为商业用途,有特殊需求请联系站长。