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 the executable's boot gets as far as scePthreadAttrGetaffinity (libkernel, called by libc.elf), with 252 of 686 system imports implemented.
Start here · Documentation · Discussions · Contributing
| | Functions | Bytes | |---|---:|---:| | Target (Ghidra export) | 157757 | 42487347 | | Replaced | 51 (0.03%) | 24169 (0.06%) | | Edge-verified | 51 (0.03%) | 24169 (0.06%) | | Verified | 21 (0.01%) | 14010 (0.03%) |
Each row includes the next: verified functions are also edge-verified and replaced.
| Runtime | |
|---|---|
| System imports implemented | 252 of 686 (36.73%): 219 by the game's own modules, 33 by the runtime |
| Other imports | 4 registered fail-loud diagnostics, 430 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.
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
- the game runs natively on a PC on Paleblood's own runtime: no PS4, no emulator, and no original
- because it is source, the game can be read, understood, preserved, fixed and modded like any
Two tracks get there, side by side:
- Decompilation: functions rewritten as readable C++ and proved against the original in the
- Runtime (
runtime/): our own loader (done; the verification harness maps the executable
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
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
- The frame loop's code is decompiled: the clock, the frame limiter, the per-frame step and the
BB_TARGET_FPS=30|60|uncappeddoes in code what the community frame-rate patches do with
How it works
- Map the original. Our loader (
runtime/loader.c) maps the unmodified
- Rewrite a function. A replacement in
game/, readable (STYLE.md) and/
game/hooks.csv registers it.
- Prove it.
tools/verify.pyruns the original machine code and the
- Review it. An independent reviewer checks the verification and the readability before a
- Boot further. The runtime track implements the system functions the executable needs,
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 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), the verification harness and a first verified function. docs/ARCHITECTURE.md explains the pieces.
Contributing
One function or cluster per pull request, each verified with tools/verify.py, readable
(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, and read
CONTRIBUTING.md first.
Documentation
- The documentation site: how each
docs/systems/: one page per game system (generated; changes go through
- QUIRKS.md: traps in Ghidra, the PS4 executable and the ABI.
- 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: 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.
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
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
- No images of the game. No screenshots, clips or extracted game images are kept here or in
- Not affiliated. This is a fan project. It is not affiliated with, endorsed by or sponsored
License
GPL-2.0-or-later (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.