跳轉到

D-20261025-01|持彈碰撞體切換與可選彈體獨立耐久

背景與驅動力

D-20260808-03 規定 launch 彈體於 world 建立時預配置為獨立剛體, 以 fixed joint 持彈。fixed joint 是迭代求解的約束,不是剛性焊接。001077 實測:jungle v8 單台 control 以發射器與預載彈正面頂住護欄、馬達持續推,hold joint 錨點誤差恆超出 bounded-step 容差 (0.1 mm),每幀 26–46 次試算、world step 200–260 ms。一台車卡牆即可使整場八車每幀多 150–250 ms, 與牆的種類無關。研究副本中預載彈不建剛體時,細分風暴消失(P95 236→26.6 ms)。

另外,「預載彈發射前不具獨立耐久」目前沒有一條明文規定。這個結果由三份決策疊加形成: D-20260808-03 的 {handle, partIndex} 對映(預載彈 collider 歸武器零件)、D-20260814-05「weapon broken 連帶停用未發射彈藥」,以及零件級破壞單位(D-20260712-01)。創作者也無法選擇「外露彈匣、 每顆各自耐久」這類設計。

考慮過的選項

  • 預載彈改在發射時才建立剛體:牴觸 world 拓樸全預配置、SavedState 拓樸驗證與 LaunchExit 以預載 pose 為基準的契約,改動最大,否決。
  • 一顆涵蓋全部預載彈的整體 collider:發射後碰撞與視覺不符,否決。
  • 以武器底座相對座標每幀直接擺放彈體:動態彈體的接觸反力傳不回車體,kinematic 彈體等於無限質量, 兩者都會穿牆或推人,否決。
  • bounded-step 誤差計算排除 hold joint:彈體仍被擠壓,可能抖動或穿入,治標,否決。
  • 每顆預載彈在車體剛體上預配置同形狀持彈 collider,彈剛體預配置但停用,發射時切換(採納); 另加 bounded-step 細分停損,作為其他卡住情境的通用保險(採納)。
  • 彈體獨立耐久一律開啟:在偏航問題未解前會放大擦牆掉彈的不公平,平衡數值也未知,否決。
  • 彈體獨立耐久由創作者在武器上選擇、預設關閉(採納)。

決定

持彈碰撞體切換(001077)

  • 每顆 launch 預載彈於 world 建立時預配置兩件:
  • 持彈 collider:掛在車體 primary body 上,形狀、材質與質量取自該彈的 canonical proxy,pose 為 authored 預載 pose;歸屬記錄為 {handle, partIndex: 武器, projectileIndex}。
  • 彈剛體與 collider:形狀、材質、質量相同,建立後停用。
  • 不再建立 hold fixed joint。
  • 發射第 i 顆:同一幀內停用第 i 顆持彈 collider,以相同 world pose 與該點的車體速度啟用第 i 顆彈剛體, 再依既有規則施加 impulse 與等量 recoil。持彈 collider 停用即自 primary 質量屬性移除,總質量守恆。
  • LaunchExit(D-20260814-08)、owner 轉 bullet、發射後的生命週期都不變。
  • 未發射彈的呈現改由 authored 預載 pose 相對 primary 輸出,不再讀停用剛體的位姿。
  • rollback 由 immutable VehicleSpec 加上已驗證的彈藥與損毀狀態,推導每顆彈的持彈 collider 與彈剛體 應有的啟用狀態,並與 Rapier snapshot 比對;不一致則原子拒絕。

bounded-step 細分停損

  • 計數範圍為世界層:全世界任一車需要細分即計入連續細分幀數;連續 BOUNDED_STEP_STALL_FRAMES 幀需要細分後,全世界該幀接受初始分段試算,記錄診斷計數,不再繼續細分,直到某幀不再超出容差。 理由:Rapier 原生 jointConstraintErrors 只回傳全世界最大誤差,無法歸屬到單一車輛;分車計數需要 vendor 變更,或逐關節讀取誤差、承擔額外成本。
  • 常數初值於實作研究時量測後定,寫入 程式參數/protocol.md。停損條件與接受規則必須決定性, 不依牆鐘時間判斷。

預載彈耐久語意(明文化)

  • 預設(projectile_independent_durability 為 false 或缺省):預載彈發射前屬武器零件,不具獨立耐久。 持彈 collider 承受的碰撞、熱與疲勞全部計入武器零件;武器零件 broken 時,未發射彈一律停用。 彈體發射後脫離武器,依既有 projectile 規則運作。

可選彈體獨立耐久

  • 武器 GLB root extras 新增布林欄位 projectile_independent_durability,缺省為 false。編輯器武器面板 提供開關。finalizer 將它寫入 PhysicsManifest 的武器描述,admission 驗證型別。
  • 開啟時:
  • 耐久計算:每顆預載彈以自身 proxy 的材質、質量與接觸資料,套用現行零件 fatigue 與熱公式, 不另創公式。持彈 collider 承受的碰撞只累計到該彈,不累計到武器本體。
  • 武器本體:武器零件的耐久、熱容與 thermal limit 只由非彈體 proxy 合成;彈體材質不再拉低 武器的 weakest thermal limit。
  • 損毀:預載彈 broken 時,停用其持彈 collider 與彈剛體,質量自 primary 移除,走 D-20260814-05 的幀末損毀交易;碎片純視覺。
  • 發射順序:依 children index 發射,跳過已 broken 的彈;可用彈藥數=未發射且未損毀者。
  • 流體彈:發射前 broken 時直接消失,不建立部署區。
  • 同幀判定:發射在幀內輸入處理時決定;損毀交易在幀末提交。同一幀先發射、後判定損毀時, 發射成立,彈體已脫離武器,不再受武器損毀交易影響。
  • 歸因:預載彈 broken 記為損傷事件,但不計入零件致毀、destructionCounts、信譽或戰績統計 (修訂 D-20260814-10)。彈為消耗品,避免以刷彈換取統計。
  • 武器零件 broken:未發射彈一律停用,與預設模式相同。
  • 編輯器檢核:開啟時顯示每顆彈的耐久估計;任一顆在 PROJECTILE_FRAGILE_WARN_* 門檻下即給警告 (門檻於實作時定)。
  • 公版武器維持預設 false。
  • SavedState 每顆預載彈保存 broken/breakFrame;runtime hash 納入。HUD 與觀戰呈現以有界描述顯示 已損毀的預載彈。

後果與影響

  • 消除 001077 的持續細分來源;每台有發射器的車少 N 個 fixed joint,彈剛體在發射前停用,不參與模擬。
  • 持彈 collider 數與預載彈數相同;歸屬紀錄含 projectileIndex,兩種耐久模式共用同一拓樸。
  • PhysicsManifest 武器描述新增欄位,所有含 launch 彈的武器 canonical digest 會改變;公版 weapon-03 需隨同批重烘。
  • 需要補的驗證:
  • 發射前、發射當幀、回滾跨越發射幀與損毀幀的決定性與 conformance 案例;
  • 兩種耐久模式各一組;
  • 頂牆回歸案例(001077 場景)的 trials 上限斷言。
  • canon 同步:physics-engine.md 第 2.4 節 與世界組成、零件與共用介面.md 武器欄位、算式表 fatigue/熱的 彈體段、編輯器操作.md 武器面板、程式參數 protocol.md 新常數、D-20260814-10 歸因例外。
  • 平衡數值仍需 playtest 驗證;預設關閉,因此不影響公版平衡。
  • 細分停損採世界層計數的取捨:觸發時全場同幀都改用初始分段試算,精度略降;停損條件只依決定性的 幀數與試算結果,全部 peer 同幀同判,決定性與公平不受影響。八車同場時,不同車輪流需要細分也會串成 連續計數,可能誤觸發。世界層已有不入共識的診斷計數(停損觸發幀數、接受超出容差幀數、最長連續細分 幀數),playtest 觀察後再評估是否改為分車計數。