HK: Dual Souls

A native Android port of Hollow Knight (GOG/Steam, v1.5.12620 "Voidheart") for the AYN Thor dual-screen handheld.

README

Hollow Knight for the AYN Thor — dual-screen ("HK: Dual Souls")

A native Android port of Hollow Knight (GOG/Steam, v1.5.12620 "Voidheart") for the AYN Thor dual-screen handheld, in the spirit of the PS Vita port: a same-version Unity rebuild that you provision from your own copy of the game. Unlike the Vita port there is no PC step — the patch applier is compiled into the APK, so it's folder → patch → done, entirely on the device.

IMPORTANT: You must own Hollow Knight on GOG or Steam to use this. One patch serves both stores (their game data is byte-identical — measured, 1,759 of 1,761 files; the two that differ are store DLLs the patch never touches).

What the bottom screen does

  • Live HUD — masks, soul vessel, geo, mirrored to the bottom panel; the top screen stays clean.
  • Companion panes — Map / Inventory / Charms, touch-driven, while the game keeps running on top:
    • Map: live quick-map of your current area with the "you are here" compass, pinch-zoom, drag-pan, and a reset pill. Auto-updates as you explore; markers and pins follow real progress, including your shade and an active dream gate.
    • Inventory: tap any item for its name, description and control prompt (with the proper controller glyph).
    • Charms: full grid of obtained charms, tap for details, equipped row and notch count mirrored up top.
  • Story overlays — tutorials, lore tablets, NPC dialogue (with the speaker's name), item popups and the opening attribution render on the bottom panel on a clean black background.
  • Fade sync — room transitions, deaths and cutscene fades mirror 1:1 on both screens.
  • Plus: FPS + battery readout, per-area name, equipped-charm strip, screen-off when the app is backgrounded.

Everything else

  • Plug-and-play controllers: the Thor's built-in pad (both Standard and Xbox handle styles), plus external Xbox / PS4 / PS5 / Switch pads — each gets its own button glyphs automatically.
  • Touch controls appear automatically when no gamepad is present.
  • Rumble through the Thor's body motor and external pads' motors.
  • 120 fps capable (set the Thor's display to 120 Hz), correct frame pacing.
  • Video cutscenes, save slots, all 501 rooms — the whole game.

Skins

The hub's Skins page imports CustomKnight-format skin packs (folders of PNGs) straight from your device storage — no mod loader, no PC. Skins apply live in-game, cover the bottom screen too, and persist across updates.

Roughly 110 of CustomKnight's ~160 sheet names are wired: the Knight (including the separate sprint page), HUD, soul orb and liquid, spells and their particle effects, charm minions, all charm icons including the glass and royal variants, and the inventory item sheets. Sheets a pack ships that this port does not implement are simply ignored — nothing breaks. Not implemented: the nine preload sheets (they need scene preloading at boot), AreaBackgrounds/, free-form Swap/, and Cinematics/ video replacement.

Skin packs are often authored against an older build of the game, so some sheets have gaps or art in the wrong frame. The port repairs those at load time: empty sprite regions fall back to the pack's own art for the same object where one exists, otherwise to the original game art, and a frame that has clearly drifted from the rest of its animation is replaced with the pack's consistent art. That is why a pack can look correct here even when parts of it were never finished.

Mod menu (quality-of-life / cheats)

Off by default — zero footprint until you opt in. Tick Mod menu in the hub and a small gear icon appears next to the bottom-screen fps corner. Tap it for the pane. Everything is toggleable live, mid-gameplay and fully revertible; MASTER gates the lot, and RESET returns every value to vanilla.

Traversal and utility: always-run, auto-map, innate compass, innate geo magnet, fast room transitions, bench teleport (tap a bench pin on the map). Combat: nail damage ×N, damage cap, one-hit kills, damage received (vanilla / no mask loss / invincible), enemy HP bars, floating damage numbers, boss retry, secret radar. Charms: costs, unlimited notches, equip anywhere. Economy and journal: geo ×N, keep geo on death, journal one-kill, unlimited soul. Plus four save-state slots with save / load / delete.

State lives in tweaks.json; per-save snapshots make reverts exact.

Compromises

  • A few of Hollow Knight's shaders are hand-reconstructed approximations (AssetRipper cannot extract the originals). Lighting/bloom are very close but not pixel-identical to PC.
  • Video cutscenes are VP8-transcoded (the Linux editor cannot import H.264); quality is near-identical.
  • The bottom-screen feature set is built for the AYN Thor's second panel. On single-screen devices the game runs, but the companion has nowhere to draw (set dualScreen: 0).

Installing

  1. Install dualsouls-v1.0.0-thor-arm64.apk. It opens to its hub screen — it cannot run yet.
  2. Copy your whole Hollow Knight folder to the device — the folder that contains Hollow Knight_Data (GOG) or hollow_knight_Data (Steam).
  3. Copy hk-android-gog.xdelta to the device.
  4. In the app: Import Game → tap Your Hollow Knight folder and Patch file (either order; each row ticks when verified) → Build game data (a few minutes) → START GAME. The first start after a build relaunches the app once — that is normal (Unity mounts the game data during startup, before the app's own code runs).
  5. Needs ~1 GB free for the built data, plus room for your copied game folder (which you can delete afterwards).

PC/Termux alternative (same patch):

tools/hkapply.sh "<Hollow Knight folder>" hk-android-gog.xdelta manifest-gog.json

Use a current xdelta3 (3.1 or newer). Older builds — 3.0.11 among them — mis-decode this patch's secondary compression and produce a file of exactly the right size but wrong contents. The script hashes its output and refuses it rather than handing you a broken .obb, so a VERIFY FAILED here usually means your xdelta3 is too old, not that your game copy is wrong.

then copy the produced main.1.igawa6.dualsouls.obb to the device and use Install a prebuilt .obb on the hub.

Updating

  • Install the new APK over the old one (adb install -r, or just open the new APK). Your saves and game data are kept. Never uninstall first — uninstalling deletes the built game data and your saves.
  • If the release notes say "game data rebuild required", the app will tell you the installed data belongs to an older version and send you back to Import Game — re-run Build game data with the new patch. Saves are untouched by a rebuild.
  • Android's Clear storage is treated as a factory reset: it discards saves and the built game data, and setup runs from scratch.

Save files

Hollow Knight's four save slots live in Android/data/igawa6.dualsouls/files/. The hub's Save Files page exports any slot to a folder you choose and imports one back (the previous slot contents are kept alongside as .bak). Saves from the PC version are not directly compatible (different format wrapping) — use slots the app created.

Troubleshooting

  • Black screen on launch after copying an .obb by hand — use Install a prebuilt .obb on the hub instead of a raw file copy; a hand-copied file is missing the install stamp and gets cleaned up as an orphan. (Sideloading over adb: adb push both the OBB and a hk_data_stamp.txt containing nohash:<obb size in bytes> into Android/data/igawa6.dualsouls/files/ — push the stamp as a file; a shell-redirected echo creates it with permissions the app cannot read.)
  • "The installed game data belongs to a different version of this app" — this APK expects the data built with its own patch. Re-run Build game data with the patch from the same release.
  • The app says the game data is installed but the game never starts — Android has not granted it storage access, so Unity refuses to mount the data (logcat repeats "No permission to read external storage"). Accept the permission prompt on first launch, or grant it under Settings → Apps → HK: Dual Souls → Permissions → Files. Builds before 1.0.0 could not request it at all on Android 13+.
  • First launch after installing takes ~1 minute — Android is optimizing the app (dex2oat); it is not a crash. Later launches are fast.
  • "x of 1761 files are wrong" while picking the folder — your copy is incomplete or modded; verify/reinstall the game on GOG/Steam and re-copy.
  • Bottom screen stays black at the title menu — expected; it shows the logo, and content appears in gameplay.

Building it yourself / source

The runtime scripts (dual-screen, companion, input, provisioning), the native blit plugin, the patch tooling and the build harness are in this repository; docs/BUILDING.md documents the build and release pipeline.

What the repository does and does not contain. The source tree carries no Team Cherry art, audio, scenes or game data: the bottom screen's chrome is either drawn procedurally at runtime or baked out of your copy of the game on first use, and the app icon is original artwork. What it cannot avoid carrying is the shape of the game — script names, sprite and FSM identifiers, and the file list the patch is built against. The release artifacts are a different matter; see the disclaimer and REDISTRIBUTION-AUDIT.md.

Credits

  • Team Cherry — Hollow Knight. Buy it. Buy Silksong. This project exists because the game is worth carrying everywhere.
  • PatnosDD — the PS Vita port that proved the same-version-rebuild approach.
  • rosbean's balatro-dualscreen — the dual-screen UX prior art for the Thor.
  • PrashantMohta / CustomKnight — the skin format this port reads.
  • AssetRipper, xdelta3 (Josh MacDonald), Unity — the tools that made it possible.

Disclaimer

This requires a legally purchased copy of Hollow Knight. The APK contains the game's compiled code and the patch reconstructs the game's data — describing this release as "clean of game content" would be false, which is why ownership is required and why the reconstruction runs against your copy. This is a fan port, not affiliated with or endorsed by Team Cherry. If Team Cherry objects to this project it will be taken down.