有一把剑WoW 老玩家没有不知道的。“灰烬使者”Ashbringer。提米手里那把黑色的剑暗影领主提里斯管理着它无数玩家在纳克萨玛斯里刷过这把刀。它掉落的概率低到离谱而且——每次掉落的灰烬使者随机属性还不一样。这就是 AzerothCore 物品系统要处理的核心场景之一同一把剑不同实例随机词缀。两套模板item_template 与 item_instance物品系统的核心和怪物一样是模板与实例的分离。item_template物品的类型定义全服同一类物品共用一份模板记录名称、属性、品质、图标、绑定规则等全服统一的配置item_instance物品的具体实例每个玩家背包里的每一个具体物品记录随机属性、耐久度、持有者模板可以共享不需要为每个玩家的物品单独存类型信息实例存每件物品独享的数据。item_template 的字段两百多个字段拆开看分几类类型标识物品类别、子类别、材质、模型 ID名称与描述name、description、displayid属性配置基础数值armor、damage、block、spellcharges、随机属性池RandomProperty / RandomSuffix行为规则bonding绑定规则拾取绑定/装备绑定/使用绑定、商店价格、职业/种族限制背包规则bagfamily背包家族矿石袋、草药袋、ContainerSlots如果是背包记录格子数两百多个字段里最核心的是前几类。后面很多字段是为特殊物品准备的常规武器装备大量字段为空。随机属性机制为什么同一把剑属性不一样WoW 里有一类装备叫随机属性装备——同一个物品模板每次掉落属性不同。拿灰烬使者来说item_template定义了它是一把传奇品质的双手剑但提供 30 暗影伤害还是40 耐力每次掉落时从词缀池里抽取。AzerothCore 用两张表处理这个item_template.RandomProperty随机的固定词缀“XX 敏捷”item_template.RandomSuffix随机的百分比词缀“15% 敏捷”随机属性在物品生成时掉落、购买、制造完成抽取结果写入item_instance.randomPropertyId——生成后属性就固定了后续不再变化。服务器不需要在运行时重新计算随机属性只需要存一个 ID。这个设计和.game_event_save 恰好相反活动叠加层里的进度需要保留玩家背包里的随机属性一旦确定就不该再变——否则今天刷出的灰烬使者是力敏双加明天上线变成智精耐加这个游戏就没法玩了。item_instance物品的生命周期item_instance是物品在服务器内存中的持久化快照。角色下线时背包状态写进去上线时从这里读回来。字段说什么itemguid物品实例唯一 IDowner_guid当前持有者角色 IDitemEntry关联的物品模板 IDcreatorGuid制造者 ID如果是制造的randomPropertyId抽取到的随机词缀 IDdurability当前耐久度flags状态标志灵魂绑定、已交易、已锁定注意耐久度在item_instance里而不是item_template里——这是对的。耐久度是实例级数据同一种物品持有时间越长耐久越低。不可能存在一个模板级的耐久度。character_inventory物品放在哪里item_instance存物品本身character_inventory存物品放在哪里character_guid, bag, slot, itemguid说的是角色 X 的背包 Y 格子 Z 里放着物品实例 M。把这两张表联合起来能完整还原一个角色背包的状态每个位置放的是什么物品物品当前的耐久度和随机属性是什么。character_inventory里用bag字段区分普通槽位和背包内部格子bag0是普通背包槽位bag物品实例ID表示这个格子在某个背包内部。这套设计让背包本身也是一个物品实例——放进背包槽位的是一个item_instance这个实例内部的格子由character_inventory里的bag字段指向这个实例的 ID。绑定规则灵魂绑定是怎么回事item_template里的bonding字段控制物品能否流通NO_BODY不绑定任何人都可以交易ON_PICKUP拾取时绑定捡起来就变成灵魂绑定ON_EQUIP装备时绑定穿上后变成灵魂绑定ON_USE使用时绑定QUEST ITEM任务物品不可丢弃、不可交易绑定信息在物品生成时写入item_instance.flags。一旦绑定服务器在交易时检查这个标志拒绝绑定物品的交易请求。还有一个边缘情况团队掉落被分配后 2 小时内可以交易——团队散了玩家可以把刚拿到的装备交易给队友。item_soulbound_trade_data表记录这个临时交易窗口的截止时间。物品外观displayid 的作用item_template.displayid是物品在客户端显示的模型 ID。不同的displayid对应不同的图标和 3D 模型。服务器只存一个 ID客户端负责渲染。有趣的是AzerothCore 通过修改displayid可以让同一个物品模板在不改变数值的情况下呈现完全不同的外观——外观和数值解耦开发者可以自由组合。这在自定义服务器里是常见的修改手段。回头看 AzerothCore 的物品系统有一条主线贯穿始终模板定义应该有什么属性实例记录这个具体的物品现在是什么状态。这两层分离让物品系统能够同时处理两种场景——全服统一的物品类型配置和每个玩家背包里独一份的物品实例。系列一到这里四个核心库全部聊完。模板模式、实例模式、条件系统、叠加层……这些反复出现的核心概念构成了 AzerothCore 数据设计的骨架。系列二会从代码层深入聊这些系统的具体实现。
AzerothCore学习笔记·数据库09:物品系统——模板表与背包结构
有一把剑WoW 老玩家没有不知道的。“灰烬使者”Ashbringer。提米手里那把黑色的剑暗影领主提里斯管理着它无数玩家在纳克萨玛斯里刷过这把刀。它掉落的概率低到离谱而且——每次掉落的灰烬使者随机属性还不一样。这就是 AzerothCore 物品系统要处理的核心场景之一同一把剑不同实例随机词缀。两套模板item_template 与 item_instance物品系统的核心和怪物一样是模板与实例的分离。item_template物品的类型定义全服同一类物品共用一份模板记录名称、属性、品质、图标、绑定规则等全服统一的配置item_instance物品的具体实例每个玩家背包里的每一个具体物品记录随机属性、耐久度、持有者模板可以共享不需要为每个玩家的物品单独存类型信息实例存每件物品独享的数据。item_template 的字段两百多个字段拆开看分几类类型标识物品类别、子类别、材质、模型 ID名称与描述name、description、displayid属性配置基础数值armor、damage、block、spellcharges、随机属性池RandomProperty / RandomSuffix行为规则bonding绑定规则拾取绑定/装备绑定/使用绑定、商店价格、职业/种族限制背包规则bagfamily背包家族矿石袋、草药袋、ContainerSlots如果是背包记录格子数两百多个字段里最核心的是前几类。后面很多字段是为特殊物品准备的常规武器装备大量字段为空。随机属性机制为什么同一把剑属性不一样WoW 里有一类装备叫随机属性装备——同一个物品模板每次掉落属性不同。拿灰烬使者来说item_template定义了它是一把传奇品质的双手剑但提供 30 暗影伤害还是40 耐力每次掉落时从词缀池里抽取。AzerothCore 用两张表处理这个item_template.RandomProperty随机的固定词缀“XX 敏捷”item_template.RandomSuffix随机的百分比词缀“15% 敏捷”随机属性在物品生成时掉落、购买、制造完成抽取结果写入item_instance.randomPropertyId——生成后属性就固定了后续不再变化。服务器不需要在运行时重新计算随机属性只需要存一个 ID。这个设计和.game_event_save 恰好相反活动叠加层里的进度需要保留玩家背包里的随机属性一旦确定就不该再变——否则今天刷出的灰烬使者是力敏双加明天上线变成智精耐加这个游戏就没法玩了。item_instance物品的生命周期item_instance是物品在服务器内存中的持久化快照。角色下线时背包状态写进去上线时从这里读回来。字段说什么itemguid物品实例唯一 IDowner_guid当前持有者角色 IDitemEntry关联的物品模板 IDcreatorGuid制造者 ID如果是制造的randomPropertyId抽取到的随机词缀 IDdurability当前耐久度flags状态标志灵魂绑定、已交易、已锁定注意耐久度在item_instance里而不是item_template里——这是对的。耐久度是实例级数据同一种物品持有时间越长耐久越低。不可能存在一个模板级的耐久度。character_inventory物品放在哪里item_instance存物品本身character_inventory存物品放在哪里character_guid, bag, slot, itemguid说的是角色 X 的背包 Y 格子 Z 里放着物品实例 M。把这两张表联合起来能完整还原一个角色背包的状态每个位置放的是什么物品物品当前的耐久度和随机属性是什么。character_inventory里用bag字段区分普通槽位和背包内部格子bag0是普通背包槽位bag物品实例ID表示这个格子在某个背包内部。这套设计让背包本身也是一个物品实例——放进背包槽位的是一个item_instance这个实例内部的格子由character_inventory里的bag字段指向这个实例的 ID。绑定规则灵魂绑定是怎么回事item_template里的bonding字段控制物品能否流通NO_BODY不绑定任何人都可以交易ON_PICKUP拾取时绑定捡起来就变成灵魂绑定ON_EQUIP装备时绑定穿上后变成灵魂绑定ON_USE使用时绑定QUEST ITEM任务物品不可丢弃、不可交易绑定信息在物品生成时写入item_instance.flags。一旦绑定服务器在交易时检查这个标志拒绝绑定物品的交易请求。还有一个边缘情况团队掉落被分配后 2 小时内可以交易——团队散了玩家可以把刚拿到的装备交易给队友。item_soulbound_trade_data表记录这个临时交易窗口的截止时间。物品外观displayid 的作用item_template.displayid是物品在客户端显示的模型 ID。不同的displayid对应不同的图标和 3D 模型。服务器只存一个 ID客户端负责渲染。有趣的是AzerothCore 通过修改displayid可以让同一个物品模板在不改变数值的情况下呈现完全不同的外观——外观和数值解耦开发者可以自由组合。这在自定义服务器里是常见的修改手段。回头看 AzerothCore 的物品系统有一条主线贯穿始终模板定义应该有什么属性实例记录这个具体的物品现在是什么状态。这两层分离让物品系统能够同时处理两种场景——全服统一的物品类型配置和每个玩家背包里独一份的物品实例。系列一到这里四个核心库全部聊完。模板模式、实例模式、条件系统、叠加层……这些反复出现的核心概念构成了 AzerothCore 数据设计的骨架。系列二会从代码层深入聊这些系统的具体实现。