歷史記錄 · 2026-07-07¶
重大重構里程碑¶
2026-07-07 ─ 里程碑 4c-2:檢核引擎——場地規則全套(測試 172/172 全綠;4c 共用 validator 收官)¶
內容(validation/track-rules.ts;共識決定性紀律適用=僅 +−×÷/sqrt/整數取捨、ESLint 防線涵蓋):①route 結構=點數(open 恰 2/fixed ≥ 2)/entry↔empty 1:1/RoutePoint_ 前綴孤兒拒收/寬度必填 > 0/⭐RP1 寬 → deriveTrackPlayerMax(floor(寬 ÷(車寬 130+安全邊距 50))clamp 8——常數推導非字面 180)→ < PLAYERS_PER_RACE_MIN 拒收、< 8 軟警告/相鄰間距 < 100mm 拒收(例外=fixed+loop 首尾 wrap-around 對;恰 2 點時相鄰迴圈已涵蓋不重複報)/lap_mode 宣告合法性(鐵則 3:loop 需 fixed+≥3 點+首尾 < 1m、open 宣告 loop=拒)/⭐貼面 ±5mm=點到 mesh 最近距離(Ericson 最近點法:barycentric 區域判定、無超越函數;facts.geometry null=box 近似期跳過);inferLapMode 推斷 helper 一併提供(Stage 2 系統性調整用)。②checkpoint=scale 域(min [100,100,1000]/max 場地 AABB 各軸 1/10;scale=worldMatrix 基底 column 長)+box containment(position±scale/2 全在 AABB 內)+entry↔empty 1:1+孤兒;killzone containment+respawn 位置在 AABB 內+「有 killzone 無 respawn」warn。③entity(graph node extras 掃描=單一來源、編輯與收件同讀)=3 類 enum/physics 互斥(visual_only 僅 decoration)/鐵則 4(destructible×visual_only)/kinematic_move(運動至少填一/period ≥ 500/amplitude 向量長 ≤ 20m/rotation 1–360+軸非零/motion_curve enum/⭐open_duration_ratio 僅 step 可填)/conveyor |v| ≤ 10/magnet 強度域/node-level 材質 enum+environment scope/全域上限(entity > 100、destructible > 50 拒收)。④weather=溫度域依 type(normal −20..40/rain 2..35/snow −30..2)/wind 0–10+方向 0–360/⭐normal 帶 patch=拒收(§8.3 不可填)/rain·snow 缺 patch 區塊=拒收(繞過填補層的手工 GLB)/patch 六欄位域/patch 預估數 ≤ 50(⭐合法域內最大 30×60000/60000=30——規則屬未來防護、現域不可觸發,同密度比先例)。⑤gravity=方向非零向量+強度 1.6–25(缺=預設填補合法)。⑥材質=environment scope+entity node 列入 materials[]=雙重宣告拒收(node-level 權威)。⑦貼圖預算=≤ 16 張 1K「或」≤ 4 張 4K 擇一檔位+單張 > 4096 直接拒收(security 新 export imageHeaderBytes/sniffImageSize 嗅探)。⑧壓縮檢核=Draco extension+KTX2 mimeType——options.requireCompression 開關(⭐自動壓縮管線落地前編輯器不啟用、收件端啟用;防繞過 Stage 2 直送)。領域常數=溫度域/patch 域/重力域(值權威=建模參數表 §8.3–8.4)。staged:三 tag(terrain/difficulty/style)=ledger record 層、隨 4e 送出表單驗;auto_* 區塊齊全性=4e 序列化層保證;Empty 標準名 PascalCase 檢核=§5.4「命名與順序分離」為準(前綴孤兒已涵蓋)。測試 +20=172/172(12 檔):乾淨 open 場地(含貼面)=零 findings/route 全規則(loop 例外含首尾重合合法整案)/checkpoint 四規則+計數斷言/killzone·respawn+warn 層級/entity 全域(101 實體 fixture)/weather·gravity 域/貼圖三檔位/壓縮開關/推導 helpers 邊界。七驗證全綠。
同日落地複審(中 2 細項 3 修、觀察 3 備查):①⭐衍生限制漏場地 AABB 上限——UGC機制 §9.3「衍生限制滿足」明列 AABB ≤ 500×500×100m,但 validateTrack 未驗(Stage 1 不擋屬正確、Stage 3 須驗縮放後最終幾何——收件端對手工直送 GLB 無此檢即放行超限場地)→ 補 checkTrackLimits(軸序映射 [長Z,寬X,高Y] 同 wave-a)+測試;②⭐衍生限制漏 visual 三角形上限——同表 tris ≤ 3M 未驗 → facts.geometry 有值時加總檢核+注入 triangleCount 測試(collider tris 區分=真 GLB 期 collider 標記慣例未定、staged);③route/checkpoints 陣列內重複 entry 未擋——「1:1」語意含陣列不重複(重複 entry=同 empty 雙掛)→ 補 route-duplicate-entry/checkpoint-duplicate-entry;④weather.type 以 in 判定會沿原型鏈命中哨兵鍵('constructor' 過關)——收件端吃原始資料須防 → 改顯式三值比對+哨兵測試;⑤貼圖嗅探對畸形 bufferView 會拋出(imageHeaderBytes 越界 throw 逃出 validator)→ try/catch fail-soft(sanitize 層責任)+不拋出測試。乾淨面覆核:§9.3 表 14 行逐條對照(三 tag/marker·區塊齊全=4e 序列化層、GLB 大小=收件管線重跑 stage1 涵蓋——皆已記錄);「宣告 linear+首尾 <100mm」被 too-close 拒=符合 canon(重合例外原文綁 lap_mode: loop);kinematic amplitude 非數字元素→NaN→拒收(fail-safe);checkpoint scale=worldMatrix 基底長恆正。觀察備查:collider/visual mesh 區分標記慣例未定(真 GLB 期定案後補 collider tris 檢核);GLB 大小 Stage 3 重驗=收件管線組合 stage1+stage3 兩段涵蓋;no-useless-assignment 為 lint 新抓規則(let 初始 null 恆覆寫——收件強固修時順修)。測試 172→177/177、七驗證全綠。
2026-07-07 ─ 里程碑 4c-1:檢核引擎——Finding 模型+Stage 1 寬鬆+零件規則全套(測試 150/150 全綠)¶
⭐與收件端共用 validator 落地開端(單一實作防「編輯器放行、全網拒收」規則漂移;4c-2=場地規則)。Finding 模型(findings.ts):{level: reject/warn/info, code, target{nodeName, field}, params}——零文案(訊息=UI 層 i18n validation.<code>、比照 PIN 錯誤結構化先例);reject=Stage 3 拒收+即時紅框+送出雙鈕灰、warn=軟警告黃框不阻擋;hasReject/countByLevel(banner「拒收 X・軟警告 Y」計數)。⭐決定性防線範圍擴充兌現(決定性掃蕩觀察項):src/editor/validation/** 納入 ESLint 共識規則(收件端全網重算須逐位元一致)——規則全程僅 +−×÷/sqrt/整數取捨;roller 軸夾角門檻改 sin 值比較(30°=0.5、60°=√3/2)免反三角。Stage 1 寬鬆(stage1.ts):no-mesh/重名/零件 vertex·tri 上限/零件 AABB 域(type 定案尺度擋點)/場地 80MB/退化 AABB;decideTypeResolution=type 定案矩陣(UI 選擇 × GLB 宣告 × 幾何符合 → proceed/proceed-override/fail)。零件規則(part-rules.ts;draft 型別=編輯中欄位可暫缺、收件端以最終值填):①材質=主材質必填/enum 存在/forbidden_scopes+allowed_part_types(isMaterialAllowed 複用)/覆寫節點存在/node-level 雙重宣告拒收/密度比 > 50:1(⭐現行 31 材質最大比=copper 8.0/snow 0.3=26.7——規則屬未來防護、現表不可觸發,以注入材質表測)/磁源強度 0–10+「部件含 source 材質」warn(fallback 防護);②motor torque_ratio 必填+0–100;③battery declared_output_w ≤ volume × K_BATTERY_OUTPUT;④chip=slot 數 ≤ deriveChipSlotCount/skill enum+重複/kinetic 1–100 整數/Σ ≤ 100;⑤weapon=passive 無 active 欄位要求、active 缺 mechanism/main_mesh_node 拒收(main 需存在且為 mesh 節點)、Axis 缺=warn(fallback 推斷路徑)、actuator 全欄位(pivot 存在/rotation_axis 非零/max_angle 1–360/speed_weight > 0/phase 0–360/payload mesh_node ⊕ chain 恰一/360 連旋帶 motion_curve=warn)、pivots ≤ 8+驅動體(轉子+鏈段)≤ 16、magnet/launch 帶 actuators=互斥拒收、Chain_Segment_<n> 斷號拒收、launch=彈藥 1–8+bullet node-level 材質必填+同套材質規則;⑥Mount=完整性(chassis 18 標準名/各 part 端標準名、缺=拒收)+幾何三規則(偏離 chassis AABB > 30 紅/10–30 黃〔點到 AABB 歐氏距〕;互距 < 3 紅/3–10 黃;roller hinge 軸(+X 慣例)與水平面 > 60° 紅/30–60° 黃、tire canonical 不檢)——門檻值=領域模組常數(MOUNT_*;程式參數表無此組、建模參數表 §6.4 為值權威)。測試 +21=150/150(11 檔):Stage 1 全擋點+定案矩陣;材質五規則(注入表測密度比與 source warn);motor/battery/chip 域;weapon 全鏈(payload 二選一/斷號 missing='3'/彈藥超限+材質缺/magnet 互斥/360+curve warn 層級);Mount 完整性+三幾何規則雙門檻(含 tire 不檢)。staged→4c-2:場地規則(route/checkpoint/killzone/respawn/entity/weather/physics/kinematic/貼圖預算/壓縮檢核/Empty↔陣列 1:1);鏈上關卡(fingerprint/文字黑名單/fork parent 狀態)隨站 5/6 接線。七驗證全綠。
同日落地複審(細項 3 修、觀察 4 備查、防線接線驗證):①⭐hinge 軸檢核漏 tire——編輯器操作 §3.1 即時表只列 roller(UI 層因 tire 不可調、不顯示),但建模參數表 §6.4 拒收表原文=「tire / roller mount 軸向 > 60° 拒收」、「檢核對 tire 恆過」語意=合法模板下必過而非免檢——收件端須擋繞過編輯器的手工歪軸 GLB → 檢核擴至 Mount_Tire_*、規則碼改中性 hinge-axis-steep/hinge-axis-tilted+tire 歪軸測試。②Stage 1「剃除違規材質指派」缺操作面——canon「禁止材質不在 Stage 1 拒收、自動剃除變未指派」是 transform 非 finding → 補 stripForbiddenMaterialOverrides+keepAllowedMaterial(scope 通用、未知材質一併剃)+測試。③編輯中 rename 重名即時層漏——重名原僅 Stage 1(上傳時)檢,編輯 session 內 rename 可再造重名 → validatePart 開頭補 duplicateNames findings(即時層單一呼叫全涵蓋)+測試。防線接線驗證:--print-config 確認 no-restricted-syntax/properties 兩規則確實套用 part-rules.ts、spec 檔無輸出=豁免(比照決定性掃蕩慣例、「lint 綠」之外的正向驗證)。乾淨面覆核:Stage 1 對 UGC上傳流程 §3 六條逐一對照(GLB 格式/結構錯誤=上游 parse 層 ✓);Stage 3 對 §4 表逐條(fingerprint/fork=站 5/6 staged ✓);「Mount 偏離」語意=距 AABB 外側距離(在內=0 恆過)✓;finding 順序決定性(Map 插入序+DFS 序)且 gate=hasReject 與順序無關;chip 無效 kinetic 不計入 Σ(range 已拒、不重複報)。觀察備查:chain 歸屬清單重複名會雙計驅動體(保守側;auto_chain 推導以 GLB 結構為準、隨 4d);chip skillSlots=[] 合法(「空 slot 可留白」);weapon 缺 mechanism 時後續欄位檢核省略=漸進揭露(補上後重跑);i18n validation.* key 名單隨站 10 語系清單收斂。測試 150→152/152、七驗證全綠。
2026-07-07 ─ 里程碑 4b:K-means 材質分群(CIELAB+ΔE2000、確定性種子;測試 127/127 全綠)¶
內容:src/editor/clustering/ 三檔。①cielab.ts=sRGB↔線性↔CIELAB(D65)互轉+labToSrgbHex(UI 色塊)+CIEDE2000 全式(Sharma 公式:G 補償/hue 平均分支/T 項/RT 旋轉項)——以公開標準測資驗證(2.0425/2.8615/3.4412/27.1492 四對至小數 4 位)+對稱性+同色 0。②face-colors.ts=per-face 色彩抽取(優先序:COLOR_0 頂點色〔float/ubyte/ushort normalized、VEC3/VEC4、三頂點平均〕× baseColorFactor〔glTF 乘法語意、皆線性〕→ 僅 factor → 預設白;面序與 extractNodeGeometry 合併順序一致=色彩↔幾何對齊;accessor 解碼 fail-soft)+faceAreasMm2(分群權重)。③kmeans.ts=全程確定性 K-means(無隨機:初始中心=Lab 粗格化〔L/10、a·b/15〕主色依面積權重降冪取前 k、平手格鍵字典序;指派=ΔE2000 最近、平手低 index;重心=面積加權 Lab 平均;收斂或 20 輪上限;空群剔除、id 依面積降冪壓實——clusters[0]=最大 sub-mesh=主材質預設來源)+操作三件(merge=absorb 併入 keep/split=成員面再跑 k=2、單一主色 no-op/repaint=面集改指派、被清空群自動剔除)+connectedRegion(fill connected region 選取:位置焊接後建共享邊圖 BFS——exporter 複製頂點不斷開連通;複用 physics-engine 新 export weldTrianglesByPosition)。k 滑桿域=CLUSTER_K_MIN/MAX/DEFAULT(4/12/8)落 clustering 模組=領域模組權威(前端技術策略 §4.1 允許「system-constants 或領域模組」;避免程式參數表插節連鎖重編號)。staged:baseColorTexture × UV 取樣(需影像解碼、隨 viewport 以 OffscreenCanvas 補入);cluster→實體 sub-mesh 切割落 GLB(隨 4e finalize)。測試 +14=127/127(10 檔):CIELAB 基準色+hex 純色往返;ΔE2000 標準測資+對稱+自反 0;三主色 k=3 全對分離+面積降冪+重跑逐位元一致;主色 < k 不生空群;areaShare 總和=1;merge 面積守恆;split 拆回兩色/單色 no-op;repaint 清空剔除;connectedRegion 孤島隔離+重複頂點不斷開+異群不擴張;GLB 面色彩三來源+面序對齊。七驗證全綠。
同日落地複審(細項 2 修、觀察 4 備查、1 疑點排除):①⭐merge/repaint 越界 id=巨型配置向量——兩操作原不驗 id、而 rebuild 依 maxId+1 配置統計陣列(targetId=1e9 → 十億元素配置=OOM/凍結)→ 補 isValidClusterId 守門(非整數/負值/≥ cluster 數=no-op 原樣返回)+回歸測試 3 斷言(split 對壞 id 本已安全:成員空 → no-op)。②extractFaceColors TSDoc 補呼叫契約(於 extractNodeGeometry 成功後呼叫——indices 同資料已驗證可解碼、不另 try/catch 以免 skip primitive 造成面序錯位;色彩 accessor 才是 fail-soft 範圍)。疑點排除:labToSrgbHex 出色域 Lab(混色重心可達)疑產 NaN hex——覆核=負線性通道走「≤0.0031308 線性分支」再 clamp 0、無 NaN 路徑(Math.pow 只收非負);補 3 斷言鎖行為(a±128/L=120/L=−10 皆合法色碼)。乾淨面覆核:spec 對照(§2.3 k 滑桿域·合併·拆分·paint·主材質=最大 sub-mesh/UGC機制 §3.7 四階段 C 之 fill connected region)全覆蓋——套索/多邊形/反選=viewport 螢幕空間選取、歸約為 repaintFaces(隨 UI);ΔE2000 已由公開測資釘死;種子/迭代/壓實全確定性(Map 插入序+穩定排序+平手規則明確);splitCluster 新 id=clusters.length 無碰撞;iterate 空群保原位收尾剔除正確。觀察備查:全對 ΔE2000 計算量(10 萬面 × k × 20 輪 ≈ 秒級)——k 滑桿即時重跑對大 mesh 可感、viewport 期可加降採樣預覽;connectedRegion 每呼叫重建鄰接圖 O(faces)——高頻互動時 viewport 層可快取;零面積面(退化三角形)純群 centroid 退化 [0,0,0]——sanitize 已擋退化面、實務不可達;clusterFaces 輸入長度不匹配回空結果(呼叫端同源、低風險)。測試 127→129/129、七驗證全綠。
2026-07-07 ─ 里程碑 4a:editor 地基(GLB scene graph+wave A 進場管線+voxel 備援;測試 111/111 全綠)¶
站 3 editor 開站(程式架構.md §5 順序;子里程碑規劃:4a 地基/4b K-means 分群/4c 檢核引擎〔⭐與收件端共用 validator〕/4d session+chain-scan/4e wave B+送出雙出口)。本站定位=先落邏輯核心(pipeline/clustering/validation/session/chain-scan——皆純函式可測);viewport 與 UI 組裝(o4-3d-stage workshop preset、版面)隨站 10 ui-kit/pages 收斂。4a 內容:①editor/glb-scene.ts=scene graph 解析層(node 樹:名稱/階層/TRS·matrix 世界變換合成〔quaternion 展開僅 +−×〕/extras/per-node 世界座標幾何展開〔多 primitive 索引 offset 合併〕;重名偵測=Stage 1 拒收依據;readRootExtras 慣例=預設 scene extras〔Blender custom properties 落點〕→ 根 extras fallback;classifyEmptyName 八類前綴;循環/越界節點 err)。②voxelization 備援補入 physics-engine/mesh-volume.ts(3c-1 註記欠帳兌現)=陣列級純函式家族重構:signedVolumeMm3/surfaceAreaMm2/meshCentroidMm(原點四面體質心加權)/isWatertightGeometry(⭐判定升級=位置逐位元焊接後判無向邊恰 2 面——exporter 為法線/UV 複製頂點時原「per-primitive 索引」判定必假陰性)/voxelVolumeMm3(沿 +X 柱射線奇偶判內外、(y,z) AABB 分桶、僅 +−×÷ 決定性;誤差 ~±1% @ 100 格);GLB 級 API 契約不變。⭐落地 debug=封閉 box 精確性測試抓到「柱心恰落三角形共享對角線(y=z)→ 兩鄰面同時計數 → 區間長度歸零 → 整排柱漏算恰 1% 體積」→ 修=y/z 取相異子格採樣偏移(0.5/0.3737 固定常數、仍決定性)——整數格索引無法同時對齊共享邊。③editor/wave-a.ts=八步進度管線(parse-scene→extract-geometry→volume〔per-node watertight 積分→voxel 備援〕→surface-area→aabb→mass-centroid→track-fit→derive;步序常數供 loading 覆蓋層「n/8」);材質相依量獨立為 computeMassAndCentroid(mass=Σ node 體積×密度、質心=密度加權;材質變動反應式重算幾何不重跑;任一 node 材質無解=null 暫缺);場地 track-fit=AABB 超限等比縮放係數(⭐TRACK_AABB_MAX_MM 軸序=[長Z, 寬X, 高Y] 同 VEHICLE 慣例——常數檔補軸序註解防誤讀)+visual 超 3M per-node 降階;衍生欄位=chip slot 階梯/motor auto_input_w/battery capacity·output 上限。④editor/decimate.ts=決定性 vertex-clustering 簡化(cell 吸附焊接→退化/重複面剔除→未達標 cell×1.4 迭代收斂;decimateNodeBudgets 依面數比例分攤=保留 sub-mesh 材質身分)。⑤wave-a.worker.ts(sanitize.worker 同模式:progress/done/error 協定;new Worker 接線隨 viewport)。staged:零件 canonical AABB 縮放對齊(缺 builtin-assets canonical 尺寸表;§7.3 ±15% 容差家族隨 4e wave B)/auto_contact_area 六向投影(spec 未列 wave A/B、隨 4e aero 同 rasterization 基建)/Draco+KTX2 壓縮(glTF 標準 extension、需套件決策)/collider 缺失衍生(visual→decimate 500k、隨 4e finalize)。觀察:builtin-assets/parts.ts 內部已有同語意 chip slot 推導(參數不變式用)——4c validator 集中規則時收斂單一實作。測試 +20=111/111(9 檔):scene graph 階層變換/重名/root extras/empty 分類;平移·旋轉·縮放幾何量(box 解析解比對);voxel 開口盒備援+封閉盒精確+重跑逐位元一致;質量質心雙密度+主材質 fallback+null 暫缺;decimate 決定性+已達標原樣返回;track-fit 兩軸向(含高=Y 對應);chip 階梯邊界;八步進度序。七驗證全綠。
同日落地複審(細項 5 修、觀察 4 備查):①⭐NaN/Inf 穿透洞——sanitize 只驗頂點座標、node transform 的非有限值不在驗證面(JSON 無法載 NaN、但 1e999 解析為 Infinity 可達),且體積 guard 原寫 volumeMm3 <= 0(NaN 比較恆 false)→ 非有限值可穿透整條管線產出 NaN 結果——修=volume 步補 Number.isFinite(單點 fail-fast 涵蓋下游全部欄位)+回歸測試(Inf 頂點 box → err、修正前必掛)。②parseSceneGraph 走訪包 try/catch(惡意深層階層的遞迴溢位不讓例外逃出解析層)+循環引用測試。③wave-a.worker 收訊包 try/catch(意外 throw 一律收斂成協定內 error 訊息、主執行緒不落 error event)。④decimate 初始格距註解殘留棄用設計描述 → 對齊實作。⑤canon 現況化=physics-engine.md §5 voxel 備援列改實作現況((y,z) 100² 柱射線奇偶+精確 x 區間積分+相異子格偏移)、:120 blockquote「voxel 隨編輯器補入」→ 已落地+watertight 判定補位置焊接語;editor.md §2「幾何計算走 WASM」→「首版 TS、指紋 WASM」(與 physics-engine.md 實作落點對齊、消措辭 drift)。乾淨面覆核:wave A 步序 vs 建模參數表 §10/UGC上傳流程 §2 清單逐項對照全覆蓋(mass·centroid=材質後反應式 ✓ UGC機制 §3.1 兩段表語意);chip 階梯 ↔ parts.ts 公式同值;K 常數(80/80/50)↔ spec 預估一致;負 scale 鏡像(signed volume 取 abs)/instanced mesh 雙節點雙計/±0 位置焊接同鍵(String(-0)='0')皆正確;ESLint 決定性防線涵蓋 mesh-volume 新增碼(lint 綠=無禁用運算)。觀察備查:welded watertight 對「兩封閉殼共面貼合」判非 watertight(共享邊 4×)→ editor 路徑落 voxel 備援、值仍近似正確——canon「恰 2 面」定義保留(真 GLB 期常見再議);decimateNodeBudgets 的 max(1,·) 可使總面數微超目標(≤ node 數、Stage 3 覆核兜底);track 大 mesh 的位置焊接 Map 建鍵屬 O(tris) 重操作(Worker 30–60s 預算內、必要時再優化);wave-a.worker 尚無 new Worker 接線(隨 viewport/UI、比照 sanitize.worker 模式)。測試 111→113/113、七驗證全綠。
2026-07-07 ─ 決定性掃蕩:實作近似數學函數清零(Math.cbrt→定次 Newton、**→連乘)+ESLint 共識防線;測試 91/91¶
決策檔:D-20260707-01
背景:使用者問「程式內許多計算有小數,是合理使用還是疏忽?」→ 全 src 盤點。判定=浮點本身是設計決定:ECMAScript 保證 + − × ÷、Math.sqrt 與整數取捨函數(round/floor/ceil/trunc/abs/min/max)正確捨入=跨引擎逐位元一致;被禁的是規格標「implementation-approximated」的函數(跨引擎可差 1 ulp=P2P 分岔源)——與 rapier deterministic-compat 同模型;整數化僅用在浮點做不到之處(TrueSkill 定點/經濟 bigint/hash 邊界量化)。盤點:Math.* 全 src(非測試)47 處中 46 處白名單內、Math.random 零使用、Date.now 三處皆非共識層(簽章時戳/nonce TTL/本地 log、皆可注入)✓。漏網 2 類 5 處全修:⭐①Math.cbrt(launch 子彈等體積球半徑——半徑→collider→世界狀態→hash)→ 新 deterministicCbrt=定次 32 輪 Newton 迭代(種子 sqrt(sqrt(x)) 同量級、僅 + − × ÷ 與 sqrt;非有限/≤0 回 0;export+TSDoc+測試 2=完全立方精確還原〔8→2、27→3 逐位元〕+全量級 10^±9 貼合 Math.cbrt 相對誤差 ≤2e-15);②** 冪運算 4 處(ES **=pow 語意、規格屬實作近似;x**3 走 libm 一般路徑跨引擎風險真實,x**2 實務多特例化為 xx 但規格無保證)→ 改連乘、保留原運算分組(重力向量長度/起跑格右向長度/衝撞動能 relativeSpeed²/子彈體積 radiusM³)。防再犯=ESLint 決定性防線(eslint.config.js):src/physics-engine/**(*.spec.ts 豁免)禁 **/**=(no-restricted-syntax)+ Math 黑名單 23 成員(no-restricted-properties=全部 implementation-approximated 三角/雙曲/指對數/pow/cbrt/hypot+非決定性 random);--print-config 驗證規則確實套用引擎檔、spec 檔豁免。觀察備查:測試檔 Math.hypot 4 處=容差斷言用、屬豁免範圍。測試 89→91/91*、七驗證全綠。
同日落地複審(細項 2 修、觀察 4 備查):①deterministicCbrt TSDoc 補收斂域——定次 32 輪對 x∈[1e-12, 1e12](引擎全部物理量值域)綽綽有餘(最壞 ~15 輪達 ≤1 ulp);遠超此域的極端輸入(如 1e300 需 ~280 輪)輪數不足僅精度下降、運算序列固定結果仍全平台一致(y² overflow→Inf→x/Inf=+0 優雅降級、無 NaN 路徑;完全立方鄰值仍映回精確根——皆驗算)。②程式架構/physics-engine.md §8 Determinism 表補「運算白名單」列(原僅 §5 mesh 體積 blockquote 有局部決定性註、引擎全域運算紀律無 canon 落點)=正確捨入白名單(+−×÷/sqrt/整數取捨)+implementation-approximated 函數與 ** 禁用+替代法(連乘/線性化/shortest-arc/定次 Newton)+ESLint 強制註;互鏈資料系統 §17 同族不變式、不建重複權威。乾淨面覆核:localeCompare/toLocale*/Intl. 全 src 零(無 locale 依賴排序入共識);非 spec 檔 ** 殘留零;ESLint 黑名單 23=ES 規格 implementation-approximated 全集+random(規格層完備、不依賴個別引擎 fdlibm 特例);Math.round(-0.5)=−0 已由量化 ||0 正規化、dag-cbor float64 編碼決定性;替換不破壞既有 hash 斷言(測試皆 run-to-run 比較、無 golden 值);git 修改面與宣稱一致。觀察備查:ESLint 防線屬 tripwire 級(const M = Math 別名/globalThis.Math 繞過不攔——靠複審把關、夠用);防線範圍隨站別擴充(站 3 檢核引擎共用 validator、站 4/5 ledger·matchmaking·network-sync 實作時同紀律納入 lint 範圍);loadVehicle 呼叫順序=共識輸入(body/collider 建構序影響 Rapier 世界——多 peer 同序由站 4/5 議定協議保證、現單機 rollback 不受影響);測試檔 Math.hypot=容差斷言用、豁免屬設計。七驗證全綠、91/91。
2026-07-07 ─ 里程碑 3c-3:場地物理(route 計圈/b-soft 處罰/掉出/deploy zone/磁源統一結算;測試 89/89 全綠)¶
介面收斂:TrackSpec.config?: TrackConfig 宣告制(真 GLB 時代由 convert 自 extras 解析、box 近似期宣告;RoutePoint{positionMm, forward, widthMm}/checkpoints(球形 trigger 近似——canon 為 trigger box、box 近似期以球近似)/respawnPoints/killZones/DeployZone/TrackMagnetSource/weather/gravity;interfaces.md §3.1 雙鏡面同步 ✓)。track-sim.ts 純函式模組:①route → Hermite spline 預採樣折線(切線長=弦長×1/3、每段 16 樣本=等弧長近似、寬度沿段線性插值=auto_route_polyline_3d 的 box 近似期替身);②RaceProgress 全欄位共識 sim state(lapsDone/nextCheckpoint/finished/atFinishGate 出生 true 防 loop 起終重合誤計/offTrack 狀態機/penaltyFrames/respawnTo/airFrames/lastValidPos+Tangent);③trackTick 每幀狀態機=統一處罰流程(decel 60 幀線性減速→fade 36 幀凍結、中點 teleport;脫離型中途回走廊即取消保留速度、掉出型不可取消)/掉出雙判(killZone AABB+重力向投影 AABB+5m buffer fallback)→最近 respawn 點/b-soft(僅 fixed+在表面=contact+100ms hysteresis 6 幀;空中段不檢核=跳躍過溝合法、落地偏離即觸發)/checkpoint 依序球形點亮(跳序不算、跨 RPn 保留)/終點=RPn.forward·車速>0 正向+全 checkpoint 已亮(linear 完賽/loop 計圈+重置、達 lapTarget 完賽;反向不增不減);④forwardToQuaternion shortest-arc(僅 +−×÷√=IEEE 決定性、反向退化繞 Y 180°)。引擎整合:①磁力統一結算 pass(3c-2b staged 兌現——武器 magnet action 改收集為 MagnetSource 與場地固定源同池:源→鐵磁 1/r² 純吸引+源↔源 N 極耦合=−dot(nPoleA,nPoleB)(N 對 N 互指→斥)、Newton 3rd 成對、場地源 owner=null 不受反作用;算式表 §5.3 耦合註記順修=互指 θ<0→coupling>0=斥);②deploy zone 四效果(burn 升溫過加持抗性打折/freeze 純冷卻不打折/corrosive 走 applyAcidTick/sticky 每秒保留率線性化 1−(1−decay)×dt 免 runtime pow;grip_loss+sticky grip 面隨輪胎摩擦模型 staged);③起跑格=route 起點沿右向(tangent×上向)0.3m 錯位+朝向 spline 切線(loadTrack↔loadVehicle 任一順序皆就位);④重力(config 宣告向量×強度)+環境溫 weather.temperatureC 接線;⑤StepOutput.finishedVehicles=累計完賽 vehicleId 排序;⑥RaceProgress 入 SavedState v2 與量化 hash(pos×1000/tangent×1e6/enum 字串)——rollback 含計圈與處罰狀態 bit-exact。⭐落地覆核修 1:減速階段 canon=「線性減速到 0」——初版每幀 剩餘/60 對當前速度連乘=近指數急煞(且使中途取消形同虛設)→ 修正每幀係數=剩餘/(剩餘+1)(v_n=v0×(N−n)/N 真線性)。測試 +12=89/89:純函式 6(loop 計圈+checkpoint 閘+gate 防重複/linear 反向不完賽/b-soft 觸發+取消/全程 96 幀+teleport 回 lastValid/killZone+掉出→respawn/open 無 b-soft+跳躍 hysteresis 三段)+整合 6(起跑格雙順序/自走完賽 finishedVehicles 黏著/burn·freeze·corrosive/sticky 對照組/場地磁源吸 steel 車/rollback 含 race progress 完賽幀一致+重播 bit-exact);六驗證全綠。staged:天氣摩擦 patch/風力(aero 烘焙)/entity 三類+destructible/grip modifier/彈體破壞——隨輪胎摩擦模型與 entity 系統子步收斂。
同日落地複審(中 1 細項 6、測試斷言 +1=89/89):⭐①材質表 §3 sticky 公式自打——「velocity ×= velocity_decay_per_sec^dt」為共識路徑 runtime pow(corpus 超越函數禁令),spec 補線性化權威式 1−(1−decay)×dt(每秒保留率之一階近似;實作本已線性);②deploy burn/freeze/corrosive 改逐 part 判定(原以車身中心一刀套全 parts——材質表 §3 corrosive 明文「接觸 sub-mesh」per-part 語意;partWorldPosition 逐 part 含測、無 collider 退回車身中心;sticky=車速層級維持車身中心);③respawn 朝向修=最近 respawn 點所在 route 樣本切線(原一律 RP1 切線——loop 遠端重生會面向起點方向);④loadTrack 對 route < 2 點 補 err(原 buildTrackSim 內部 crash 未被 catch)+測試斷言;⑤先車後場順序 ambient 對齊=loadTrack weather 重設已載入車輛 part 溫度(算式表 §11 回合初始=場地環境溫);⑥destroy() 補 lapTarget 重設 default(防引擎重用殘留房間設定);⑦StepOutput.finishedVehicles 語意文檔化=累計完賽集合(vehicleId 排序=canonical、非名次;首次出現 frame=完賽幀、名次由上層據此排)——TSDoc+interfaces.md 鏡像。乾淨面覆核:處罰幀帳 1.0s+0.6s 精確/掉出三層(KillZone 剛體中心→重力投影→橫向不檢核)+RP1 中心 fallback/⭐b-soft「與 spline 中心線距離」=canon 原文 3D 距離(勘查後確認「改橫向距離」反而偏離 canon、不改)/RPn 正向判定適用 linear+loop(建模 §5.4)/checkpoint 跨 RPn 保留+未全亮不計圈不清除/重力式=normalize×strength(算式表 §10.4 逐字)/deploy 參數名與預設值=材質表 fluid 行(lava 30/freezing −20/oil 0.7)/applyAcidTick broken·fluid·null 三防護。觀察備查:freeze 每幀重力微沉 ~2.7mm(有接觸無礙)/checkpoint·gate 球形近似已註記(canon trigger box)/起跑格幾何 canon 無明文=引擎慣例(右向 0.3m、抬 0.05m)/SAMPLES_PER_SEGMENT=16 等弧長近似(真 GLB 期改讀預烘焙 auto_route_polyline_3d)/重複 loadTrack 帶 config 整組覆蓋重排(實際流程一回合一場地)/trackTick.finishedNow 供上層完賽幀事件、engine 內未消費。七驗證全綠。
2026-07-07 ─ 里程碑 3c-2b:武器機制(recoil/push/磁力/launch+被動加持;K 族 TBD 清零;測試 77/77 全綠)¶
⭐武器 K 常數 4 顆定值+spec 量綱覆核修 2:K_REACTION(1e-5——原 spec「預估 0.3–1.0」與能量直乘域〔10³–10⁴〕矛盾、量綱重推+算式表 §4 註記修)/K_MAGNET_FORCE(1.5e-4、滿配 ≈5N 對齊場地磁源 0–10N 域)/K_MAGNET_PERMEABILITY(500、r=mm 尺度吸收)/K_WEAPON_ROTOR_SPEED(0.001、滿配單轉子 ≈33 rad/s)——K 族 TBD 清零(其他.md 清單同步);算式表 §5.1 磁源強度語意修=kinetic_ratio × declared(持續場強、去 dt——原「applied_energy」含 dt 會使場強隨幀率變、同 §3 rotor P 語意)。介面收斂:VehicleSpec.weapon?: VehicleWeaponSpec(passive/branch/passiveWeightSplitPct/launch 彈藥宣告——真 mesh 時代自 GLB 掃、box 近似期宣告制;interfaces.md §3.1 雙鏡面同步 ✓)。實作:①被動加持三因子(createVehicleSim 靜態套用:weapon part 有效質量 ×(10000−massRed)/10000、resistFactorX10000 入 PartSim、applyImpact fatigue 累積打折——僅及武器自身、X100 整數截斷除;熱流入打折掛 deploy 接線點);②simTick weapon case=active 過 chip 全鏈(spike+殺手鐧+電池連帶)+Hold recoil(push/actuated 沿 +Z 後座)+weaponAction{mechanism, appliedEnergy, powerBudget} 輸出;③引擎層 executeWeaponAction=push 遞送(touchingOwners 接觸查詢→對接觸中他車施前推、action-reaction 對)/磁場(1/r²、per passive part、10mm 近貼防爆、Newton 3rd 雙向施力)/launch(間隔 15 幀=250ms、彈藥耗盡即空、每發能量=功率×發射週期、子彈衝量 vs chassis 後座成對、spawnBullet dynamic 球體固體彈永久留場、bullet 碰撞以實際質量入 reduced mass);④computeRotorSpeeds 純函式(P×K×權重分配、總功率守恆);⑤sim state 擴充=WeaponSim{ammoRemaining, lastFireFrame} 入 SavedState v2 與 hash。⭐debug 三連環(磁力測試不動車):(1) collider.translation() 於 attached collider 實測回 parent-relative 非世界座標(Rapier 0.19)→ partWorldPosition 改存 part local center+body 位姿自算;(2) 場地 trimesh 未設 friction=Rapier 預設 0.5、Average 合成 0.275 → 靜摩擦 0.108N 鎖死 0.037N 磁力(驅動力 0.55N 推得動=自走測試沒暴露)→ track collider 同設 ROLLING_FRICTION_APPROX;(3) 摩擦降低連鎖=滑行變遠/姿態微漂——極速鎖斷言改前向分量語意(quat 投影)、斷電斷言改衰減語意。測試 +7:被動加持(質量打折+同衝擊 fatigue 較小、僅及自身)/rotor 單雙轉子權重分配/push Hold 後座/磁力吸引 steel 車(Newton 3rd)/launch 全生命週期(發射→間隔→耗盡→rollback 還原彈藥+重播 bit-exact)——77/77、五驗證全綠。武器幾何遞送(轉子 mesh 接觸傷害)隨真 mesh collider 收斂。
同日落地複審(⭐加持漏洞 1+語意 copy 1+staged 註記 2、測試 +1=77/77):⭐①applyAcidTick 漏套被動加持抗性——spec「fatigue 累積(武器)×= 抗性因子」涵蓋全部耐受度因子族(衝撞/acid/磨耗)、原實作僅衝撞打折 → acid 補 resistFactorX10000(磨耗僅及 tire、weapon 無涉 ✓)+測試(同 tick 下 passive 武器 acid fatigue 較小);②材質表 §8.2 磁源強度舊語意 copy(「applied_energy × K_MAGNET_FORCE」→「kinetic_ratio × declared × K(去 dt)」對齊算式表 §5.1 修後權威);③staged 註記補 2=磁源↔磁源(§5.3 N 極斥吸)隨場地磁源子步收斂為統一結算 pass(現行 per-車獨立執行結構不支援跨車動作彙整——武器↔武器互斥屬同題)+彈體 fatigue 破壞隨 entity 破壞系統收斂。乾淨面——程式參數表 §18 TBD 清零驗證、src 零文檔引用、launch recoil 不重複(Hold 側只 push/actuated、launch 於發射幀)、Hold 耗電已涵蓋發射(不重複扣)、bulletId 遞減唯一=deterministic。五驗證全綠(77/77)。
2026-07-07 ─ 里程碑 3c-2:每幀模擬子系統(動力/技能/熱/損耗;14 顆 K 常數初估落地;測試 70/70 全綠——含 sim state 的 rollback bit-exact)¶
⭐K 常數初估 14 顆(TBD→初估、量綱推導、全標待校準;程式參數表 §18 補值+推導錨句、protocol/physics.ts 同步、TBD 名單縮至武器 4 顆):K_TORQUE_FROM_W(3e-5、0→極速≈2s)/K_SPEED_FROM_W(0.015、極速≈8.4 m/s)/K_DRAIN(1e-6、1100W≈11 分鐘)/K_DRAIN_FROM_J(4e-4、滿 boost≈3% 電量)/K_BOOST·BRAKE·JUMP·SLAM(6.5e-6、滿 boost≈+3 m/s·jump≈0.3m)/K_SWERVE(8e-6)/K_STABILIZE(0.005)/K_CHIP_HEAT(2e-4、殺手鐧節奏錨=滿 boost 連發≈10 次觸及 pc 130°C)/K_BATTERY_SKILL_HEAT(5e-5)/K_MOTOR_HEAT(42000、heat_in 域穩態≈+60°C)/K_BATTERY_PASSIVE(36000、≈+30°C)。順修其他.md §2 K 族清單既有帳目不符(原「初估」清單列了 4 顆實為 TBD 的常數→重列已初估 22 顆+尚無初估 4 顆〔武器子步定值、含 §4/§5 量綱覆核〕)。介面收斂(staged 授權兌現):PartType 上移 interfaces=單一來源(material-params 改 re-export);PartInstance.partType 新增;VehicleSpec 補 motor{torqueRatio,autoInputW}/battery{declaredOutputW,capacityMahInitial}/chipSlots。模組:新 vehicle-sim.ts(計算與施力分離=純函式可測;createVehicleSim 回合初始〔fatigue 0/溫度=ambient/滿電〕+simTick 每幀:駕駛動力〔min(motor,battery)、torque/速度派生、極速鎖、恆按宣告扣電〕→技能〔Event dt=1 / Hold dt、chip spike+單閾值殺手鐧「該次仍正常執行」、電池連帶扣電+直加熱、8 skill 分發(weapon 留武器子步)、chip broken=技能全滅駕駛保留〕→熱模型〔per-part heat_in(motor/battery)+散熱、過熱 broken 無 graceful degradation、k/c null 跳過〕→tire 磨耗〔μ×車重分攤近似〕+applyImpact〔stress=E/(A×K_DEPTH)、超降伏累積、一擊重傷、broken 凍結 1.0〕+applyAcidTick〔deploy zone 接線用〕);deterministic-world 擴充=per-part collider 索引(WorldCollision 含 partIndex)+applyFrameForces(前向駕駛衝量+local 技能衝量 quat 旋轉+每幀角阻尼)+forwardSpeed;引擎層=bindPeer input 路由(一人一車)、衝撞能量=½×reduced mass×v²(g·(m/s)²=mJ 量綱天然閉合、track=∞ 質量)、SavedState v2=[1B ver][4B simLen][dag-cbor sim(vehicleId 排序)][world snapshot]、hash=world+sim 量化合成。物理現實修正:box 近似車體用材質滑動 μ(≈1.0)會鎖死 0.55N 驅動力(實車=滾動阻力)→ collider friction=ROLLING_FRICTION_APPROX(0.05) 固定值、hinge tire 收斂後回歸材質 μ(註記 staged)。測試 8 新:自走加速+極速鎖+耗電/boost ΔV≈3m/s/殺手鐧連發→broken→技能失效駕駛保留/電量耗盡失去一切輸出/motor 升溫趨穩態/tire 磨耗累積/applyImpact 三態+acid 20s broken/rollback 含技能·熱·耗電 sim state 全程 bit-exact+兩引擎含 input 腳本 determinism。踩坑=測試場地牆+小地板:撞牆翻滾後「前向分量」極速鎖失效+飛出地板自由落體→32 m/s(改開闊 40m 地板)。五驗證全綠(70/70)。3c-2b=武器機制(rotor/反作用/磁力+4 顆 K 定值與 §4/§5 量綱覆核)、3c-3=場地物理。
同日落地複審(⭐spec 對指矛盾 1+鏡像 drift 1+測試 2 補、測試 70→72):⭐①physics-engine.md §7「精確式含 /100」與算式表 §3 對指矛盾——算式表權威式 applied_energy = kinetic_ratio × declared × dt 無 /100、且被動加持式(kinetic 100×split 100×30/100=3000=30.00%)反證 kinetic_ratio 值域=0–100 整數直乘 → §7 修為「直乘不除 100、尺度由各 K 常數吸收」(14 顆初估全按直乘域推導、數值自洽);②interfaces.md §3.1 鏡像 drift——code 側 VehicleSpec 已收斂(motor/battery/chipSlots)+PartInstance.partType+PartType 上移、spec 鏡像仍舊殼 → 同步(PartType 單一來源註記入契約)。乾淨面——遊戲機制 :229 明文「無 cooldown timer」=Event 技能無冷卻的實作正確;零文檔引用 0;hash 的 JSON 鍵序=字面量插入序(同版本決定性 ✓);SavedState v2 subarray byteOffset 鏈正確。測試補 2——jump 垂直躍升(fixture chipSlots 調整 boost50/jump30/stabilize20=Σ100 合規)+過熱破壞純函式(abs motor 低閾值 80°C 持續發熱→broken→駕駛歸零)。觀察 2 備查——駕駛耗電實作=actualPower>0 才扣(motor broken 不空放電;spec「永遠按宣告扣」字面歧義、playtest 面);BASE_ANGULAR_DAMPING(0.1) 為引擎調校本地常數(影響模擬、同版本同碼決定性無虞;候補入程式參數表待校準族)。五驗證全綠(72/72)。