装备合成系统开发文档
装备合成系统服务端+客户端实现,含合成算法、消耗品扣减、数据库写入
装备合成系统开发文档
一、需求概述
玩家消耗武器碎片 + 金币,合成完整武器。
- 碎片来源:抽奖系统产出
- 武器归属:入库
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
职责:
- 启动时加载
Synthesis.csv到内存(Dictionary<int, SynthesisRecipe>) - 合成核心逻辑:
bool CanSynthesize()/SynthesisResult Synthesize() - 扣费 + 发奖
关键接口:
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)
八、注意事项
- #flag 语义:服务器需独立解析
#0/#1,客户端 CSynthesis.cs 已简化为只读第一个材料,不处理 flag - 碎片不足判断:需从
inventory.items中读取实际持有量,而非直接扣减 - 原子性:碎片扣除和武器发放应在同一事务或连续 DB 操作中完成,避免碎片扣了但武器未发的状态
- 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 判断(待联调)
所有内容仅供学习与交流,转载须标明链接。未经同意,禁止作为商业用途,有特殊需求请联系站长。
