跳轉到

材質表

本檔角色:全 31 種材質的權威 source of truth。 程式端執行 source of truth:src/material-params/materials.ts(必須與本檔一致;PR review 強制同步)。

1. 欄位定義

欄位 單位 / 型別 說明
name 中文名 UI 顯示名稱
id string 程式識別符(snake_case)
desc string 玩法定位 / 用途
forbidden_scopes vehicle / environment 禁止用於哪類 GLB;空白 = 任意
allowed_part_types chassis / body / tire / motor / battery / roller / chip / weapon 白名單例外(在 forbidden_scopes 內仍允許)
density g/cm³ 密度
yield_strength MPa | null 屈服強度(材料強度數值,與「能否破壞」無關,破壞由建模決定,見 §10)
ultimate_strength MPa | null 極限強度(同上)
friction 0–3 摩擦係數
restitution 0–1 彈性係數
thermal_conductivity W/(m·K) | null 熱導;null = 不參與熱傳合成
specific_heat J/(kg·K) | null 比熱;null = 同上
thermal_limit °C | null 過熱閾值(材料軟化/熔點溫度數值,與「能否熱壞」無關,由建模決定,見 §10);null = 該材質未定義有意義的熔點(地表抽象材質、fluid sensor mode)
magnetism_role enum:passive / source / none 磁性身分(三選一,型別系統強制互斥)。passive = 被動鐵磁、source = 主動磁源身分、none = 無磁性(多數材質)。詳見 §8
magnetic_susceptibility 0–1 | null 被動鐵磁強度(材料固有屬性、電子組態決定的磁化率);僅 magnetism_role: passive 時有值,其他 role 為 null(markdown 表記 —)。主動磁源強度由建模層 Root Extras magnet_source_strength_n 決定(見 §8.2)
rolling_resistance 基準 1.0 車輛行駛該地面的滾動阻力(所有材質必填,作為 fallback 防護避免疏忽放錯位置造成 runtime 運算問題)
is_fluid bool 觸發 sensor mode + deploy_behavior
deploy_behavior enum 5 種:grip_loss / sticky / freeze / burn / corrosive
deploy_params object deploy_behavior 對應參數
display_order { vehicle?: number, environment?: number } 可選;UI 排序覆蓋值(小到大),無設則用 §2 表格 array index

命名分層:

  • 程式(materials.ts):以 id 為唯一識別符;不存 name / desc
  • 本檔規格:id + name(繁體中文)並存,做為設計討論與 PR 同步基準
  • UI 顯示:i18n bundle 對 id 取 name + desc 的繁中 / 英文 / 其他語言;UI 不直接讀本檔 name / desc
  • i18n 鍵契約:每個 canonical id 必須在所有支援語系提供 materials.<id>.name 與 materials.<id>.description;完整性測試以 materials.ts 清單逐一驗證,禁止只有部分語系或部分材質有值
  • 共用顯示格式:編輯器主材質、子網格覆寫、場地 entity 與含合法 {material} 參數的驗證訊息,統一顯示 <本地化名稱> (<canonical id>) — <本地化用途>;表單實際值及 canonical 資料仍只使用 id。未知 id 不猜測翻譯,驗證訊息保留原值以利診斷

1.1 MaterialDef TypeScript Interface

src/material-params/materials.ts 對應型別:

type MaterialId = string;
type PartType =
  | "chassis"
  | "body"
  | "tire"
  | "motor"
  | "battery"
  | "roller"
  | "chip"
  | "weapon";

interface MaterialDef {
  id: MaterialId;

  // === 物理欄位 ===
  density: number; // g/cm³
  yield_strength: number | null; // MPa
  ultimate_strength: number | null; // MPa
  friction: number; // 0-3
  restitution: number; // 0-1
  thermal_conductivity: number | null; // W/(m·K)
  specific_heat: number | null; // J/(kg·K)
  thermal_limit: number | null; // °C
  rolling_resistance: number; // 基準 1.0,所有材質必填(fallback 防護)

  // === 磁性身分(三選一,型別系統強制互斥;磁源強度由 Root Extras magnet_source_strength_n 決定,見 §8)===
  magnetism_role: "passive" | "source" | "none";
  magnetic_susceptibility: number | null; // 0-1,僅 role='passive' 有值;其他 role 為 null

  // === Fluid 特性(runtime 行為標識,不參與檢核)===
  is_fluid?: boolean;
  deploy_behavior?: "grip_loss" | "sticky" | "freeze" | "burn" | "corrosive";
  deploy_params?: Record<string, number>;

  // === 硬規則(Stage 1 剃除違規指派 / Stage 3 拒收殘留,見 §4)===
  forbidden_scopes?: ReadonlyArray<"vehicle" | "environment">;
  allowed_part_types?: ReadonlyArray<PartType>;

  // === UI 排序(軟提示,optional)===
  display_order?: { vehicle?: number; environment?: number };
}

型別 & load-time 強制:

  • magnetism_role: 'passive' ↔ magnetic_susceptibility: number(必有值,0–1)
  • magnetism_role: 'source' \| 'none' ↔ magnetic_susceptibility: null(必為 null)
  • materials.ts 載入時雙向 assert 上述不變式,違反即 throw(避免 malformed 資料靜默通過)
  • 公式端依 role === 'passive' narrow 後使用 susceptibility;其他 role 直接 force = 0,不觸碰 null 欄位

分類辨識:

  • forbidden_scopes 為空 → vehicle-friendly(14 種,可用於零件與場地)
  • forbidden_scopes = ['vehicle'] 且 is_fluid = false → environment-only(12 種,地表 + 場地特殊材質如 magnet_floor)
  • forbidden_scopes = ['vehicle'] 且 is_fluid = true → fluid(5 種,僅 weapon + 場地可用)

1.2 Gameplay capability 契約

材質欄位只有在正式 runtime 存在明確 consumer 時,才可宣稱具備對應 gameplay capability。資料列有值不等於該值在所有 scope、body 或接觸型態都會生效;文件、UI 與平衡討論不得把 fallback/分類資料描述成已接線玩法。

欄位/欄位族 已接線 capability 與適用邊界
density 由實際水密 sub-mesh 體積合成質量/慣性;所有合法 vehicle region 都適用,fluid weapon payload 也按其實際幾何計入質量。這不代表存在浮力或 3D 流體密度模擬。
friction、restitution 只供 solid collider 接觸;fluid sub-mesh 是 sensor,不建立實體碰撞回應,因此其數值僅是資料完整性的 fallback。
rolling_resistance tire/roller 與 solid surface 的實際接觸耗散;fluid sensor 不套用。
thermal_conductivity、specific_heat vehicle part 合成 heat capacity/ambient conductance;tire 與 solid surface 接觸時,以雙方 baked exchange factor 與實際 contact area 做熱交換。地表/entity 溫度是由天氣/場景決定的固定熱庫,不建立會被車輛加熱或冷卻的動態地面熱場。任一必要熱欄為 null 時該路徑不啟用。
thermal_limit 只為可破壞 vehicle part 烘焙 thermalLimitC;null 表示無有意義閾值。Track Entity/地表是固定熱庫而非動態溫度實體,fluid sensor 也不執行過熱。
magnetism_role、magnetic_susceptibility passive 才會被磁源依 susceptibility 施力;source 只建立磁源身分,強度仍由 authored magnet_source_strength_n 提供;none 不參與。
is_fluid、deploy_behavior、deploy_params 建立 sensor 與 grip-loss/sticky/freeze/burn/corrosive 觸發效果;不提供體積流場、浮力、黏度求解或一般流體阻力。sticky 的速度衰減是明示 gameplay effect,不等同 3D viscosity。
yield_strength、ultimate_strength 只在現行 fatigue/衝擊/腐蝕/輪胎 wear capacity 公式明確取用時生效;數值本身不使物件可破壞,仍服從 §10。

若未來要讓目前無 consumer 的值產生新玩法,必須在同一變更中補 runtime 實作、決定性/有限值測試與本表契約,不能只改材質參數後宣稱生效。反之,只要 UGC 通過 schema、介面與資源規則,極端但合法的質量、尺寸與材質組合之數值穩定性屬 runtime 責任:以固定步長、有限值 guard、clamp/budget 與決定性退化處理,不另用公版外形比例限制封堵。

2. 31 種材質完整表

— = 無此欄位 / 不適用;null = 數學上不參與計算(不可破壞 / 不參與熱傳)。

name id desc forbidden allowed_parts density yield_strength ultimate_strength friction restitution thermal_conductivity specific_heat thermal_limit magnetism_role magnetic_susceptibility rolling_resistance is_fluid deploy_behavior deploy_params
ABS 塑膠 abs 輕、便宜、易碎;熱絕緣;不耐熱 — — 1.05 40 50 0.40 0.40 0.17 1300 80 none — 0.95 false — —
聚碳酸酯 pc 韌性塑膠、平衡;中等耐熱 — — 1.20 60 70 0.42 0.50 0.20 1170 130 none — 0.95 false — —
聚乙烯 pe 滑、輕、低摩擦適合 roller — — 0.95 25 30 0.05 0.45 0.42 2300 100 none — 0.85 false — —
木材 wood 極輕、易破、復古主題;熱絕緣 — — 0.70 30 50 0.55 0.30 0.15 1700 200 none — 1.0 false — —
碳纖維複合 carbon 輕、強、對剪切力弱;高溫穩定 — — 1.55 500 600 0.45 0.30 7 850 1000 none — 0.9 false — —
玻璃纖維 glass_fiber 中等強度複合、便宜替代碳纖 — — 2.00 200 400 0.50 0.25 0.40 800 800 none — 0.9 false — —
矽膠 silicone 比 rubber 更軟、更耐熱 — — 1.05 4 20 0.95 0.75 0.20 1300 200 none — 1.1 false — —
橡膠 rubber 柔軟吸震、超彈跳、衝擊不破 — — 1.10 5 25 1.20 0.85 0.16 1500 150 none — 1.2 false — —
陶瓷 ceramic 硬但脆、易碎裂;頂級耐熱 — — 3.50 100 200 0.65 0.10 30 900 1500 none — 0.85 false — —
鎂合金 magnesium 超輕量金屬(比 aluminum 更輕且更強;易過熱) — — 1.80 130 220 0.50 0.20 156 1023 350 none — 0.9 false — —
鋁 aluminum 中重、易凹但難穿;散熱佳 — — 2.70 90 120 0.50 0.20 237 900 400 none — 0.9 false — —
鈦 titanium 最強、強度重量比最佳;散熱差(磁吸免疫=全非鋼材質預設,見 §8) — — 4.50 750 880 0.55 0.18 22 522 1000 none — 0.9 false — —
銅 copper 高密度、超佳散熱 — — 8.00 70 220 0.45 0.10 401 385 500 none — 0.85 false — —
鋼 steel 重、抗衝擊、可被磁吸 — — 7.85 250 400 0.70 0.15 50 460 800 passive 1.0 0.95 false — —
柏油 asphalt 基準柏油路 vehicle — 2.4 4 6 0.85 0.20 0.75 920 null none — 1.0 false — —
水泥 concrete 水泥地 vehicle — 2.4 25 35 0.75 0.15 1.4 880 null none — 1.0 false — —
泥地 dirt 軟質土地(強度極低,數學上跳過 fatigue) vehicle — 1.5 null null 0.70 0.05 0.50 800 null none — 1.3 false — —
草地 grass 草地(強度極低,數學上跳過 fatigue) vehicle — 0.4 null null 0.65 0.10 0.10 1500 null none — 1.2 false — —
碎石 gravel 碎石地(強度極低,數學上跳過 fatigue) vehicle — 1.8 null null 0.70 0.10 0.30 800 null none — 1.4 false — —
沙地 sand 沙地(強度極低,數學上跳過 fatigue) vehicle — 1.6 null null 0.60 0.05 0.30 830 null none — 1.6 false — —
泥沼 mud 陷得深 vehicle — 1.7 null null 0.55 0.05 0.60 1500 null none — 1.6 false — —
積雪 snow 壓雪重 vehicle — 0.3 null null 0.30 0.10 0.10 2090 null none — 1.8 false — —
冰面 ice_sheet 光滑、低摩擦 vehicle — 0.92 null null 0.10 0.50 2.2 2100 null none — 0.8 false — —
青苔 moss 溼滑 vehicle — 0.5 null null 0.40 0.10 0.10 1500 null none — 1.3 false — —
水面 water_surface hydroplaning vehicle — 1.0 null null 0.30 0.00 0.60 4180 null none — 1.5 false — —
磁鐵地板 magnet_floor 純主動磁源材質身分;強度由建模物件 Root Extras 宣告,未宣告 = 0(等於未磁化的鐵磁地板);N 極 = sub-mesh 面積加權平均法向(§8.3) vehicle — 7.85 250 400 0.70 0.15 50 460 null source — 1.0 false — —
水 water 路面打滑 vehicle weapon 1.0 null null 0.10 0.10 null null null none — 1.0 true grip_loss { grip_modifier: 0.5 }
油 oil 打滑 + 拖慢 vehicle weapon 0.9 null null 0.05 0.05 null null null none — 1.0 true sticky { grip_modifier: 0.3, velocity_decay_per_sec: 0.7 }
結凍液 freezing_fluid 凍冷 vehicle weapon 0.8 null null 0.05 0.05 null null null none — 1.0 true freeze { temperature_delta_per_sec: -20 }
熔岩 lava 加熱 vehicle weapon 2.5 null null 0.20 0.10 null null null none — 1.0 true burn { temperature_delta_per_sec: 30 }
酸液 acid 腐蝕(走耐受度因子族) vehicle weapon 1.2 null null 0.05 0.05 null null null none — 1.0 true corrosive {}(fatigue 由耐受度公式決定)

注 1:fluid sub-mesh 為 sensor(§6 規則 1)→ friction / restitution 不參與碰撞反應(僅作玩家硬塞非 weapon 部位的 fallback 防護);正常 deploy 行為由 deploy_behavior + deploy_params 驅動。唯 density 例外:仍計入 mass_g(§7 幾何質量恆對所有 sub-mesh 求和,含合法的 weapon fluid sub-mesh,如熔岩刃塗層)。

注 2:所有 31 種材質皆設 rolling_resistance。hinge tire/roller 與 solid surface 的實際 contact 以 tire × surface 成對套用;Vehicle 14 種與 fluid 5 種的值是該材質若合法成為 solid 接觸面的初估值,待 playtest 校準(基準 asphalt = 1.0)。fluid sensor 不套滾阻。

注 3:可破壞性由建模決定,不由材質的 yield/ultimate 決定(見 §10)。例如 asphalt yield=4 不代表 asphalt 地面可被擊破 — 它是 Fixed body 不標 destructible,仍不可破壞。

注 4:磁性身分由 magnetism_role enum 三選一強制互斥(見 §8)。magnet_floor 為純主動磁源身分(role: source),強度由建模物件 Root Extras magnet_source_strength_n 決定;steel 為純被動鐵磁(role: passive, magnetic_susceptibility: 1.0);其他材質皆 role: none。

注 5:magnet_floor 的物理欄位(density / yield / ultimate / friction / restitution / thermal_conductivity / specific_heat)目前鏡像 steel(= 磁化鋼地板);thermal_limit 不在鏡像之列——magnet_floor 屬環境材質、依環境慣例 thermal_limit = null(非鏡像 steel 的 800)。兩者為獨立材質:可保持一致、亦可各自調整;改 steel 物理時不會自動同步 magnet_floor,依需要決定是否一併調。

注 6:環境材質(12 種)的 thermal_conductivity / specific_heat 已接入 tire/roller 對 solid surface 的固定熱庫接觸:先烘焙量化 sqrt(k×density×specific_heat),再與輪組 factor、接觸面積及實際 normal impulse 合成熱導。entity 本身仍不模擬有限熱容量,地表熱庫溫度取 weather.temperature(算式表.md §6.5)。

3. Deploy Behavior 對接

Behavior 中文 機制
grip_loss 打滑 經過時 grip × grip_modifier,由輪胎/roller 與地表的接觸牽引求解
sticky 黏滯 grip × grip_modifier(同上)+ 每幀 velocity ×= 1 − (1 − velocity_decay_per_sec) × dt(每秒保留率之線性化;decay^dt 的一階近似——runtime pow 屬超越函數、禁入共識路徑)
freeze 凍冷 temperature_delta_per_sec × part.heatCapacityJPerC 轉為負 W 進單一熱 ledger;不受 passive thermal resist 折抵
burn 灼熱 temperature_delta_per_sec × part.heatCapacityJPerC 轉為正 W 進單一熱 ledger;受 passive thermal resist 折抵
corrosive 腐蝕 接觸 sub-mesh 每秒 fatigue += K_ACID / sub_mat.ultimate × dt(耐受度因子族)

4. 檢核邏輯

材質在 vehicle 場景使用(零件 GLB):
  if 'vehicle' in material.forbidden_scopes:
    if material.allowed_part_types contains 該零件類型:
      ✅ 通過(白名單例外)
    else:
      ❌ 違規(處置見下)

材質在 environment 場景使用(場地 GLB):
  if 'environment' in material.forbidden_scopes:
    ❌ 違規(處置見下)
  else:
    ✅ 通過

違規處置(三階段分工):Stage 1 自動剃除違規材質指派(變未指派、不拒收上傳)→ Stage 2 編輯器過濾不可選 + 玩家重新指派 → Stage 3 嚴格拒收殘留違規(UGC機制.md §2.2 / §4.2、UGC上傳.md §3)。

is_fluid 不參與檢核,純為 runtime 行為標識。

5. UI 排序規則

各編輯器(vehicle / environment / 各零件類型)顯示材質清單:

  1. 過濾:根據檢核邏輯排除不允許的材質
  2. 排序(共識安全 + 可選覆蓋):
  3. 預設:用 §2 表格 array index(固定,跨 peer / 跨語系一致)
  4. 覆蓋:若材質設了 display_order.<scope> → 用該值(小到大)
  5. 不採用 locale-aware 排序:i18n 名稱排序會造成 peer 與語系間順序不一致,禁用
  6. 不提供「顯示全部」開關(避免誤用不適合的材質)
  7. UI 額外功能(不影響 spec canonical 順序):
  8. 編輯器可加「搜尋 / 過濾 / 依屬性排序」view 功能(如依 mass 排序)
  9. 這些是純客戶端 view,不影響任何 ledger / 共識邏輯

6. Runtime 規則

規則 1:fluid sub-mesh 為 sensor mode

  • 視覺 mesh 保留(玩家自選 texture / shader)
  • 不施力、不參與 rigid body 碰撞
  • 接觸偵測仍存在(用於觸發 deploy_behavior)

規則 2:零件全 fluid fallback

若某顆零件 part 所有 sub-mesh 都 is_fluid: true:

  • 該 part 從遊戲開始 broken = true
  • 立即套用部件破損規則(見 零件與場景.md)
  • 散開的 fluid 落到地面成 deploy_zone

此規則為 runtime safety net。上傳檢核已擋下大部分情況;本規則處理 regulation 漏接或規則變更的 edge case。

規則 3:場地 fluid 永遠 active

場地 GLB 內 is_fluid: true sub-mesh:永遠 sensor mode + deploy_behavior active,不需 broken 條件。

規則 4:「水包塑膠」邊界 — 編輯器警告

Stage 2 對 part 的 6 個 cardinal 方向(±X / ±Y / ±Z)做投影檢查:若 ≥ 1 個方向上 fluid sub-mesh 是最外層(該方向上 sub-mesh 的最大座標等於 part AABB 對應面,誤差 < 0.5mm)→ 顯示警告:

「外層 fluid 包覆 rigid body collider — 其他玩家會穿透 fluid 層直接撞到內部 collider。視覺上像水但物理上不會擋人。確定要這樣設計嗎?」

玩家確認後上傳,後果自負(規則 1 + 規則 2 仍生效)。

7. 多材質零件的物理合成

物理量 合成方式
mass_g Σ(sub_volume × sub_material.density)
stress / fatigue 由碰撞 collider handle 取接觸 sub-mesh 的 yield / ultimate;車輛與 destructible Track Entity 均不得退回主材質
摩擦 / restitution 接觸點所在 sub-mesh 對應值
鐵磁吸力 對每 canonical sub-mesh 施力 ∝ 磁源 strength_n × sub.magnetic_susceptibility(僅 role: passive 的 sub-mesh 受力;方向取實際 collider 世界中心,總 impulse 施於剛體 COM、不產生 torque;磁源不限武器,場地磁源同理)
thermal_conductivity / specific_heat Pre-bake 直接算 heatCapacityJPerC=Σ(massKg×specific_heat)、依 exposed area 與 capped conductivity factor 算 ambientConductanceWPerC,並為每個 proxy 烘焙量化 thermal exchange factor,不合成平均值。Runtime 只用 current PhysicsManifest typed 值。
thermal_limit Pre-bake:取 weakest non-null sub-mesh(忽略 null;若全 null 則整體 null)→ Canonical PhysicsManifest.geometry.thermalLimitC。Runtime 只比較 hydrate 的 part.thermalLimitC 與 part.temperature,不讀 extras、不做 sub-mesh 級別重算。是否觸發 broken 由建模決定(見 §10)
watertight 每 sub-mesh 各自水密;整顆體積 = Σ sub-mesh 水密體積
摩擦 / restitution(inter-body) 上列係數屬實際接觸 collider 的材質。一般 collider 的 friction、restitution 由 Rapier CoefficientCombineRule::Average 合成;tire/roller friction 採 Average、restitution 固定採 Min。UGC 不得覆寫 combine rule,但逐 collider 材質係數必須保留。規則見 D-20260811-04。

8. 磁性系統 — 三選一身分

詳細公式見 算式表.md §5。本檔列出設計原則。

8.1 三種磁性身分(材質層 — enum 強制互斥)

magnetism_role 三選一(型別系統保證單一身分,無需額外 schema 檢核):

身分 magnetism_role magnetic_susceptibility 物理意義 範例
主動磁源 source —(不適用) 有 N/S 極身分;強度由建模物件決定 magnet_floor
被動鐵磁 passive 0–1(材料固有磁化率) 無極性方向、會被磁源吸/斥;強度為材料固有屬性 steel
無磁性 none —(不適用) 不參與磁力 多數材質

8.2 磁源強度來源(強度層 — 分離設計)

材質型磁源(場地物件 / 部件)「成為磁鐵」的條件:sub-mesh 材質 magnetism_role: source 且 物件 Root Extras magnet_source_strength_n > 0,兩者缺一即無磁源效果。武器 magnet 為分支型例外(動態強度、不依賴材質 role,見下表第一列)。

磁源類型 strength_n 來源
武器 magnet 分支 動態 = available_output_w × allocation_pct / 100 × K_MAGNET_FORCE(SOC 降額後的可供功率比例;持續場強、去 dt,算式表.md §5.1);不依賴材質 role
場地物件磁源(任意 entity) 靜態 = Root Extras magnet_source_strength_n(玩家建模時宣告,0–10 N,MAGNET_SOURCE_STRENGTH_N_MAX,protocol.md §3)+ sub-mesh 材質 magnetism_role: source
車輛部件磁源(fallback 防護) 正常情境不會發生 — magnet_floor 為 vehicle forbidden、目前無 vehicle-friendly source 材質,車輛部件無可用 source 材質。此 row 為防呆備援:若異常出現 source sub-mesh + Root Extras magnet_source_strength_n(如未來新增 vehicle-friendly source 材質、或 schema 漏網),runtime 仍照規則計算避免崩潰

設計理由:磁源強度依賴特定物件的磁化處理 / 線圈電流 / 永磁加工,不是材料本身屬性 → 移到建模層;被動鐵磁強度是材料固有屬性(磁化率)→ 留在材質層(magnetic_susceptibility)。

8.3 N 極方向統一規則

依磁源類型自動推導(無獨立 n_pole_direction schema 欄位):

  • 武器 magnet:Axis empty +Z
  • 場地物件 / 部件磁源:sub-mesh 面積加權平均法向(pre-bake 寫入 extras;每 sub-mesh 各自一向量;退化〔近球對稱、平均趨零〕→ fallback node +Z)——磁源 ↔ 磁源內積需每源單一向量(算式表.md §5.3)

8.4 互動算式(算式表.md §5)

互動 用到的欄位 結果
磁源 → 鐵磁 source.strength_n × target.magnetic_susceptibility × 1/r² 純吸引
磁源 ↔ 磁源 a.strength_n × b.strength_n × N 極夾角 × 1/r² 同極斥、異極吸
鐵磁 ↔ 鐵磁 (無互動) 無力

算式不涉及 polarity 開關;吸/斥純由 N 極方向夾角決定。

9. 耐受度因子族(fatigue / acid / wear 統一公式)

所有持續性損耗共用接觸 sub-mesh 的 ultimate_strength 耐受度因子,不為每種來源另加 acid_resistance/wear_factor。衝撞、acid、輪胎 rolling/slip、熱加權、zone 去重與門檻公式只由 算式表.md §7–9 定義;產品層破壞語意見 遊戲機制.md §4。

10. 可破壞性 — 由建模決定,不由材質決定

⚠️ 核心原則:材質的 yield_strength / ultimate_strength / thermal_limit 是材料強度與閾值數值,與「能否破壞 / 能否熱壞」無關。能否破壞由建模屬性決定。 即使 fluid 材質因疏忽被設定在不可破壞的建模上,仍維持不可破壞(建模優先於材質)。

10.1 可破壞性決策表(涵蓋衝撞 + 過熱兩條路徑)

建模條件 是否可破壞 runtime 動作
Dynamic body(vehicle parts) ✅ 可破壞 用材質 ultimate_strength 算 fatigue;用 manifest geometry.thermalLimitC hydrate 的 part.thermalLimitC(§7)判過熱
Fixed/Kinematic body + destructible: true + physics: "default" ✅ 可破壞 用材質 ultimate_strength 算 fatigue;達閾值時停用 intact body/colliders/完整 visual,依版本化 descriptor 重建純視覺碎片(entity 無溫度模擬、過熱路徑僅車輛部件,場地.md §9.3)
場景 entity 未標 destructible(Fixed/Kinematic 皆同) ❌ 不可破壞 跳過 fatigue(與材質 ultimate_strength / thermal_limit 值無關;entity 不執行溫度模擬,車輛部件恆可破壞、不適用此列)
場景 entity + physics: "visual_only" ❌ 不可破壞 無 collider,不參與物理(僅場景 entity 適用,車內部件不會出現此設定);即使誤標 destructible: true 仍不可破壞——visual_only 優先(無 collider 無從受力)
sub-mesh is_fluid: true ❌ 不可破壞 sensor mode,不施力、不參與碰撞、不參與熱傳合成

10.2 Runtime 跳過條件(完整 skip 清單)

下列為 runtime 實際跳過計算的完整條件(前 2 列 = §10.1 決策派生、後 2 列 = 純數學 ÷0 / null 保護):

例外 判定 跳過項目 理由
場景 entity 未標 destructible(不論 body type) destructible !== true(Fixed/Kinematic 皆同) fatigue entity 需 destructible: true 才可破壞,未標即跳過(含會動的 kinematic 平台);entity 本來就不執行過熱檢查,車輛部件不適用(恆可破壞)
sub-mesh 是 fluid is_fluid: true fatigue + 過熱合成 sensor mode,不施力、不參與熱傳
sub-mesh ultimate_strength 為 null 或 0 數學退化保護 fatigue 避免 ÷0
part.thermalLimitC 為 null manifest pre-bake 結果(所有 sub-mesh thermal_limit 皆 null) 過熱檢查 該 part 無有意義的熔點

10.3 三種破壞機制分工

場景 機制 觸發條件
車內部件破壞 fatigue 累積式 + 一擊重傷 Dynamic body parts;stress / ultimate 累積
場地物件破壞 destructible entity + fatigue destructible: true + physics: "default";fatigue 達 1.0 或一擊重傷時停用 intact 物理/visual,依 descriptor 顯示純視覺碎片,不建立 fragment body/collider
Fluid 部署效果 deploy_behavior(非 fatigue) sensor mode 觸發 zone;走 grip_loss / freeze / corrosive 等

10.4 規則 2 全 fluid part fallback(機制見 §6 規則 2)

全 fluid part(所有 sub-mesh is_fluid: true)→ broken = true + 部件破損規則,機制定義見 §6 規則 2、不在此重列。

置於本節(可破壞性)的意義:這是 runtime safety net、不是「fluid 材質可破壞」的證明 —— fluid 本身仍 sensor mode(不參與碰撞);fallback 只處理「玩家疏忽放錯位置」的 edge case。

11. 材質變更與廢止流程

11.1 變更場景與升版規則

詳細升版分類見 版本規範.md §3;本表為材質專屬流程。

場景 流程 client_version builtin_assets_version derive_logic_version
新增材質 1. spec §2 加 row(含 name + id + 物理欄位 + 可選 display_order)
2. materials.ts 加 const
3. PR review 確認 spec ↔ const 一致
major(觸 src/material-params/ path-based、版本規範.md §4;既有 GLB 不受影響,但 builtin/derive +1 擋配對 → 舊 client 須升) +1 +1
改物理數值(如 yield_strength / thermal_limit) 1. spec §2 改值
2. materials.ts 改 const
3. PR review 比對
major(破壞 deterministic) +1 +1
改 desc / name spec §2 改文字(const 不動,i18n bundle 視需要更新) patch(純文檔) 不動 不動
改 id(rename) 禁止直接 rename — 破壞已上鏈 GLB 引用;改走「新增新 id + 廢止舊 id」雙步(舊 id const 永久保留) 新增 major + 廢止 minor 新增 +1 / 廢止不動 新增 +1 / 廢止不動
廢止材質(永不物理刪除) 1. 將 id 加入驗證層 DEPRECATED_MATERIAL_IDS 清單(client 隨附、登記於 protocol.md §3;非 protocol、刻意置於 src/material-params/ 等 path-based major 路徑之外〔版本規範.md §4〕、不觸發雙 bump;materials.ts const 一字不動)
2. 效果:Stage 2 編輯器不可選、Stage 3 拒收新上鏈使用;已上鏈舊資產(UGC + 公版)照常載入與比賽 = 絕版品(§11.3)
3. 不走治理、不強制更新公版:公版若仍用該材質亦變絕版品、照常可玩;要清理公版另走一次獨立公版變更(非廢止前置)
minor(const 值不動、determinism 不破、不擋配對;僅新上鏈驗證規則變更) 不動 不動

鐵則:材質 id 一旦發布即 immutable,且材質清單 append-only——GLB 用 id 引用材質、引用內嵌於 CID 鎖死的內容,無從替既有資產「換材質」(B 軸資產遷移機制不適用於材質);「確認全網無已上鏈使用」於 permissionless P2P 亦不可驗證。新增便宜、廢止可行、物理刪除與 rename 不存在。

11.2 通用原則

  • 不走治理層 ConfigUpdateEvent:物理性質是規則不是 config;治理只能改 economy_config_version(鑄幣 / 經濟參數),不能改物理常數。材質廢止亦不走治理——它是 client 發版的上傳驗證規則變更(操作流程見 流程/升版.md §8),非鏈上 config
  • 任何 materials.ts 變動自動觸發 版本規範.md §13 CI 不變式:src/material-params/ 路徑變更 → builtin_assets_version + derive_logic_version 雙 bump(版本規範.md §4 path-based);廢止標記不在此路徑(驗證層 DEPRECATED_MATERIAL_IDS,見 §11.1)、path-based 規則零例外
  • PR review 必須檢查 spec ↔ const 物理欄位一致(name / desc 為純文檔欄位不存於 const,i18n bundle 另行維護;CI 可加 schema 比對)
  • 任何已上鏈 GLB 的 materials[].id 引用必須能在 materials.ts 找到對應 const(append-only 鐵則下恆成立);Stage 3 拒收引用不存在 id 的新上鏈;runtime 載入時缺 id = 資料異常 → 拒絕載入該資產(fail-fast 純防呆、不靜默 fallback,比照 零件與共用介面.md §2 loader 無 marker 拒載入慣例)

11.3 絕版品行為(廢止材質的舊資產)

廢止只擋新上鏈,不動已存在的資產。已上鏈、引用了廢止材質的 UGC 與公版資產一律 絕版品:

  • 永久可玩:const append-only 保留 → 物理數值與廢止前完全相同;絕版品永不變 unusable(與 B 軸 schema 棄用 → unusable 生命週期不同,版本規範.md §17)。
  • 決定性安全:廢止不碰物理 const,全場 8 人對同一顆 GLB 算出相同結果。
  • 配對安全:廢止不 bump builtin_assets_version(僅 client minor)→ checkCompatibility 六欄位仍相等 → 已更新與未更新的 client 仍可同房;兩邊共用同一份 const、物理一致,差別僅在下述提示(純 UI、各 client 用自有清單判斷、不需 pin 帳本檢查點)。

為何是 client minor 而非 protocol-major:DEPRECATED_MATERIAL_IDS 是僅作用於上傳時(Stage 2/3)的驗證清單、零賽中足跡。TEXT_BLACKLIST 的 DMCA pre-check 與可選聊天 starter list 也都是 minor 級本機清單資料,不進房間協商或賽中共識(protocol.md §4)。上傳時清單跨 peer 不一致無共識風險,故不擋配對。

房內提示(絕版材質揭露):開賽前若場內任一玩家零件或場地含廢止材質,房間等待頁顯示軟提示說明其存在(流程/配對.md §9);續留房 = 默認認同該場公平性(沿用「開賽前退出無懲罰」同意機制,版本規範.md §21)。提示不逐一點名材質 / 理由(避免 i18n 隨時間膨脹);廢止理由集中於 資產政策.md §2(隨廢止 PR 同步登記)。此提示性質是平衡揭露(材質物理沒變),與 §21 兩種「降版本 / schema 差異」提示正交。

fork 絕版品:fork = 新上鏈 → 撞 Stage 3「拒收廢止材質」→ 必須先在 Stage 2 換掉該材質才能上鏈(把生態推離問題材質)。

可逆(廢止 → 復用):社群若共識某廢止材質可回歸,從 DEPRECATED_MATERIAL_IDS 移除即復用(對稱 client minor)。因 const 從未刪除,復用零遷移、零風險。復用決策機制(如投票)不屬本專案範疇(可由外部平台舉辦);本檔僅定義「移出清單即復用」這個操作。

情境路由(材質出問題時走哪條):

情境 走法 結果
數值不合理 / 引擎變更需調參增減 改物理數值(§11.1)= major const 原地改值,對全網所有用該材質資產追溯生效
不適合遊戲性 / 引擎變更使其不適 廢止(§11.1)= minor 凍結既有為絕版品、只擋新建