# MeleePad
**Super Smash Bros. Melee on iPhone, iPad, and Apple Silicon Mac.**
Build a native Apple app from your own supported copy of Melee, with touch
controls, physical-controller support, Metal rendering, and Slippi online play
on iPhone and iPad. Game code is compiled ahead of time, so no JIT is required
on iOS or iPadOS.
Built with [ModernGekko](https://github.com/ExpansionPak/ModernGekko),
[DolRecomp](https://github.com/ExpansionPak/DolRecomp), and the
[RecompCore](https://github.com/ExpansionPak/RecompCore) / [Dolphin](https://github.com/dolphin-emu/dolphin)
runtime, with Apple integration based on [SunPad](https://github.com/chrissotraidis/sunpad).
See [credits and maintained sources](#credits-licensing-and-contributing).
**[Build and setup](#build-from-source) ·
[Slippi profile setup](#import-your-slippi-profile-on-iphone-or-ipad) ·
[FAQ](#faq) · [Discord](https://discord.gg/xwHfUD2bxW)**
> [!IMPORTANT]
> Releases publish the app without any game code. [PadMint](https://github.com/chrissotraidis/padmint/releases/latest)
> makes the game part on your Mac from your own disc and adds it. See [Get MeleePad](#get-meleepad).
## Get MeleePad
**No Mac? Build it on a Windows PC (experimental).** PadMint 0.5.27 or newer
builds MeleePad for iPhone or iPad on Windows 11 (x64 or ARM64) from your own
Super Smash Bros. Melee (NTSC v1.02) disc image. Install Visual Studio 2022 Build Tools with **Desktop development with
C++**, then choose MeleePad in PadMint. PadMint downloads the game-free MeleePad app
from this release and adds the game code it builds from your file on your PC;
nothing of yours is uploaded. The Mac build is unchanged. This Windows route is
new: builds pass on Windows 11 ARM64, but a Windows-built copy has not yet been
played on a device. GitHub's Mac can't build MeleePad, because that would mean
uploading your game file. Details: [portable module backend](docs/PADMINT-MODULE.md).
You need an Apple Silicon Mac with Xcode, your own GALE01 USA v1.00 or v1.02
disc image, and AltStore Classic, SideStore or Sideloadly.
1. Once, install the build tools PadMint does not fetch itself: `brew install ripgrep`,
then [rustup](https://rustup.rs) and
`rustup toolchain install 1.88.0 --target aarch64-apple-ios`.
2. Download [PadMint](https://github.com/chrissotraidis/padmint/releases/latest),
unzip it and double-click `PadMint.command`. In the PadMint page that opens in
your browser, choose MeleePad and your disc image, then click **Make my copy**. PadMint downloads the published app from the
[latest release](https://github.com/chrissotraidis/meleepad/releases/latest),
builds your game module from your disc and adds it, then saves your MeleePad
IPA in your Downloads folder.
3. Install that IPA with your sideloading tool, over an existing MeleePad to keep
your data, then import the same disc image in the app.
With PadMint 0.5.5 or newer you can also choose **This Mac**: PadMint builds
`MeleePad.app` from your disc and saves it as a zip; move it to Applications and
choose your disc image under **Game Data**.
The IPA and the Mac app contain code translated from your disc: they are yours
alone; never share them. This covers offline play. Native Slippi online play still needs the
[developer build](docs/SLIPPI-BUILD.md#playable-private-builds).
On Windows, PadMint builds the offline game module from your disc with the
[portable module backend](docs/PADMINT-MODULE.md); see **No Mac?** above.
## Preview 7 (build 29)
- The in-game three-dot menu groups Slippi, display, controls, game data, and
help so its main list fits on an iPad. Existing actions remain available.
- Peer warnings are shorter and sit below the menu button, away from Slippi's
top-left performance message and the match timer. Steady Wi-Fi matches no
longer show a persistent status banner.
- **Slippi Connection Check** remains available from Home Settings and the
in-game Slippi menu. It checks the network path and Slippi website response,
**not** matchmaking UDP or an opponent's ping.
Build 29 launched on the maintainer's iPad with the game, Slippi module, and
account ready. An earlier build 28 Unranked match connected and played, but
showed high peer latency and poor frame pacing. Build 29 changes the menu and
warnings; it does **not** claim to fix match lag. A build 29 live-match UI retest
remains open.
See the [Preview 7 release notes](docs/releases/v0.1.0-preview.7.md) and
[Slippi build guide](docs/SLIPPI-BUILD.md). [Older release notes](docs/releases/).
## Choose an install path
| Goal | Start here |
|---|---|
| Play on your own iPhone or iPad | Make your copy with PadMint on an Apple Silicon Mac: see [Get MeleePad](#get-meleepad). |
| Use Slippi online | Build for USA v1.02 with the [private Slippi build requirements](docs/SLIPPI-BUILD.md#playable-private-builds), then [import your own account](#import-your-slippi-profile-on-iphone-or-ipad). |
| Update an existing installation | Keep the same bundle identifier and signing team. Install a **complete private build** in place to retain app data; the public shell would replace your bundled modules. |
## How MeleePad works
MeleePad does not depend on a completed source-code decompilation of Melee.
Instead, it uses **static recompilation**: translating the original game's
compiled PowerPC instructions into code that can be compiled for a different
processor before the app runs.
The build pipeline works in five stages:
1. You provide your own supported USA `GALE01` disc image locally: v1.02
(recommended) or v1.00.
2. The tooling verifies that exact image and extracts its executable and game
data. Nothing is downloaded from Nintendo or committed to this repository.
3. [DolRecomp](https://github.com/ExpansionPak/DolRecomp) reads the GameCube
executable, decodes its PowerPC instructions, and emits portable C in
manageable generated chunks.
4. Apple Clang compiles those generated chunks ahead of time into an ARM64 game
module. The iPhone or iPad does not translate that code while you play.
5. [ModernGekko](https://github.com/ExpansionPak/ModernGekko), built on a
Dolphin-derived runtime, supplies the console environment around that code:
memory, timing, disc access, graphics, audio, and controller interfaces.
MeleePad connects that runtime to UIKit, Metal, Apple audio, touch controls,
and GameController.
The result is a native ARM64 Apple app running ahead-of-time-compiled game code.
Static recompilation replaces the runtime CPU translation layer; the
Dolphin-derived compatibility layer still models the GameCube hardware and
services the game expects. This is therefore most accurately described as a
**native static-recompilation compatibility port**, not a traditional
source-code port and not a stock Dolphin frontend.
The iPhone and iPad app imports a user-supplied game image from Files. The macOS
app provides a native launcher, Metal rendering, keyboard and controller input,
local settings, and developer-facing netplay controls. This repository contains
the Apple integration, maintained dependency pins, tests, and reproducible build tooling.
Normal builds consume committed fork sources; old patches remain only as an archive.
It does **not** contain Melee, a disc image, extracted Nintendo assets, saves,
signing material, or a generated game module.
See the [melee-pc research assessment](docs/MELEE-PC-RESEARCH-2026-09-16.md) for
the audited reuse candidates and the limits of the performance evidence.
## FAQ
Can I download a playable IPA?
No. The release has the app without game code; PadMint builds your game module
from your own disc and adds it. See [Get MeleePad](#get-meleepad).
Does the completed decompilation make MeleePad faster?
It helps us understand and profile the original game. MeleePad still uses
statically translated PowerPC code and a Dolphin-derived compatibility runtime;
the decompilation does not automatically produce an optimized ARM64/Metal port.
The September 9 investigation retained better scene diagnostics but established
no reliable gameplay speedup. Heavy iPhone 14 scenes remain a known problem.
Where are the other answers?
The [full FAQ](docs/FAQ.md) covers native execution, JIT, supported images,
controllers, multiplayer, privacy, connection troubleshooting, Slippi, and
physical-device limitations. The [Online Play guide](docs/ONLINE-PLAY.md)
contains setup instructions, verified results, and remaining acceptance gates.
## Current status
| Area | Working now | Important limitations |
|---|---|---|
| macOS | Native Apple Silicon launcher and runner, Metal rendering, keyboard and controller profiles, matches, saves, and settings | Final display and worst-frame acceptance work remains |
| iPhone and iPad | Native app shell, Metal gameplay, touch controls, controller mapping, More menu, exact-image import, persistent saves and settings, and diagnostic export | Serious water, reflection, and shadow rendering defects remain; the full visual, audio, controller, and lifecycle matrix has not passed |
| Performance | A physical iPad held 59.9–60.0 FPS/VPS at 2x resolution in one observed solo scene | A later Slippi match had high ping, rollback stalls, and a 54.5 FPS median; iPhone 14 heavy-scene slowdowns also remain unresolved |
| Experimental multiplayer | Preview 4 fixed-delay Private Room and Direct IP transport, eight-character room codes, temporary peer chat, native Host/Join lobby, compatibility fingerprinting, and synchronized Mac/iPad Simulator runs in both host directions | These custom rooms are separate from Slippi; no public room browser or relay |
| Distribution | Preview 7 source plus an unsigned, module-free IPA shell; locally generated and signed playable apps | Public IPA is not playable as downloaded; no App Store or TestFlight build; the locally generated game module is not distributed |
The combat-only right-stick mapping has passed a hands-on physical-iPad retest,
including the required menu/gameplay behavior. The current evidence, remaining
acceptance rows, and known rendering debt are tracked in
[the goal loop](docs/GOAL-LOOP.md), [project status](docs/STATUS.md), and
[technical debt](docs/TECH-DEBT.md).
The accepted Preview 1 performance debt and the retained physical-device
measurements are summarized in
[the physical-iPad thermal slowdown record](docs/artifacts/2026-09-03/preview1-physical-ipad-thermal-slowdown.md).
## Requirements
To build MeleePad, you need:
- an Apple Silicon Mac;
- Xcode 26 or 27 (this release was built locally with Xcode 27.0);
- CMake, Ninja, Git, ripgrep, and Python 3; and
- your own supported USA Melee disc image (`GALE01`): v1.02 recommended,
or v1.00 for existing setups.
Use [the version guide](docs/MELEE-VERSIONS.md) to identify supported input and
build the matching module. Preparation verifies content and executable identity;
it rejects unlisted images. Each revision has separate extraction/module storage.
## Build from source
Prepare the pinned public dependencies and your private game input:
```sh
./scripts/bootstrap-dependencies.sh
./scripts/prepare-game.sh /path/to/GALE01.iso
```
These commands build the public tools, validate and extract the supplied game
locally, and generate private build inputs under ignored paths. They never
download or redistribute game data.
Build and open the Apple Silicon macOS app:
```sh
./scripts/package-macos-app.sh
open build-macos/MeleePad.app
```
Build the iOS Simulator core and app:
```sh
./scripts/ios-build-core.sh
./scripts/ios-provision.sh
xcodebuild -project MeleePad.xcodeproj -scheme MeleePad \
-configuration Release \
-destination 'platform=iOS Simulator,name=iPad Pro 13-inch (M5)' \
CODE_SIGNING_ALLOWED=NO build
```
Release maintainers can build the publishable module-free iPhoneOS shell and
package it reproducibly with:
```sh
./scripts/build-ios-app.sh
```
This builds the pinned runtime and app with the version from `version.json`.
The packager refuses game modules, game/save files, provisioning profiles,
signatures, and private host paths. Its output remains an app shell; it does not
replace the playable local-build process below.
### Build for a physical iPhone or iPad
For the recommended USA v1.02 image, build its matching device core and
offline native module:
```sh
MELEEPAD_GAME_REVISION=2 ./scripts/ios-build-core-device.sh
open MeleePad.xcodeproj
```
For an existing v1.00 setup, omit `MELEEPAD_GAME_REVISION=2` and prepare the
matching v1.00 image instead. Native Slippi currently requires v1.02.
Then, in Xcode:
1. Select the **MeleePad** target and open **Signing & Capabilities**.
2. Select your Apple development team. If Xcode reports that the bundle
identifier is unavailable, change it to a unique reverse-DNS identifier
owned by your team.
3. Connect and unlock the iPhone or iPad, enable Developer Mode if required,
and select that device as the run destination.
4. Choose **Product → Run** to build, sign, install, and launch the app shell.
**Product → Run alone does not stage a playable native module or the Slippi
resources.** For a playable device build, stage the matching private module and,
for online play, the separate Slippi module and resources into the finished app;
then sign the complete bundle before installation. Follow the
[Slippi private-build steps](docs/SLIPPI-BUILD.md#playable-private-builds).
Importing an ISO or Slippi account into the module-free shell does not replace
these build steps.
Keep the same bundle identifier for later updates if you want iOS to preserve
the app's private game data, saves, controller settings, and preferences.
Changing the identifier creates a separate app container.
Generated sources, extracted game data, app packages, profiles, saves, and
locally recompiled modules are ignored and must not be committed.
## First launch on iPhone or iPad
MeleePad never downloads or bundles game data.
1. Tap **IMPORT GAME DATA** on the Original Melee card. For an existing setup,
use **Game Data** on Home instead.
2. Choose **Import a Disc Image**, then select your supported raw ISO or GCM
image in Files.
3. Leave the app open while it validates, extracts, and atomically activates
the private game data.
4. Start playing when Home confirms the matching native module is present.
Importing the image alone cannot make a module-free app playable.
A failed reimport leaves the prior working data active. Removing stored game
data keeps saves and control settings separate.
## Controls and settings
The landscape touch layout provides move and C sticks, compact L and R
shoulder buttons, A/B/X/Y/Z, Start, and a grouped editable directional pad.
The **•••** menu groups **Slippi & Online**, **Display**, **Controls**,
**Offline Cheats**, **Game Data & Saves**, and **Help & About**, with
**Exit to Home** at the bottom. Display contains render scale, aspect ratio,
and the FPS counter. Controls contains mapping and touch settings. A physical
controller can automatically hide the touch overlay.
The built-in macOS keyboard controls are:
| Action | Key |
|---|---|
| Move | W, A, S, and D |
| Attack or confirm | J |
| Special or back | K |
| Jump | Space or U; I is the second jump button |
| C-stick or smash attack | Arrow keys |
| Shield | Q or E |
| Grab | O |
| Start or pause | Return |
Launching the macOS app replaces only MeleePad's internal automation pipe
profile with this interactive keyboard profile. Existing custom keyboard and
physical-controller profiles are preserved.
## Slippi support
MeleePad's iOS/iPadOS Slippi integration has completed real Unranked matches on
the maintainer's physical iPad, corroborated by game-end logs. Connection
stability and performance remain under investigation after earlier disconnects
and a later laggy match. Project Slippi has not endorsed this port.
Ranked follows Slippi's current access rules. A subscription prompt from
Slippi is an access gate, not an app failure.
Direct, Teams and Party are enabled but lack equivalent completed-match testing.
macOS Slippi interoperability has not received the same hardware acceptance.
Use your own Slippi account. Replay and diagnostic files stay local unless you
choose to share them. See [setup and build requirements](docs/SLIPPI-BUILD.md).
Before matchmaking, use **Home Settings → Slippi & Online → Slippi Connection
Check** or **••• → Slippi & Online → Slippi Connection Check** in-game. It makes
three short requests to Slippi's website and shows a median response time;
it cannot test matchmaking UDP or predict an opponent's ping. During a match,
a compact warning below the menu button reports high peer ping, rollback
stalls, or missing ping samples. Stalls can reflect the network or the device.
### Import your Slippi profile on iPhone or iPad
MeleePad imports your Slippi **account file, `user.json`**. A replay (`.slp`),
controller profile or public profile link will not work. You need your own
Slippi account; MeleePad does not include a shared account.
1. In Safari, open [Slippi's account export page](https://slippi.gg/online/enable).
Sign in to your Slippi account and download your `user.json` file. If you
download it on your Mac instead, AirDrop it to your iPhone/iPad and save it
in **Files**.
2. Make sure `user.json` is available in **Files → Downloads** (under iCloud Drive
or On My iPhone/iPad, depending on your Safari download setting).
3. Install a locally built, signed app with the matching native Slippi module
and import your supported game data. The home card shows which of these is
missing; **SET UP SLIPPI → Build Instructions** explains a missing module.
4. On the home screen, tap **SET UP SLIPPI**.
5. Tap **Import Account**, then select your `user.json` in the Files picker.
6. After import, MeleePad attempts to start Slippi. On subsequent launches, the
home card shows **PLAY SLIPPI** when game data, module and account are present.
Start with **Unranked**. Ranked follows Slippi's access rules.
**Account import does not install the game or native module.** You still need a locally signed playable
build with your own USA v1.02 game data and matching native Slippi module;
see [Slippi build requirements](docs/SLIPPI-BUILD.md).
The imported account is saved in this device's Keychain; Slippi receives a
restricted temporary runtime copy while running. Keep the downloaded file
private—it contains your login key. Do not attach it to Discord posts or bug
reports. After a successful import, you can delete the downloaded copy from
Files if you do not need it elsewhere.
If the picker cannot select the file, confirm that you downloaded the actual
`.json` export, not an HTML page, ZIP or replay. If MeleePad says “Select your
own Slippi user.json export,” download a fresh export and try again; do not edit
or invent its account fields. “Native Slippi code set is incomplete” or a missing
module/game-data message refers to the playable build setup, not your profile.
## Experimental multiplayer
Private Room and Direct IP are available for controlled tests with people you
trust. Both peers need the **same app build, game revision, matching modules and
game data, and compatible gameplay settings**. For Preview 7,
that means build 29 on both ends; USA v1.02 is recommended. v1.00 can only play
with a compatible v1.00 peer.
| Option | Current boundary |
|---|---|
| Private Room | Eight-character room codes through Dolphin traversal; no relay fallback |
| Direct IP | Advanced testing on a trusted network or private VPN |
| Public Games | Development UI only; no production public browser |
| Room Chat | Temporary plaintext peer chat in Private Room and Direct IP |
Retained tests include synchronized Mac/iPad Simulator runs. These custom rooms have not passed a complete physical-device Internet match
acceptance run. They are separate from the Slippi integration above; encrypted
gameplay and four-player online acceptance are not established.
For setup, troubleshooting, privacy, and the full test history, see the
[Online Play guide](docs/ONLINE-PLAY.md). Use the
[Private Room test guide](docs/PRIVATE-ROOM-TESTING.md) for a complete report.
## Reporting issues
Join the [Discord community](https://discord.gg/xwHfUD2bxW) for discussion and
setup help. Report reproducible bugs through GitHub using the steps below.
Use **••• → Help & About → Report a Problem…** to review and share a diagnostic package.
Gameplay timing summaries are collected automatically; note the approximate time
and scene when a slowdown happens. No profiler switch is required. Then
[open a MeleePad GitHub issue](https://github.com/chrissotraidis/meleepad/issues/new)
and include:
- the Apple device and OS version;
- whether touch, keyboard, or a named controller was in use;
- the scene and steps needed to reproduce the problem;
- relevant display, audio, and controller settings; and
- the diagnostic export, after checking it for anything you do not want to
share.
For Online Play, also include whether you hosted or joined, whether the players
used the same or separate networks, whether either side used a VPN, approximate
time to receive the room code, approximate ping if a peer connected, and
whether a full match, results screen, character select, and rematch completed.
The [community test guide](docs/PRIVATE-ROOM-TESTING.md) contains a copyable
report template.
Never upload a game image, extracted game data, save files, signing material,
IP addresses, or room codes.
## Testing and project policy
The repository uses a proof-gated workflow: small falsifiable changes, focused
regressions, live visual evidence for playability claims, ROM-safe Git history,
and explicit separation between verified, partial, and blocked work.
Run the repository safety suite before publishing:
```sh
./scripts/check-repository.sh
```
The final iPad Simulator performance gate must be played by a person; automated
touch input cannot replace it. With exactly one Simulator booted, run:
```sh
./scripts/run-g8-human-acceptance.sh
```
The harness starts a fresh Release build, records the complete screen without
UI polling, and retains same-session runtime rows and hashes outside Git. Follow
its displayed match instructions, play for five uninterrupted combat minutes,
reach results, return to the menu, and finish the capture from the terminal.
The script reports numeric thresholds but never declares acceptance; a person
must still review the recording and every phase.
See the [product requirements](docs/PRD.md), [engineering journal](docs/JOURNAL.md),
and [current status](docs/STATUS.md) for the acceptance contract, chronology,
and detailed evidence.
## Community and support
[Join the Discord](https://discord.gg/xwHfUD2bxW) for help and news. It is one
community for MeleePad and its sibling projects, such as KartPad, BlueWake and
SunPad: ask about setup, building with PadMint, and installing, share how it
runs on your device, and hear about new releases first.
Found a bug? [Open an issue](https://github.com/chrissotraidis/meleepad/issues)
with your device, its OS version, and the steps that led to it.
## Credits, licensing, and contributing
Built with [ModernGekko](https://github.com/ExpansionPak/ModernGekko), by Hyperway,
ExpansionPak and contributors, and [DolRecomp](https://github.com/ExpansionPak/DolRecomp),
on the [RecompCore](https://github.com/ExpansionPak/RecompCore) /
[Dolphin](https://github.com/dolphin-emu/dolphin) runtime. The Apple integration
builds on [SunPad](https://github.com/chrissotraidis/sunpad). MeleePad's contribution
is the Apple app, controls, integration, and game-specific fixes; the underlying
compiler and runtime remain the work of their upstream authors.
**Maintained dependency forks:** [ModernGekko](https://github.com/chrissotraidis/ModernGekko/tree/codex/meleepad-slippi-preview5),
[RecompCore](https://github.com/chrissotraidis/RecompCore/tree/codex/meleepad-slippi-preview5),
[DolRecomp](https://github.com/chrissotraidis/DolRecomp/tree/codex/meleepad-integration-20260914), and
[ENet](https://github.com/chrissotraidis/enet/tree/codex/meleepad-slippi-preview5).
MeleePad is the Apple app repository; its runtime/compiler changes live in these
forks and are selected through pinned submodules. See [full credits](CREDITS.md)
and the [source graph](docs/DEPENDENCIES.md).
See [Credits](CREDITS.md), [third-party notices](THIRD-PARTY-NOTICES.md), and
[contribution guidelines](CONTRIBUTING.md). MeleePad-owned integration code is
licensed under [GPL-3.0-or-later](LICENSE); upstream files retain their original
licenses, notices, and authorship. This does not grant rights to Nintendo's game,
generated game code, artwork, or trademarks.
Development has used AI assistance. The maintainer reviews accepted changes;
upstream authors are not responsible for MeleePad-specific modifications.
Runtime and compiler changes should retain upstream history and be reviewed in
the relevant dependency fork. The [dependency guide](docs/DEPENDENCIES.md)
records the exact fork commits and upstream bases used by this app.
## Legal
MeleePad is an unofficial, fan-made project. It is not affiliated with, endorsed
by, or sponsored by Nintendo. Super Smash Bros. Melee and related names and
marks are trademarks of Nintendo (and their respective owners). This repository
contains no game data, disc images, or extracted assets. To use it, you need
your own legally obtained copy of the game, and you build it yourself on your
own machine. Please don't share game files or builds made from them.
MeleePad is an independent compatibility project and is not affiliated with or
endorsed by Nintendo, HAL Laboratory, or the Dolphin project. MeleePad does not
provide copyrighted game data; users are responsible for supplying and using
their own legally obtained game image in accordance with applicable law.