纸片化学社区版 · 数据格式
本文档定义数据源(远程服务器)提供的数据格式。游戏运行时通过 DownloadManager 从 GameManager.data_origin(数据源根 URL)下载数据,并加载到 GameManager 的各字典中。
本文档由 AI 生成,对应数据后端 0.1.1 版本。
目录结构(数据源服务器端)
<data_origin>/
├── index.json # 数据源信息
├── card/list.json # 卡牌索引
├── card/id/{id} # 某张卡牌的详细定义(文本,JSON 格式)
├── reaction/list.json # 反应索引
├── reaction/id/{id} # 某条反应的详细定义
├── matter/list.json # 物质索引
├── matter/id/{id} # 某物质的详细定义
└── asset/list.json # 图片与音频资源索引
├── asset/pic/{id} # 图片文件
└── asset/sound/{id} # 音频文件
index.json
{
"name": "数据源名称",
"uuid": "c8f3b2a1-...(唯一标识,用于本地缓存目录名)"
}
list.json(三类通用结构)
card、reaction、matter 的 list.json 均为「id → 文件名」映射:
{
"card-h": "H",
"card-o": "O",
"card-ignite": "点燃·升温"
}
客户端下载后按文件名保存为 cards/H.json、cards/点燃·升温.json 等,load_resource() 会读取每个详细定义并以 id 为键存入对应字典。
asset/list.json
{
"pics": {
"pic-metal-fe": "fe.png"
},
"sounds": {
"sound-hit": "hit.ogg"
}
}
卡牌定义(card/*.json)
{
"id": "card-h",
"name": "H",
"name_en": "Hydrogen",
"type": "atom",
"category": "nonmetal",
"count": 4,
"pic": "pic-metal-fe",
"effects": ["IGNITE", "HEAT"]
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 是 | 卡牌唯一标识 |
name | string | 是 | 牌面名称(中文) |
name_en | string | 否 | 英文名称 |
type | string | 是 | atom 原子牌 / group 原子团牌 / condition 条件牌 / sequence 定序牌 / electron 电子层牌 / count 计数牌 |
category | string | 否 | metal 金属 / nonmetal 非金属 / group 原子团 |
count | int | 否 | 单局单种卡牌数量上限:整局游戏中该卡牌在「牌堆+手牌+反应区+元素区+弃牌堆」的总张数上限(即放入牌堆的张数),默认 4;设为 0 或负数表示本局不使用该卡牌 |
pic | string | 否 | 对应 asset/list.json 中 pics 的键 |
element | string | 否 | 元素符号(如 H、O、Fe),条件牌可省略 |
effects | string[] | 否 | 条件牌效果,见下方「条件效果枚举」 |
condition_effect | int | 否 | 条件牌主效果数值(与 effects[0] 等价,供 _get_condition_effect 读取) |
单局单种卡牌数量上限(count)
count 字段定义某张卡牌在一局游戏中的总张数上限。引擎在开局初始化牌堆时,每种卡牌恰好放入 count 张;此后所有操作(发牌、摸牌、调度、O2、结晶、提取、增益、攻击者/队友补牌等)只在不同区域间移动卡牌,总量守恒,因此任意时刻该卡牌在「牌堆+手牌+反应区+元素区+弃牌堆」中的总张数都不会超过 count。
- 默认值:
4。 count <= 0:该卡牌本局不进入牌堆(不参与游戏)。- 引擎提供
GameLoopManager.get_card_count_limit(card_id)(单种上限)与GameLoopManager.get_card_global_count(card_id)(当前整局总张数)查询接口;若数据异常导致某卡牌整局总张数超过上限,引擎会剔除该张并打印告警(见_draw_from_deck)。
条件效果枚举(effects 合法值)
| 值 | 对应 GameLoopManager.ConditionEffect | 说明 |
|---|---|---|
IGNITE | 0 | 点燃:作为反应条件或否决降温,默认自带氧气 |
HEAT | 1 | 升温:作为反应条件或否决降温 |
DISSOLVE | 2 | 溶解:自带水,使与水反应的物质发生反应 |
COOL | 3 | 降温:否决升温/点燃 |
FILTER | 4 | 过滤:除去自己反应区内固体类一般伤害物 |
COLLECT_GAS | 5 | 集气:除去自己反应区内所有气体 |
EXTRACT | 6 | 提取:取走他人区域中一种非生成物物质或元素 |
CRYSTALLIZE | 7 | 结晶:从弃牌堆取牌组成晶体加入手牌 |
物质定义(matter/*.json)
物质定义驱动「伤害自动分类」,是结算阶段的唯一数据依据。
{
"id": "matter-h2so4",
"formula": "H2SO4",
"composition": ["H", "H", "S", "O", "O", "O", "O"],
"state": "liquid",
"solubility": "soluble",
"categories": ["strong_acid", "corrosive"],
"damage_type": "CORROSION",
"corrosion_strength": "strong",
"is_illegal_attack": false,
"is_harmless_gas": false,
"is_generated_water": false,
"special": []
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 是 | 物质唯一标识 |
formula | string | 是 | 化学式(与 substance 的 formula 字段匹配) |
composition | string[] | 否 | 组成该物质的元素/原子团牌名列表(供 UI 组合提示) |
state | string | 否 | solid / liquid / gas(常温常压物态) |
solubility | string | 否 | soluble(可/易/微溶) / insoluble(难溶) |
categories | string[] | 是 | 分类标签,见下方「物质分类标签」 |
damage_type | string | 否 | 显式指定伤害类型:CORROSION / POISONING / GENERAL;省略则由 categories 自动推导 |
corrosion_strength | string | 否 | 腐蚀物强度:strong(强酸/强碱,结算扣 2n)/ weak(可溶性弱酸/弱碱,扣 n) |
is_illegal_attack | bool | 否 | 是否是非法进攻物质(金属碳化物、金属氢化物、金属氧化物、金属硅化物、固体单质、有机物、配合物、混盐等),不可直接进攻打出 |
is_harmless_gas | bool | 否 | 是否是无害气体(结算二后进入弃牌堆) |
is_generated_water | bool | 否 | 是否是生成的水(结算二后进入弃牌堆) |
special | string[] | 否 | 特殊物质标签:O2(可回复/摸牌)、H2(生成使攻击来源摸一张牌)等 |
物质分类标签(categories 合法值)
| 标签 | 推导出的伤害类型 | 结算规则 |
|---|---|---|
strong_acid | CORROSION | 强酸,结算阶段扣 2n 层电子 |
strong_base | CORROSION | 强碱,结算阶段扣 2n 层电子 |
weak_acid(可溶性弱酸) | CORROSION | 扣 n 层电子 |
weak_base(可溶性弱碱) | CORROSION | 扣 n 层电子 |
toxic_gas | POISONING | 毒气,扣 n 层电子 |
toxic_liquid | POISONING | 有毒纯液体,扣 n 层电子 |
cyanide | POISONING | 氰化物,扣 n 层电子 |
insoluble_salt_base | GENERAL | 难溶性酸碱盐,扣 n 层电子 |
complete_hydrolysis_solid | GENERAL | 广义完全水解固体,扣 n 层电子 |
solid_element | GENERAL | 固体单质,扣 n 层电子 |
solid_oxide | GENERAL | 固体氧化物,扣 n 层电子 |
分类重复规则:一个物质可同时属于多个分类(如 Zn(CN)₂ 既是 cyanide 又是 insoluble_salt_base),但伤害不叠加,按「最早的结算时机」结算:
GENERAL(结算阶段一)优先于POISONING/CORROSION(结算阶段二)POISONING优先于CORROSION
引擎在 _auto_classify_damage() 中按此优先级自动推导 damage_type;若定义中显式写了 damage_type,则以其为准。
已配平产物与无伤害物质:不包含上述任何 categories 的物质的 damage_type 为 null(非伤害物),可用于暗攻、反应中间体等。
反应定义(reaction/*.json)
反应定义驱动「自动反应引擎」。引擎在反应区内为每个玩家的物质自动匹配反应,遵循规则「反应区内能反应物质之间会立即发生反应」。
{
"id": "reaction-h2so4-naoh",
"reactants": ["matter-h2so4", "matter-naoh"],
"products": ["matter-na2so4", "matter-h2o"],
"conditions": [],
"priority": 0
}
{
"id": "reaction-mg-ignite",
"reactants": ["matter-mg", "matter-o2"],
"products": ["matter-mgo"],
"conditions": ["IGNITE"],
"priority": 1
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 是 | 反应唯一标识 |
reactants | string[] | 是 | 反应物 matter id 数组;引擎在反应区内按顺序各匹配一个 |
products | string[] | 是 | 生成物 matter id 数组;全新 substance 会写入反应区(进攻)或直接弃置(防御) |
conditions | string[] | 否 | 必需的条件效果(IGNITE / HEAT / DISSOLVE 等);需反应区中有物质携带对应 condition_effects 才可触发 |
priority | int | 否 | 匹配优先级,数值大者优先匹配,默认 0 |
反应语义
- 进攻 / 辅助 / 暗攻 / 补伤触发:反应物被消耗(其卡片组合进生成物),生成物留在反应区,参与伤害结算;自动完成伤害分类。
- 防御触发:反应物被消耗,生成物直接进入弃牌堆,视为防御成功。
- 条件消耗:反应要求
conditions时,参与反应的条件效果视为被该反应消耗,条件牌随反应物一并进入弃牌堆。 - 递归触发:生成物可能继续与反应区其他物质反应,引擎会反复匹配直到无反应可发生(最多 32 轮,防止死循环)。
- 产物的
source_player_id:取参与反应物中timestamp最大者(即「最后补全的人」),保证伤害来源正确。
客户端加载结果(GameManager 字典)
DownloadManager.load_resource() 加载后:
| 字典 | 结构 |
|---|---|
GameManager.card_list | { "card-h": { ...卡牌定义... }, ... } |
GameManager.matter_list | { "matter-h2so4": { ...物质定义... }, ... } |
GameManager.reaction_list | { "reaction-h2so4-naoh": { ...反应定义... }, ... } |
GameManager.pic_list | { "pic-metal-fe": "fe.png", ... } |
GameManager.sound_list | { "sound-hit": "hit.ogg", ... } |
兼容性:若某个详细定义文件不存在(旧版数据源),对应键保留 list.json 中的原始文件名字符串,游戏逻辑可通过
is Dictionary判断。
物质实例(substance_data)字段约定
引擎在 create_substance_data() 基础上补充/修正以下字段,供 UI 与结算读取:
| 字段 | 类型 | 说明 |
|---|---|---|
matter_id | string | 关联的物质定义 id(由 _auto_classify_damage() 按 formula 匹配填充) |
damage_type | int | 伤害类型(GameLoopManager.DamageType),由物质分类自动推导 |
is_strong_acid_base | bool | 强酸碱标记(影响腐蚀结算扣 2n) |
is_harmful | bool | 是否为伤害性物质(damage_type != null 且非生成水/无害气体) |
is_illegal_attack | bool | 非法进攻标记(不可直接进攻打出) |
is_gas / is_harmless_gas | bool | 气体 / 无害气体标记(集气、结算二清除用) |
is_generated_water | bool | 生成的水标记(结算二清除用) |
is_product | bool | 是否为反应生成物(提取/结晶限制用) |
is_dark_attack | bool | 是否暗攻产物 |
source_player_id | int | 伤害来源玩家 |
timestamp | int | 打出时间戳(后置先发结算顺序用) |
condition_card_ids | string[] | 附加条件牌 id |
condition_effects | int[] | 附加条件效果(ConditionEffect 枚举值) |