Repo ↗ · 原始 README ↗ · 文件包(Markdown/授權)

封面參考(原作): Kingdom Hearts II Final Mix · 原作遊戲截圖,由 IGDB 提供。圖片版權屬原權利人,供辨識原作使用,不代表此重寫/模組專案的實際畫面。

來源維護者: steferro78-HIV · 版本: 17f363b8a594 · 整理日期: 2026-10-12

文件授權: MIT · LICENSE · 本文形式: README 翻譯

下文為來源 README 的繁中翻譯,由 Kirikirin 使用 AI 輔助整理;功能、完成度與測試結果均為原作者描述,本站未逐項實機驗證。圖片改為來源連結,指令與技術識別保留原文。


KH2 戰鬥套件

Kingdom Hearts II Final Mix(Sora,基礎型態)的戰鬥規則,重建為一個小型
Rust 函式庫,可讓你嵌入另一個遊戲中。

Leggi in italiano: README.it.md.

  • 不包含任何遊戲檔案。 此函式庫會讀取一份「目錄」,該目錄由你使用 tools/kh2 中的腳本從你自己的遊戲副本產生。
  • 沒有圖形、沒有相依性。 此函式庫只決定會發生什麼事:哪個攻擊開始、按鍵按下何時算數、跳躍跳多高。你的遊戲負責繪製。
  • 已與真實遊戲比對。 這些規則已對照 KH2 的逐格錄影重播驗證:請見還原度如何。

這是一個非官方粉絲專案。與 Square Enix 或 Disney 無隸屬關係,亦未獲其背書。

內容物

資料夾 內容
src/kh2-combat-core 函式庫(Rust,無相依性)。這是你整合的部分。
src/first-combo 使用此函式庫的最小程式:在終端機中印出一段連段。
src/arena 以 Bevy 製作的小型測試競技場:一個使用此函式庫的遊戲實例。
tools/kh2 Python 腳本,會讀取你的 KH2 副本並寫出目錄(以及,供競技場使用的 Sora 模型與動畫)。
docs/SPEC-FUNZIONALE.md、docs/INTERFACCIA.md 此函式庫撰寫所依據的兩份文件(義大利文):戰鬥的行為方式,以及函式庫、目錄檔案與錄影的結構。
PROVENANCE.md 此函式庫的程式碼是如何產生的:依據那兩份文件進行的淨室重實作。

函式庫涵蓋的範圍

  • 地面與空中連段:哪個攻擊開始取決於目標的距離、高度與角度、周圍的敵人、你是否在空中,以及已裝備的能力。這是 KH2 自身的選擇表,不是固定順序。
  • 按鍵何時算數:連段視窗、「你的攻擊必須碰到東西」規則、被忽略的按鍵。
  • 連段長度與終結技:Combo Plus、Air Combo Plus、Negative Combo、Finishing Plus、Combo Master、Berserk Charge。
  • Sora 基礎招式組的每一個攻擊能力:Slide Dash、Flash Step、Slapshot、Dodge Slash、Vicinity Break、Guard Break、Explosion、Finishing Leap、Upper Slash、Aerial Sweep、Aerial Dive、Aerial Spiral、Horizontal Slash、Aerial Finish、Magnet Burst。
  • 空中移動:可變高度跳躍、每個空中攻擊的小跳、落下、著地,以及空中攻擊的前衝。
  • 防禦:Guard、成功格擋、Counterguard、武器被敵人防禦彈開、被擊飛、Retaliating Slash、Aerial Recovery、「無法被擊中」的影格。

未涵蓋: Dodge Roll、魔法、Drive Forms、Limits、召喚、反應指令(函式庫只會告訴你何時允許使用)、敵人行為、傷害計算(公式在規格書中描述,目錄帶有每一擊的威力與擊退)、等級與選單。

需求

  • Rust 1.85 或更新版本(https://rustup.rs).
  • Python 3.10 或更新版本(僅標準函式庫),用於建置目錄。
  • 你自己的 KINGDOM HEARTS -HD 1.5+2.5 ReMIX- PC 版副本。已以 Steam 版本、組建 1.0.0.10 測試。
  • OpenKH(https://github.com/OpenKH/OpenKh),,用作解開遊戲封裝檔的程式。
  • Windows,因為遊戲與 OpenKH 工具都是 Windows 程式。函式庫本身可在任何 Rust 可建置的平台上建置。

快速開始

  1. 告訴腳本 OpenKH 在哪裡(包含 OpenKh.Command.IdxImg.exe 的資料夾)。
    如果遊戲不在 Steam 的預設資料夾中,也將 KH2_GAME_DIR 設為遊戲資料夾
    (包含 Image 的那個)。

    $env:OPENKH_DIR = "D:\tools\OpenKH"
    
  2. 建置目錄。遊戲安裝只會被讀取。所有內容都會寫入
    extracted/,Git 會忽略它:絕不要提交它。

    python tools/kh2/build_catalog.py
    
  3. 執行測試。

    cargo test --manifest-path src/Cargo.toml
    
  4. 在終端機中看它運作:一個戰鬥者、一個靜止不動的敵人,以及一個每當連段能繼續時就按下攻擊的玩家。它會逐 tick 印出函式庫的決定(原始碼在 src/first-combo/src/main.rs,是開始閱讀的好地方)。

    cargo run --manifest-path src/Cargo.toml -p first-combo
    
  5. 選用:在競技場中試試看。第一個指令會準備 Sora 的模型與動畫
    (它需要 OpenKH 的 OpenKh.Research.Kh2Anim.exe);沒有它,競技場仍會啟動。

    python tools/kh2/prepare_arena.py
    
    cargo run --manifest-path src/Cargo.toml -p arena
    

    按鍵:WASD 移動、Space 攻擊、K 跳躍(按住可跳更高)、E 特殊
    攻擊(方形)、Q 防禦、X 假人打你、方向鍵移動假人、PgUp/PgDn
    升高與降低它、N 第二個假人、F1/F2 選擇能力與 F3 切換它、
    1/2/3 遊戲速度。遊戲手把也可用。

整合到你的遊戲中

誰負責什麼

函式庫 你的遊戲
選擇攻擊、執行其影格、開啟與關閉命中與連段視窗 讀取按鍵
決定角色的高度(跳躍、小跳、落下) 在地面上移動角色,並告訴函式庫地板在哪裡
逐 tick 提供空中攻擊的前推力 將該推力加到位置上
告訴你正在播放哪個 KH2 動畫以及在第幾格 繪製動畫
告訴你武器何時能造成傷害,以及以何種威力 檢查武器是否真的碰到敵人,並套用傷害
執行格擋、彈開、擊退與回復 告訴函式庫敵人攻擊何時到來或敵人何時防禦

時間以 1/60 秒的 tick 計算:每秒精確呼叫 tick 60 次。
距離以 KH2 單位計算(Sora 每 tick 跑 8 單位,完整跳躍高度為 185 單位;
競技場將 100 單位繪製為 1 公尺)。位置為 [x, height, z],高度
向上增長。

最小範例

use std::sync::Arc;

use kh2_combat_core::catalog::Catalog;
use kh2_combat_core::combo::Event;
use kh2_combat_core::fighter::{Controls, Fighter};
use kh2_combat_core::rules::{Body, Loadout, Scene};

// Once, at start-up.
let catalog = Arc::new(Catalog::load(&Catalog::default_path()).expect("build the catalog first"));
let mut loadout = Loadout::default();
loadout.equip(catalog.ability_number("Slide_Dash").unwrap());
loadout.combo_plus = 1;
let mut sora = Fighter::new(catalog, loadout);

// 60 times per second.
let enemy = Body {
    position: [enemy_x, enemy_aim_height, enemy_z], // the point to aim at
    radius: 40.0,                                   // distances are measured from its edge
    size: 30.0,                                     // widens the height limits of the moves
};
let nearby = [enemy];
let events = sora.tick(Controls {
    attack_pressed,          // true only on the tick the button goes down
    command: None,           // Some(entry id) for Guard and the other "square" moves
    jump_pressed,
    jump_held,
    hit_landed,              // your collision check: the weapon touched an enemy this tick
    busy: false,
    berserk: false,
    floor: 0.0,              // height of the ground under the character
    scene: Scene {
        fighter: [player_x, 0.0, player_z],   // the library fills in the height
        facing: [facing_x, facing_z],         // unit vector
        main_target: Some(enemy),             // the locked-on (or chosen) enemy
        nearby: &nearby,                      // every enemy around, main target included
        ledge_ahead: false,
    },
});

// Apply what the library decided.
let push = sora.slide();
player_x += push[0];
player_z += push[1];
let player_height = sora.height();
match sora.shown() {
    Some((motion, frame)) => { /* draw KH2 animation number `motion` at `frame` (from 1) */ }
    None => { /* idle or running: your choice */ }
}
for event in events {
    match event {
        Event::MoveStarted { motion, .. } => { /* an attack started */ }
        Event::HitWindowOpened { power, .. } => { /* the weapon can hurt from now */ }
        Event::HitWindowClosed => {}
        _ => {}
    }
}

src/first-combo/src/main.rs 就是這個迴圈在一個可執行程式中的版本;競技場
(src/arena/src/main.rs,函式 simulate)就是同樣的迴圈在真實遊戲中。

你的遊戲必須告訴函式庫的事

  • 有命中落地。 當 sora.combo.hit_power() 為 Some(power) 時,檢查武器
    是否碰到敵人。如果碰到,在該 tick 傳入 hit_landed: true。沒有它,連段
    就不會繼續,完全如同 KH2。sora.combo.hit_attack() 會給出命中的編號:
    catalog.attack(number) 帶有其威力、擊退與其他數值。
  • 敵人攻擊到來。 如果 sora.combo.guarding() 為 true,呼叫 sora.guarded():該
    打擊會被擋下。如果它落在真正的防禦上,格擋會開始,從那裡攻擊
    按鈕會給出 Counterguard;有些招式在攻擊時同時防禦,然後該招式就單純繼續。如果
    sora.combo.unhittable() 為 true,該攻擊會落空。否則呼叫
    sora.knocked(reaction_motion, rise):連段中斷、播放受傷動畫,且
    當 rise 大於零時,角色會被擊飛到空中(接著 Retaliating
    Slash 與 Aerial Recovery 就成為可能)。
  • 敵人防禦了你的武器。 呼叫 sora.deflected()。

會叫出特定招式的按鈕

有些招式不是來自攻擊按鈕:你將其項目編號傳入
Controls::command。在 Sora 的目錄中它們是:Guard 11、Upper Slash 12、Finishing Leap 37、
Horizontal Slash 38。Counterguard(39)與 Retaliating Slash(40)會在情況正確時由攻擊按鈕自動叫出。指令只有在能力已裝備且時機正確時才會生效;否則你會得到 Event::PressIgnored。

能力

Loadout 保存已裝備的內容。會新增招式的能力有一個編號:
loadout.equip(catalog.ability_number("Flash_Step").unwrap())。名稱就是目錄中寫的那些(以 ability 開頭的行)。會改變規則的能力是欄位:
combo_plus、air_combo_plus、negative_combo、finishing_plus、combo_master、
berserk_charge。Aerial Recovery 是 rules::AERIAL_RECOVERY。你可以隨時透過 sora.combo.loadout 變更配置。

動畫

函式庫以 KH2 動畫編號溝通(例如 151 是第一個地面攻擊,3
是跳躍,4 是落下)。它不包含動畫。要看到 Sora 動起來,你必須
將它們從你的遊戲副本轉換成你的引擎格式:腳本
tools/kh2/prepare_arena.py 與 tools/kh2/export_arena_poses.py 展示了一種方式(它們為每個骨骼每 tick 寫出
一個姿勢,供競技場播放)。

從其他語言使用

此函式庫是純 Rust,無相依性。要從 C、C++、C# 或腳本語言呼叫它,將 Fighter 包在一個小型 cdylib crate 中,對外暴露 extern "C" 函式
(create、tick、read state)。該包裝並未包含在內。

程式碼是如何撰寫的

src/kh2-combat-core 中的函式庫是一份淨室重實作。較早的版本是在研究遊戲時
撰寫的。在發布之前,行為被寫成一份
功能規格書(docs/SPEC-FUNZIONALE.md)與一份介面描述
(docs/INTERFACCIA.md),然後此函式庫從零開始、僅依據那兩份
文件與資料重新撰寫,由一個無法存取較早
程式碼或研究筆記的獨立工作階段完成。PROVENANCE.md 精確說明了該工作階段擁有
與不擁有什麼,以及該方法保證與不保證什麼。它提到的
工作記錄與問答檔案由專案擁有者私下保存,因為它們
包含個人姓名:它們不屬於此儲存庫。在重寫之後,函式庫資料夾內唯一
做的變更是其 Cargo.toml 中的兩行套件中介資料
(license 與 publish):設定,不是程式碼。那兩份文件在此完全依照該工作階段收到它們的樣子呈現(它們提到一個
data\ 資料夾:那是重寫的工作資料夾,內含目錄與錄影)。

tools/kh2 中的範例、競技場與腳本不屬於重寫的一部分:它們只
使用函式庫的公開介面或讀取遊戲的資料檔案。

還原度如何

這些規則來自三個來源:遊戲自身的資料表(由腳本從你的
副本讀取)、真實遊戲的逐格錄影(「遙測」),以及一份遊戲行為的書面描述
(docs/SPEC-FUNZIONALE.md)。測試會將錄影透過
函式庫重播並比較。

項目 如何檢查 結果
地面與空中的連段規則(哪些按鍵算數、下一個攻擊何時開始、終結技何時出現) 重播 128 段錄製的連段 0 差異
跳躍與落下 重播 45 次錄製的跳躍,逐 tick 比較高度 36 次在 2 單位內,42 次在 5 單位內(其餘撞到階梯或敵人)
空中攻擊的前衝 30 次錄製的空中攻擊,目標在遠處 28 次行進距離在 8% 內相同
每個招式與能力的攻擊選擇 Sora 目錄的每個項目都在其自身情況中測試 通過;在真實遊戲中僅對無能力的招式檢查過
Combo Plus、Negative Combo、Finishing Plus 的效果 取自社群文件 未在遊戲中檢查
Guard、格擋、Counterguard、Retaliating Slash、Aerial Recovery 時序來自遊戲資料;規則來自規格書 在競技場中試過,未對照錄影檢查
朝近距離目標的前衝速度;地面對空攻擊的上升 以少量樣本擬合 近似

錄影並未包含在內(它們來自某位玩家的遊戲),所以兩個重播測試會
自行跳過並說明。所有測量所用的 Steam 組建為 1.0.0.10。

目錄檔案

一個純文字檔,每行一項,由 tools/kh2/build_catalog.py 寫入
extracted/kh2/catalog/sora_base.catalog:

  • entry ... 選擇表每招一行:何時可選(距離、
    高度、角度、地面或空中、所需能力)以及播放哪個動畫;
  • motion ... 一個動畫及其以 tick 為單位的長度;
  • span ... 與 point ... 一個動畫的事件:命中區域、「允許連段」、
    「允許終結技」、「無法被擊中」等等;
  • attack ... 一次命中的數值:威力、擊退等等;
  • ability ... 一個能力的編號與名稱。

Catalog::load(path) 讀取它;Catalog::default_path() 指向腳本寫入它的位置。型錄包含遊戲資料:將它排除在任何儲存庫之外。

測試

cargo test --manifest-path src/Cargo.toml
  • 模組內部的測試與 tests/interfaccia.rs 使用小型自製型錄:它們
    在任何地方都能執行。
  • tests/catalogo_vero.rs 使用你的真實型錄:在你建置它之前會跳過自身。
  • tests/registrazioni.rs 從 logs/ 資料夾重播遊戲錄影:當沒有錄影時
    會跳過自身。

關於語言的說明

程式碼註解、測試名稱與兩份文件使用義大利文;程式碼中的名稱與
範例使用英文。

法律

  • 此儲存庫包含沒有遊戲檔案、沒有反編譯程式碼,也沒有擷取出的資料。你
    需要自己合法持有的遊戲副本才能產生型錄。
  • 不要發布 extracted/ 資料夾或任何由遊戲產生的內容。
  • Kingdom Hearts 是 Disney 與 Square Enix 的商標。本專案為非官方專案。

致謝

請見 CREDITS.md。

授權條款

MIT,請見 LICENSE。它涵蓋此儲存庫的程式碼與文件,不涵蓋
遊戲或任何由遊戲產生的內容。


授權與來源聲明

原始 README 與翻譯沿用 MIT 授權;本次修改為繁中翻譯、連結與排版調整。可修改的 Markdown、原始 README、LICENSE 與 NOTICE 收錄於頂部文件包。原作遊戲內容與商標不因此獲得授權。

LICENSE

MIT License

Copyright (c) 2026 steferro78

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.