# Pocket Wormhole A native Android port of [Project Wormhole](https://gitlab.com/znixian/xftl) (xftl), the clean-room reimplementation of the **FTL: Faster Than Light** engine by Campbell Suter (ZNix) and contributors. The engine is re-implemented from scratch and loads **all game assets directly from your own `ftl.dat`** — the exact file that ships with your Steam/GOG copy of FTL. **No FTL assets are included.** You must own the game. FTL: Faster Than Light is © Subset Games; this project is not affiliated with or endorsed by them.

FTL running on Android — the Kestrel at a beacon, FTL drive ready to jump

Combat against a pirate scout in an asteroid field, touch power UI at the bottom

## Installing 1. Grab the latest APK from [GitHub Releases](https://github.com/adamkulik/pocket-wormhole/releases) (or build it — see below), copy it to your phone and install it (allow "install from unknown sources"). 2. Copy `ftl.dat` from your PC's FTL install (`FTL Faster Than Light\ftl.dat`, ~280 MB) to the phone — anywhere you like. 3. Launch the app. On first run it asks you to pick `ftl.dat` with the system file picker. It copies the file into the app's private storage (one time, needs ~280 MB free) and then starts. ## Controls | Action | Result | |---------------------|-----------------------------------------------------| | Tap | Left click | | Drag | Mouse drag | | Long-press (~0.5 s) | Right click (move crew, power down systems, cancel) | | Two-finger drag ↕ | Scroll wheel (ship lists, options) | | Back button | Escape (opens the pause/escape menu) | | Physical keyboard | Space/Enter/arrows/Tab/Escape/letters reach the game | | Tap a crewmember | Selects them and auto-pauses in room-selection mode — tap a room to send them there, tap empty space to cancel | | Tap a system icon | Opens a power panel with big +/− buttons (drones get on/off toggles); the game auto-pauses | | Tap a weapon to fire | Auto-pauses in targeting mode — your ship shrinks out of the way and the enemy ship goes full-size; tap rooms to target (drag for beams), long-press to cancel | | In the store, maps & upgrades | First tap on an item just inspects it (highlights + shows its description); tap the same item again to buy/sell/jump/confirm. Tapping a different item moves the highlight, tapping empty space clears it. Event choices and the pause menu stay single-tap | ## Saves & data Everything lives in the app's internal private storage (`Context.filesDir`, `/data/data/com.pocketwormhole.android/files/`), which file managers can't open without root: - `ftl.dat` — the copied game data - `ProjectWormhole/save-profile.xml` — profile (unlocks, achievements, options) - `ProjectWormhole/run-save.xml` — your in-progress run - `ProjectWormhole/ftl-path.txt` — pointer to the copied `ftl.dat` - `ProjectWormhole/mods/` — mods, loaded like on desktop (with an `order.txt` listing them); since the folder is private, there's currently no way to put mods there on an unrooted phone - `log-session-*.txt` — session logs (useful for bug reports); these are also written to `/Android/data/com.pocketwormhole.android/files/`, which you can reach over USB or with a file manager on most Android versions **Save + Quit** (escape menu) saves your run; the next time you open the app the run resumes automatically, exactly where you left it. Starting a new run or dying discards the saved one, as in vanilla FTL. ## Moving runs between devices (EXPORT / IMPORT SAVE) The pause menu can **EXPORT** your run as a vanilla-compatible `continue.sav` (loadable by vanilla FTL 1.6.14+ with AE, or another Pocket Wormhole install) and **IMPORT** such a file back. > **⚠️ READ THIS BEFORE USING — these are hard limitations, not fine print:** > > - **Move runs at the start of a sector.** The EXPORT button only exists > while you stand on the newly arrived sector's entry beacon, because that > is the one state that transfers faithfully. There is no way to pin a > mid-sector position across engines. > - **The map layout reshuffles on every transfer.** Ship, crew, weapons, > scrap, sector number, visited route, stores, quests and fleet progress > all carry over — but the beacon geometry is re-rolled by whichever > engine imports the save, so everything sits in different places. > - **In-flight state is dropped**: an active battle (enemy ship and > projectiles), open event dialogs, hacking effects and crew waiting in > the clonebay do not survive a transfer. > - **Exports from v0.2.4 or older are broken** and will *hang vanilla FTL* > on load. Re-export the run with v0.2.5 or newer. > - Lifetime profile statistics are zeroed in exports (vanilla keeps its own > totals in its `prof.sav` anyway). > - `run-save.xml` — the engine-native autosave — is **not** a transfer > format. It only works between Pocket Wormhole installs. In short: jump to a new sector, EXPORT, move the file, IMPORT (or drop it next to vanilla's saves), and continue there. ## Known limitations - XSLT-based mod patches are unsupported (Saxon doesn't run on Android); vanilla data and most Slipstream mods work fine. - Requires Android 8.0+ (API 26) and a GLES 3.0 GPU (everything from ~2014 on). - The hangar ship editor UI is mouse-centric; it works with touch but is fiddly. - Hover-dependent desktop UI (tooltips) only shows while you're touching — except in the store, maps and upgrades, where a tap keeps the info up (see tap-to-confirm above). ## Building from source Prerequisites: JDK 17, Android SDK (platform 34, build-tools 34.0.0). ``` ./gradlew assembleDebug # Linux/macOS gradlew.bat assembleDebug # Windows ``` The APK lands in `app/build/outputs/apk/debug/`. `local.properties` is created by Android Studio, or write it yourself: `sdk.dir=`. ### How it works The engine (`xyz.znix.xftl`), Slipstream (`net.vhati.*`) and patched jorbis/PNGDecoder sources are compiled into the app; the desktop LWJGL layer is replaced by small Android-backed shims: - `org.lwjgl.opengl.*` — GL11..GL30 → `android.opengl.GLES30` (the engine's renderer is GL 3.0-core, mapping 1:1 onto GLES 3); each frame is drawn into an offscreen framebuffer with a guaranteed depth+stencil attachment - `org.lwjgl.openal.*` — a software OpenAL implementation (SoftAL) mixing to an `AudioTrack`, including buffer-queue streaming for music and `AL_SEC_OFFSET` seeking - `org.lwjgl.glfw.GLFW` — key constants; windowing is replaced by `AndroidGameContainer` (GLSurfaceView) and `AndroidInput` (touch → mouse, with a one-frame click deferral so the engine's draw-time hover state is correct for instant taps) - `org.newdawn.slick.*` — the Slick2D classes the engine uses (decoders, listeners, geometry), with Android-backed implementations Patches to the upstream engine are kept minimal; see the source comments and git history. ## Credits & licences See [NOTICE.md](NOTICE.md) for the full list. In short: - [Project Wormhole](https://gitlab.com/znixian/xftl) — Campbell Suter (ZNix) and contributors (GPL-2.0+) - [Slipstream Mod Manager](https://github.com/Vhati/Slipstream-Mod-Manager) — Vhati and contributors (GPL-2.0) - [JOrbis/JOgg](http://www.jcraft.com/jorbis/) — JCraft (LGPL-2.1) - PNGDecoder — Matthias Mann (BSD-3-clause) - **FTL: Faster Than Light** — © Subset Games. This project ships none of its assets; load them from your own copy. ## Licence This project is free software: you may redistribute and/or modify it under the terms of the [GNU General Public License v2.0](LICENSE), or (at your option) any later version.