# Paleblood *Paleblood is a decompilation of Bloodborne with its own runtime: the game's code rewritten as readable C++, one verified function at a time.* The game doesn't run on Paleblood yet: 21 of 157757 functions are verified (0.01%). On [our own runtime](runtime/) the executable's boot gets as far as `scePthreadAttrGetaffinity` (libkernel, called by libc.elf), with 247 of 686 system imports implemented. **[Start here](https://github.com/Yharnam-Hunters/Paleblood/issues/31)** · **[Documentation](https://yharnam-hunters.github.io/byrgenwerth-site/)** · [Discussions](https://github.com/Yharnam-Hunters/Paleblood/discussions) · [Contributing](CONTRIBUTING.md) | | Functions | Bytes | |---|---:|---:| | Target (Ghidra export) | 157757 | 42487347 | | Replaced | 31 (0.02%) | 15353 (0.04%) | | Edge-verified | 31 (0.02%) | 15353 (0.04%) | | Verified | 21 (0.01%) | 14010 (0.03%) | Each row includes the next: verified functions are also edge-verified and replaced. | Runtime | | |---|---| | System imports implemented | 247 of 686 (36.01%): 219 by the game's own modules, 28 by the runtime | | Other imports | 2 registered fail-loud diagnostics, 437 unbound | | Furthest boot milestone | loaded (0 of 8) | | Boot stops at | `scePthreadAttrGetaffinity` (libkernel, called by libc.elf) | Generated by `tools/progress.py --update-readme` from `symbols/`. Do not edit. ![tools/verify.py proving the frame-pacing replacement against the original, stock and with the 60 FPS patch applied](docs/assets/verify.gif) Paleblood rewrites the code of Bloodborne's PS4 executable as readable C++, function by function, and builds its own runtime for that code to run on. It is a **functional** decompilation: a replacement does not have to compile to the same bytes, it has to *behave* exactly like the original, and every one is proved to, against the original itself. It is made by people who love this game and want it to outlive the hardware it was made for. ## The goal **A complete source port of Bloodborne for the PC.** When Paleblood is finished: - every function of the game's 1.09 executable has been rewritten as readable C++, and each one has been proved to behave exactly like the original; - the game runs natively on a PC on Paleblood's own runtime: no PS4, no emulator, and no original executable. You still bring your own copy of the game, for its data; - because it is source, the game can be read, understood, preserved, fixed and modded like any other program, at any frame rate and resolution. Two tracks get there, side by side: - **Decompilation:** functions rewritten as readable C++ and proved against the original in the verification harness, on recorded and generated inputs. Nothing waits for the game to run. - **Runtime** (`runtime/`): our own loader (done; the verification harness maps the executable with it), then, in order, generic input capture, kernel, threads and memory, files, input, audio, video out, and GNM and shaders, the largest part. Graphics are rebuilt at the engine's own level, by replacing the game's graphics layer with our Vulkan code, not by emulating the PS4's GPU. Written clean-room: public documentation and our own reverse engineering only. Paleblood's own runtime does not yet run the full game. The current native run path still uses an external scaffold through the documented host interface; keep it until the project-owned runtime can replace that path and pass the same run checks. ## Where it stands - **The game-run scaffold is still active.** Full game runs use the external scaffold documented in `third_party/README.md`; it supplies the host and graphics layers while Paleblood's runtime grows. Recorded inputs remain usable by the independent verification harness. - **Our runtime:** the loader maps the executable and the game's own C library and file system modules; the boot runs the executable's entry and the C library's start-up and stops at the first system function not written yet (the status line above says which). - The **frame loop's code** is decompiled: the clock, the frame limiter, the per-frame step and the frame pacing object are replaced and verified, plus functions in the event, kernel, input, AI, character, physics and render layers. - **`BB_TARGET_FPS=30|60|uncapped`** does in code what the community frame-rate patches do with byte edits, and each part is checked against the patch it replaces. - What happens next is in [STATUS.md](STATUS.md) and the queue in [NEXT.md](NEXT.md). ## How it works 1. **Map the original.** Our loader ([`runtime/loader.c`](runtime/loader.c)) maps the unmodified executable from your own dump: segments, relocations, and every system import bound. 2. **Rewrite a function.** A replacement in `game//`, readable ([STYLE.md](STYLE.md)) and faithful to the original; [`game/hooks.csv`](game/hooks.csv) registers it. 3. **Prove it.** [`tools/verify.py`](docs/VERIFY.md) runs the original machine code and the replacement side by side on recorded and generated cases and compares return values, registers, every byte written and every library call. Deliberately wrong versions must fail. Options that replace a community patch are verified against the original *with that patch applied*. 4. **Review it.** An independent reviewer checks the verification and the readability before a function counts as verified (CONTRIBUTING.md, "Definition of done"). 5. **Boot further.** The runtime track implements the system functions the executable needs, measured by how far its boot gets ([`runtime/boot.c`](runtime/boot.c), `tools/boot.py`). Supporting tools: call-counting probes that show which original functions a run reaches (`runtime/probe.c`, `tools/probe_list.py`), a map from community patches to the functions they edit (`tools/patch_overlap.py`), relocated-pointer lookup for functions reached through vtables (`tools/reloc_refs.py`), and Ghidra scripts for drafts and names (`tools/ghidra/`). ## Options | Variable | Effect | |---|---| | `BB_TARGET_FPS=30`, `60`, `uncapped` | Frame rate target, as the community "30 FPS++", "60 FPS++" and "Uncap FPS++" patches. Unset: the original behaviour, exactly. | | `BB_LIMITER_WAIT=sleep` | The frame limiter sleeps instead of spinning while it waits (the game carries this wait but never selects it). | ## Getting started You need Linux and a dump of your own copy of the game from your own PS4 (see Legal below). ``` git clone https://github.com/Yharnam-Hunters/Paleblood.git cd Paleblood cmake -S . -B build && cmake --build build -j && ctest --test-dir build --output-on-failure tools/install_hooks.sh ``` [docs/ONBOARDING.md](docs/ONBOARDING.md) goes from your own dump to your first pull request: preparing the dump (`tools/prepare_dump.sh`), Ghidra with the GhidraOrbis loader ([docs/GHIDRA.md](docs/GHIDRA.md)), the verification harness and a first verified function. [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) explains the pieces. ## Contributing One function or cluster per pull request, each verified with `tools/verify.py`, readable ([STYLE.md](STYLE.md)) and independently reviewed; runtime work is claimable per system call group (issues labelled `runtime`). Every pull request carries a session report (`tools/session_report.py`): what was named, replaced and verified, the verify results, and the findings and open questions. CI checks it, along with the build, the tests and the no-game-data rule. **Everyone is welcome:** fork the repository, pick a good first issue or a target from [NEXT.md](NEXT.md), and read [CONTRIBUTING.md](CONTRIBUTING.md) first. ## Documentation - **[The documentation site](https://yharnam-hunters.github.io/byrgenwerth-site/)**: how each system works, the devlog, the progress dashboard and the address map. It is also written as a place to learn how a console game works and how it is reverse engineered and proved correct; no console or game files needed to read it. - [`docs/systems/`](docs/systems/): one page per game system (generated; changes go through issues and pull requests). - [QUIRKS.md](QUIRKS.md): traps in Ghidra, the PS4 executable and the ABI. - [docs/VERIFY.md](docs/VERIFY.md): how replacements are proved, cases, captures, probes. ## Layout | Path | What | |---|---| | `game//` | Replacement code, one directory per game system, with its case generators. | | `game/hooks.csv` | Hook registry: original address to replacement. | | `game/routes/` | Pad routes for unattended game runs through the current host scaffold. | | `runtime/` | The generic layer: hooks, capture, probes. Nothing specific to this game. | | `symbols/` | `functions.csv` (what we track) and `ghidra_functions.csv` (every function, the denominator). | | Function intelligence | [`docs/FUNCTION_CATALOG.md`](docs/FUNCTION_CATALOG.md): local catalog, dependency evidence, ranking, and CLI. | | `tools/` | Verification harness, boot harness, progress, validators, Ghidra scripts, hooks. | | `third_party/bbport/` | Active external run scaffold; retained until a verified project-owned replacement is available. See its license and integration notes in `third_party/README.md`. | | `docs/` | Onboarding, Ghidra setup, architecture, verification, system pages. | ## Target CUSA03173 (EU), update v1.09 merged over the base game. Hashes of the executables converted from SELF to ELF (`target.sha256`); addresses in `symbols/` are PS4 virtual addresses (Ghidra image base `0x400000`, the same as the community patches). See [QUIRKS.md](QUIRKS.md). ``` ca8813862d7b1345a6791b7d88cc1d383ede2a6bbc944f39dd3c0e0e3ad9e285 eboot.elf 6552d61af5258817f434c00f759e194c5d97ac97cfc7ce11b1f23aec11f94d0a libc.elf 8def93e0cd3224619d3d51ddfda8b3dd745e6707d1398fd399d5f04199a7caab libSceFace.elf 16369566417f7bacd34ebd75f8cffb586563da3e2c40fe8880c60d76718e4833 libSceFios2.elf 6ec2b7bd0cb1dcfe491f3981301c6f30836e34d06e97a1aaaa609580dc2a899a libSceHand.elf 3f303ae1bd114380729987698b5aa4cfcfeb11d2dc6c9d09f5d6ae9baa53ce18 libSceHeadTracker.elf b653f26abcf0fd185b4110a6aacc123f7e2e8c0d085f8e5ba1698123213b6659 libSceS3DConversion.elf a85c286a110f406682dafc97819318eedc9aa1591b79465f1ef9c1929655de8c libSceSmart.elf ``` ## Legal - **No game files, ever.** This repository contains no code, assets, binaries, decompiler output or extracted data from the game, and never will. What it holds is newly written source, tools and documentation. `tools/check_no_game_data.py` runs in the pre-commit hook and in CI and rejects anything that looks like game data. - **Your own console, your own copy.** To build, run or verify anything you need Bloodborne (CUSA03173, EU) with the 1.09 update, dumped from your own PS4. The project does not provide or point to game files, pkgs, firmware, keys or decryption tools, and requests for or links to them are removed ([CONTRIBUTING.md](CONTRIBUTING.md), "Your own copy"). - **No images of the game.** No screenshots, clips or extracted game images are kept here or in other project repositories; the checks refuse them. The only images are recordings of our own tools. - **Not affiliated.** This is a fan project. It is not affiliated with, endorsed by or sponsored by Sony Interactive Entertainment or FromSoftware. Bloodborne and related names are trademarks of their respective owners. ## License GPL-2.0-or-later ([LICENSE](LICENSE)). The active external run scaffold has its own GPL-2.0-or-later license and attribution notice in `third_party/README.md`; that notice does not grant any right in the game or its code. *Fear the old blood.*