open-goal/jak-project

GitHub: open-goal/jak-project

将PS2平台「杰克与达斯特」系列游戏反编译并原生移植到PC的逆向工程项目

Stars: 3244 | Forks: 210

Documentation Badge Linux and Windows Build Codacy Badge Discord

## 请先阅读 有关如何安装和运行游戏的设置指南,您可以观看以下视频:https://youtu.be/K84UUMnkJc4 如有关于项目的问题或需要更多信息,我们有一个 Discord 讨论区:https://discord.gg/VZbXMHXzWv 此外,您可以在项目主页上找到更多文档和**常见问题**的解答:https://opengoal.dev - [项目描述](#project-description) - [当前状态](#current-status) - [方法论](#methodology) - [搭建开发环境](#setting-up-a-development-environment) - [Docker](#docker) - [Linux](#linux) - [Ubuntu (20.04)](#ubuntu-2004) - [Arch](#arch) - [Fedora](#fedora) - [Windows](#windows) - [所需软件](#required-software) - [使用 Visual Studio](#using-visual-studio) - [MacOS](#macos) - [Intel 架构](#intel-based) - [Apple Silicon](#apple-silicon) - [VSCode](#vscode) - [构建与调试](#building-and-debugging) - [构建并运行游戏](#building-and-running-the-game) - [提取资源](#extract-assets) - [构建游戏](#build-the-game) - [运行游戏](#run-the-game) - [将 REPL 连接到游戏](#connecting-the-repl-to-the-game) - [运行游戏(不自动启动)](#running-the-game-without-auto-booting) - [与游戏交互](#interacting-with-the-game) - [技术项目概览](#technical-project-overview) - [`goalc`](#goalc) - [运行编译器](#running-the-compiler) - [`decompiler`](#decompiler) - [运行反编译器](#running-the-decompiler) - [`goal_src/`](#goal_src) - [`game` runtime](#game-runtime) ## 项目描述 本项目旨在将原始的 Jak and Daxter 和 Jak II 移植到 PC 平台。超过 98% 的游戏代码是用 GOAL 编写的,这是一种由 Naughty Dog 开发的定制 Lisp 语言。我们的策略是: - 将原始游戏代码反编译为人类可读的 GOAL 代码 - 开发我们自己的 GOAL 编译器,并将游戏代码重新编译为 x86-64 架构 - 创建一个工具,将游戏资源提取为易于查看或修改的格式 - 创建工具将游戏资源重新打包为我们移植版本使用的格式 我们的目标是: - 使移植版成为 x86-64 上的“原生应用程序”,并具有高性能。它不应是模拟、解释或转译运行的。 - 我们的 GOAL 编译器性能应与未优化的 C 语言相当。 - 尽可能匹配原始游戏和开发中的细节。例如,原始 GOAL 编译器支持在游戏运行时实时修改代码,我们也这样做,即使这仅仅是为了移植游戏并不是必须的。 - 支持修改。应该能够在不破坏其他所有内容的情况下对代码进行编辑。 我们支持 x86-64 架构上的 Linux 和 Windows。 ### 当前状态 Jak 1 已基本可以从头到尾游玩,但仍有一些正在不断修复的小错误。Jak 2 正在开发中。 ![](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/52121bfec9154018.png) ![](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/8bcec0553e154024.png) YouTube 播放列表: https://www.youtube.com/playlist?list=PLWx9T30aAT50cLnCTY1SAbt2TtWQzKfXX ### 方法论 为了辅助反编译,我们构建了一个可以处理 GOAL 代码和解包游戏资源的反编译器。我们手动指定函数类型以及我们认为原始代码中存在类型转换的位置(或感觉合适的位置),直到反编译器成功运行,然后我们通过添加注释和调整格式来清理反编译代码的输出,最后将其保存在 `goal_src` 中。 我们的反编译器专门设计用于处理原始 GOAL 编译器的输出。因此,当给定正确的转换时,它生成的代码通常可以直接输入编译器并完美运行。这作为我们单元测试的一部分持续进行测试。 ## 搭建开发环境 本 README 的其余部分主要面向有兴趣从源代码构建项目的人员,通常是以开发者身份贡献为目的。 如果这不适用于您,且您只想玩游戏,请参阅上方的 [快速入门](#quick-start) 部分 ### Docker 所有三种 Linux 系统都支持使用 Docker。 选择您支持的偏好 Linux 发行版并构建您选择的镜像 ``` docker build -f docker/(Arch|Fedora|Ubuntu)/Dockerfile -t jak . ``` 这将创建一个包含所有必需依赖项并已完成构建的镜像。 ``` docker run -v "$(pwd)"/build:/home/jak/jak-project/build -it jak bash ``` 注意:如果您更改了 `build/` 目录的内容,则需要重新运行 `build` 命令。或者,您可以通过 `docker cp` 获取构建内容。 这会将您的 `build/` 文件夹链接到镜像,以便您可以在外部设备上验证您的构建或进行测试。 Docker 镜像可以链接到您的 IDE(例如 CLion)中,以帮助进行代码嗅探、静态分析、运行测试和持续构建。 遗憾的是,您仍然需要本地机器上的任务运行器(task runner)来运行游戏,或者通过 `Taskfile.yml` 中的命令手动运行游戏。 ### Linux #### Ubuntu (20.04) 安装软件包并初始化仓库: ``` sudo apt install gcc make cmake ninja-build build-essential g++ nasm clang-format libxrandr-dev libxinerama-dev libxcursor-dev libpulse-dev libxi-dev python libgl1-mesa-dev libssl-dev sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin ``` 编译: ``` cmake -B build && cmake --build build -j 8 ``` 运行测试: ``` ./test.sh ``` 注意:我们发现 `clang` 和 `lld` 的编译和链接速度明显快于 `gcc`,生成的代码更快,并且有更好的警告信息。要安装这些: ``` sudo apt install lld clang ``` 并使用以下命令运行 `cmake`(在一个新的构建目录中): ``` cmake -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ .. ``` #### Arch 安装软件包并初始化仓库: ``` sudo pacman -S cmake libpulse base-devel nasm python libx11 libxrandr libxinerama libxcursor libxi yay -S go-task ``` 仅针对 Arch,在其余说明中将 `task` 替换为 `go-task`。 编译: ``` cmake -B build && cmake --build build -j 8 ``` 运行测试: ``` ./test.sh ``` #### Fedora 安装软件包并初始化仓库: ``` sudo dnf install cmake python lld clang nasm libX11-devel libXrandr-devel libXinerama-devel libXcursor-devel libXi-devel pulseaudio-libs-devel mesa-libGL-devel sudo sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin ``` 使用 `clang` 编译: ``` cmake -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -B build cmake --build build -j$(nproc) ``` 运行测试: ``` ./test.sh ``` ### Windows #### 所需软件 我们在 Windows 上主要使用 Visual Studio 进行 C++ 开发。从[这里](https://visualstudio.microsoft.com/vs/)下载最新的社区版。在撰写本文时,这是 Visual Studio 2022。 您需要 `使用 C++ 的桌面开发` 工作负载。可以在安装过程中选择,也可以之后通过 `Visual Studio Installer` 修改 Visual Studio 安装来选择。 在 Windows 上,建议使用包管理器,我们使用 Scoop。按照[这里](https://scoop.sh/)主页底部的步骤进行安装。 安装 Scoop 后,运行以下命令: ``` scoop install git llvm nasm python task ``` #### 使用 Visual Studio 在您选择的文件夹中运行以下命令来克隆仓库。 ``` git clone https://github.com/open-goal/jak-project.git ``` 这将创建一个 `jak-project` 文件夹,通过 Visual Studio 作为 CMake 项目打开该项目。 ![](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/43201662c7154025.png) 然后将整个项目构建为 `Windows Release (clang)`。您也可以按 Ctrl+Shift+B 作为全部生成的热键。我们目前在 Windows 上更倾向于使用 `clang` 而不是 `msvc`,尽管 `msvc` 应该也能工作! ![](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/11970ab039154042.png) ![](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/2022572c0b154044.png) ### MacOS 确保您已安装 Xcode 命令行工具(这会安装诸如 Apple Clang 之类的工具)。如果没有,您可以运行以下命令: ``` xcode-select --install ``` 在 Apple Silicon 上,还必须安装 Rosetta 2: ``` softwareupdate --install-rosetta ``` #### 为 x86_64 构建 ``` brew install cmake nasm ninja go-task clang-format cmake -B build --preset=Release-macos-x86_64-clang cmake --build build --parallel $((`sysctl -n hw.logicalcpu`)) ``` #### 为 ARM64 构建(实验性,不提供支持) ``` brew install cmake ninja go-task clang-format cmake -B build --preset=Release-macos-arm64-clang cmake --build build --parallel $((`sysctl -n hw.logicalcpu`)) ``` 您可能需要将 MacOS SDK 添加到您的 `LIBRARY_PATH`: - `export LIBRARY_PATH="$LIBRARY_PATH:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib"` ### VSCode 如果您不想或无法使用 Visual Studio 来处理 C++ 项目,VSCode 是一个不错的替代方案。 推荐使用 [推荐](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd) `clangd` 扩展,并且需要 `clangd` 位于您的 `$PATH` 中。如果您可以在终端中成功运行 `clangd`,那么您应该就准备就绪了。 一旦您第一次生成 CMake,clangd LSP 就应该能够索引项目并为您提供智能感知。 #### 构建与调试 TODO - 考虑贡献文档 :) ### 构建并运行游戏 获得一个可运行的游戏涉及 4 个步骤: 1. 构建 C++ 工具(按照上方的入门步骤操作,针对您的平台) 2. 从游戏中提取资源 3. 构建游戏 4. 运行游戏 #### 提取资源 首先,设置您的配置,以便以下脚本知道您使用的是哪个游戏以及哪个版本。对于黑标版本的游戏,在终端中运行以下命令: ``` task set-game-jak1 task set-decomp-ntscv1 ``` 对于其他版本的游戏,您需要使用不同的 `-set-decomp-` 命令。以下是 PAL 版本的示例: ``` task set-game-jak1 task set-decomp-pal ``` 第一步是将您的 ISO 文件内容提取到 `iso_data/` 文件夹中。对于 Jak 1,这是 `iso_data/jak1`。 完成后,在 `jak-project` 文件夹中打开终端并运行以下命令: ``` task extract ``` #### 构建游戏 下一步是构建游戏本身。为此,在同一个终端中运行以下命令: ``` task repl ``` 您将看到如下提示: ``` _____ _____ _____ _____ __ | |___ ___ ___| __| | _ | | | | | . | -_| | | | | | | |__ |_____| _|___|_|_|_____|_____|__|__|_____| |_| Welcome to OpenGOAL 0.8! Run (repl-help) for help with common commands and REPL usage. Run (lt) to connect to the local target. g > ``` 运行以下命令来构建游戏: ``` g > (mi) ``` #### 运行游戏 最后,游戏可以运行了。从 `jak-project` 目录打开第二个终端并运行以下命令: ``` task boot-game ``` 如果一切正确完成,游戏应该会自动启动。 ##### 将 REPL 连接到游戏 将 REPL 连接到游戏允许您在游戏运行时检查和修改代码或数据。 为此,在 REPL 中成功执行 `(mi)` 后,运行以下命令: ``` g > (lt) ``` 如果成功,您的提示符应变为: ``` gc> ``` 例如,运行以下命令将打印出关于 Jak 的一些基本信息: ``` gc> *target* ``` ##### 运行游戏(不自动启动) 您也可以在不启动的情况下启动游戏。为此,在一个终端中运行以下命令 ``` task run-game ``` 然后在您的 REPL 中运行以下命令(在成功执行 `(mi)` 之后): ``` g > (lt) [Listener] Socket connected established! (took 0 tries). Waiting for version... Got version 0.8 OK! [Debugger] Context: valid = true, s7 = 0x147d24, base = 0x2123000000, tid = 2438049 gc> (lg) 10836466 #xa559f2 0.0000 ("game" "kernel") gc> (test-play) (play :use-vis #t :init-game #f) has been called! 0 #x0 0.0000 0 gc> ``` #### 与游戏交互 在图形窗口中,您可以使用句点键调出调试菜单。控制器也可以使用,映射与原始游戏相同。 查看 `goal_src` 下的 `pc_debug`、`examples` 和 `pc` 文件夹,了解我们编写的一些 GOAL 代码示例。未被引擎自动加载的调试文件包含有关如何运行它们的说明。 ## 技术项目概览 该项目有四个主要组件。 1. `goalc` - 针对 x86-64 的 GOAL 编译器 2. `decompiler` - 我们的反编译器 3. `goal_src/` - 包含所有 OpenGOAL / GOOS 代码的文件夹 4. `game` - 即用 C++ 编写的 runtime 让我们分解每个组件。 ### `goalc` 我们的 GOAL 实现称为 OpenGOAL。 所有编译器源代码都位于 `goalc/` 中。编译器通过提示符控制,可用于输入命令进行编译、连接到正在运行的 GOAL 程序进行交互、运行 OpenGOAL 调试器,或者如果您连接到正在运行的 GOAL 程序,可用作 REPL 交互式运行代码。除了编译代码文件外,编译器还具有打包和构建数据文件的功能。 #### 运行编译器 **环境无关** 如果您已按照上方的建议安装了 `task`,则可以使用 `task repl` 运行编译器 **Linux** 要在 Linux 上运行编译器,有一个脚本 `scripts/shell/gc.sh`。 **Windows** 在 Windows 上,有一个 `scripts/batch/gc.bat` 脚本和一个 `scripts/batch/gc-no-lt.bat` 脚本,后者不会尝试自动附加到正在运行的目标。 ### `decompiler` 项目的第二个组件是反编译器。 反编译器将输出旨在供人类检查的代码和其他数据到 `decompiler_out` 文件夹中。此文件夹中的文件不会被编译器使用。 #### 运行反编译器 您必须拥有 PS2 游戏的副本,并将 DVD 中的所有文件放置在 `iso_data` 文件夹中对应游戏的文件夹内(Jak 1 黑标版为 `jak1` 等),如下图所示: ![](https://raw.githubusercontent.com/open-goal/jak-project/master/docs/img/iso_data-help.png) 反编译器将把资源提取到 `assets` 文件夹。这些资源将在构建移植版时被编译器使用,您可能希望在运行一次后关闭资源提取。 **环境无关** 如果您已按照上方的建议安装了 `task`,则可以使用 `task decomp` 运行编译器 **Linux** 要运行,您可以使用 `scripts/shell/decomp.sh` 来运行反编译器 **Windows** 要运行,您可以使用 `scripts/shell/decomp-jak1.bat` 来运行反编译器 ### `goal_src/` 用 OpenGOAL 编写的游戏源代码位于 `goal_src` 中。所有 GOAL 和 GOOS 代码都应在此文件夹中。 ### `game` 最后一个组件是“runtime”,位于 `game` 中。这是游戏中用 C++ 编写的部分。 在移植版中,这包括: - “C 内核”,其中包含 GOAL 链接器和一些低级 GOAL 语言功能。GOAL 有一种完全自定义的动态链接目标文件格式,因此为了加载第一个 GOAL 代码,您需要一个用 C++ 编写的链接器。一些用于内存分配、与 I/O 处理器通信、符号表、字符串和类型系统的低级函数也在 C 中实现,因为这些是链接器所需的。它还监听来自编译器的传入消息,并将它们传递给正在运行的游戏。这还会通过初始化 PS2 硬件、分配 GOAL 堆、从 DVD 加载 GOAL 内核并执行内核调度程序函数来初始化游戏。这位于 `game/kernel` 文件夹中。这应该尽可能接近游戏,所有差异都应通过注释注明。 - Sony 标准库的实现。GOAL 代码可以调用 C 库函数,Naughty Dog 使用一些 Sony 库函数来访问文件、内存卡、控制器,并与独立的 I/O 处理器通信。库函数位于 `game/sce`。特定于 PC 移植版的库功能实现位于 `game/system`。 - I/O 处理器驱动程序 OVERLORD。PS2 有一个独立的 CPU,称为 I/O 处理器 (IOP),它直接连接到 DVD 驱动器硬件和声音硬件。Naughty Dog 为 IOP 创建了一个自定义驱动程序,用于处理从 DVD 流式传输的数据。它比我最初预期的要复杂得多。它位于 `game/overlord`。与 C 内核一样,我们尽量使其尽可能接近实际游戏。 - 声音代码。Naughty Dog 使用了一个名为 `989SND` 的第三方声音库。该库的代码及其接口位于 `game/sound`。 - PC 特定的图形代码。我们有一个功能正常的 OpenGL 渲染器和上下文,可以创建游戏窗口并显示图形。然而,游戏使用的特定渲染器大部分已实现。除了后处理效果外,游戏中的所有内容都已渲染。这位于 `game/graphics`。虽然会采取许多自由度来实现这一点,但最终结果应该非常接近实际游戏。 - 移植版以某种方式使用的额外资源,位于 `game/assets`。其中包括额外的文本文件、图标等。
标签:Bash脚本, C++, DNS解析, Jak and Daxter, OpenGOAL, PlayStation, 云资产清单, 动作冒险游戏, 开源项目, 数据擦除, 游戏复刻, 游戏开发, 游戏引擎, 编程语言, 编译器, 语言重构, 请求拦截, 软件架构, 逆向工具, 逆向工程