Skip to main content

libmelee

This is a fork of libmelee geared toward machine learning.

Differences from upstream

  • Gamestates match raw values from slp files, allowing faster tools such as peppi to be used to process replays for imitation learning without risking mismatch between replay data and live data. Upstream on the other hand preprocesses some values to make them more legible, e.g. sets intangibility for ledge grabbing.
  • A separate process is used to keep the enet connection to dolphin alive. Otherwise, it will time out after one minute of inactivity.
  • Sets up gecko codes for exi-inputs/fast-forward mode, which allows the game to run much faster than normal. These codes internally disable melee's rendering in the same way that is used to fast-forward a replay during playback. A custom dolphin build is required for this (see below).
  • Fixes input stick and analog trigger values to match what the game outputs. This makes imitation-trained bots behave correctly. See this commit for details.
  • Various other miscellaneous improvements, such as being able to control dolphin's debug logging, interfacing with mainline slippi-dolphin, setting infinite time mode, and playing as Sheik.

Installing Libmelee

This fork is now the source for the melee package on pypi, starting with version 0.45.0, and so can be installed with

pip install melee

To upgrade, run

pip install -U melee

Setup Instructions

Linux / OSX / Windows

  1. You can install and configure Slippi just like you would for rollback netplay -- see https://slippi.gg for instructions. If you want to use fast-forward mode, you will need to use my fork of slippi-Ishiiruka. A prebuilt Linux AppImage is available here, which can be used like a regular executable. This build is also headless, meaning it has no graphical elements at all. There is also a Linux mainline build that can run either headless or with graphics (but not in fast-forward mode).

  2. If you want to play interactively with or against your AI, you'll probably want a GameCube Adapter, available on Amazon. Alternatively the HitBox adapter works well too.

  3. Run the example script:

./example.py -e PATH_TO_SLIPPI_FOLDER_OR_EXE

Fast-Forward Mode

To use fast-forward mode, set these arguments in the Console constructor:

console = melee.Console(
  path="PATH_TO_CUSTOM_DOLPHIN",
  gfx_backend="Null",
  disable_audio=True,
  use_exi_inputs=True,
  enable_ffw=True,
)

Known Issues

  • On MacOS, mainline slippi dolphin crashes (segfaults) for unknown reasons. You should use Ishiiruka instead, or you can try building a "nogui" executable (this is what I use).

Playing Online

Do not play on Unranked There is no libmelee option for it, but don't try. Eventually we'll have a way to register an account as a "bot account" that others will have the ability to opt in or out of playing against. But we don't have it yet. Until then, do not play any bots on Unranked. If you do, we'll know about it, ban your account, overcook all of your food, and seed you against a campy Luigi every tournament. Don't do it.

Quickstart Video

Here's a ~10 minute video that will show you how easy it can be to write a Melee AI from scratch. Libmelee Quickstart Video

Some of the minor aspects of the API have changed since this video was made, but it's still a good resource.

The API

This readme will give you a very high level overview of the API. For a more detailed view into specific functions and their params, check out the ReadTheDocs page here: https://libmelee.readthedocs.io/

GameState

The GameState represents the current state of the game as a snapshot in time. It's your primary way to view what's happening in the game, holding all the information about the game that you probably care about including things like:

  • Current frame count
  • Current stage

Also a list of PlayerState objects that represent the state of the 4 players:

  • Character X,Y coordinates
  • Animation of each character
  • Which frame of the animation the character is in

The GameState object should be treated as immutable. Changing it won't have any effect on the game, and you'll receive a new copy each frame anyway.

Note About Consistency and Binary Compatibility

Libmelee tries to create a sensible and intuitive API for Melee. So it may break with some low-level binary structures that the game creates. Some examples:

  • Melee is wildly inconsistent with whether animations start at 0 or 1. For some animations, the first frame is 0, for others the first frame is 1. This is very annoying when trying to program a bot. So libmelee re-indexes all animations to start at 1. This way the math is always simple and consistent. IE: If grab comes out on "frame 7", you can reliably check character.animation_frame == 7.
  • Libmelee treats Sheik and Zelda as one character that transforms back and forth. This is actually not how the game stores the characters internally, though. Internally to Melee, Sheik and Zelda are the same as Ice Climbers: there's always two of them. One just happens to be invisible and intangible at a time. But dealing with that would be a pain.

Some Values are Unintuitive but Unavoidable

Other values in Melee are unintuitive, but are a core aspect of how the game works so we can't abstract it away.

  • Melee doesn't have just two velocity values (X, Y) it has five! In particular, the game tracks separately your speed "due to being hit" versus "self-induced" speed. This is why after an Amsah tech, you can still go flying off stage. Because your "attack based speed" was high despite not moving anywhere for a while. Libmelee could produce a single X,Y speed pair but this would not accurately represent the game state. (For example, SmashBot fails at tech chasing without these 5 speed values)
  • Melee tracks whether or not you're "on ground" separately from your character's Y position. It's entirely possible to be "in the air" but be below the stage, and also possible to be "on ground" but have a positive Y value. This is just how the game works and we can't easily abstract this away.
  • Your character model can be in a position very different from the X, Y coordinates. A great example of this is Marth's Forward Smash. Marth leans WAAAAY forward when doing this attack, but his X position never actually changes. This is why Marth can smash off the stage and be "standing" on empty air in the middle of it. (Because the game never actually moves Marth's position forward)

Controller

Libmelee lets you programatically press buttons on a virtual controller via Dolphin's named pipes input mechanism. The interface for this is pretty simple, after setting up a controller and connecting it, you can:

controller.press_button(melee.enums.BUTTON_A)

or

controller.release_button(melee.enums.BUTTON_A)

Or tilt one of the analog sticks by:

controller.tilt_analog(melee.enums.BUTTON_MAIN, X, Y)

(X and Y are numbers between 0->1. Where 0 is left/down and 1 is right/up. 0.5 is neutral)

Note on Controller Input

Dolphin will accept whatever your last button input was each frame. So if you press A, and then release A on the same frame, only the last action will matter and A will never be seen as pressed to the game.

Also, if you don't press a button, Dolphin will just use whatever you pressed last frame. So for example, if on frame 1 you press A, and on frame 2 you press Y, both A and Y will be pressed. The controller does not release buttons for you between frames. Though there is a helper function:

controller.release_all()

which will release all buttons and set all sticks / shoulders to neutral.

API Changes

Each of these old values will be removed in version 1.0.0. So update your programs!

  1. gamestate.player has been changed to gamestate.players (plural) to be more Pythonic.
  2. gamestate.x and gamestate.y have been combined into a named tuple: gamestate.position. So you can now access it via gamestate.position.x.
  3. projectile.x and projectile.y have been combined into a named tuple: projectile.position. So you can now access it via projectile.position.x.
  4. projectile.x_speed and projectile.y_speed have been combined into a named tuple: projectile.speed. So you can now access it via projectile.speed.x
  5. gamestate.stage_select_cursor_x and gamestate.stage_select_cursor_x have both been combined into the PlayerState cursor. It makes the API cleaner to just have cursor be separate for each player, even though it's a shared cursor there.
  6. playerstate.character_selected has been combined into playerstate.charcter. Just use the menu to know the context.
  7. playerstate.ecb_left and the rest have been combined into named tuples like: playerstate.ecb.left.x for each of left, right, top, bottom. And x, y coords.
  8. hitlag boolean has been changed to hitlag_left int
  9. ProjectileSubtype has been renamed to ProjectileType to refer to its primary type enum. There is a new subtype int that refers to a subtype.

OpenAI Gym

libmelee is inspired by, but not exactly conforming to, the OpenAI Gym API.

Metadata

Release files for melee 0.47.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for melee 0.47.5
File Size Uploaded
melee-0.47.5.tar.gz 589.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for melee 0.47.5
File Interpreter ABI Platform
melee-0.47.5-py3-none-any.whl Python 3 none any Details

Total release size: 1.2 MB

Release files / melee-0.47.5.tar.gz

Download URL melee-0.47.5.tar.gz
Size 589.0 kB
Tags Source
SHA-256 checksum
How to use checksums
8a517fb267129720fcbfe53176522f03e1bdb5d5011d78f50ebe11ea3131b669
BLAKE2b-256 checksum
How to use checksums
791cf84d430eace53b21649d6ddc7bc129d106cb79e83e183488e7c3f02459b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / melee-0.47.5-py3-none-any.whl

Download URL melee-0.47.5-py3-none-any.whl
Size 630.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
28951be33bfa19a9da0c0cfd7476197095fabbe323637768e123e74a2dcd9046
BLAKE2b-256 checksum
How to use checksums
ebd9d310adb2554c43a6a65b484e705642d04e12af610793356e352a8e952881
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.47.5 This release

2 release files

0.47.3

2 release files

0.47.0

2 release files

0.46.1

2 release files

0.46.0

2 release files

0.45.1

2 release files

0.45.0

2 release files

0.41.1

1 release file

0.40.1

1 release file

0.37.0

1 release file

0.36.0

1 release file

0.35.0

1 release file

0.34.0

1 release file

0.33.0

1 release file

0.32.3

1 release file

0.32.2

1 release file

0.32.1

1 release file

0.32.0

1 release file

0.31.0

1 release file

0.30.3

1 release file

0.30.2

1 release file

0.30.1

1 release file

0.30.0

1 release file

0.29.1

1 release file

0.29.0

1 release file

0.28.0

1 release file

0.27.0

1 release file

0.26.0

1 release file

0.25.0

1 release file

0.24.5

1 release file

0.24.4

1 release file

0.24.3

1 release file

0.24.2

1 release file

0.24.1

1 release file

0.24.0

1 release file

0.23.1

1 release file

0.23.0

1 release file

0.22.0

1 release file

0.21.4

1 release file

0.21.3

1 release file

0.21.2

1 release file

0.21.1

1 release file

0.21.0

1 release file

0.20.2

1 release file

0.20.1

1 release file

0.20.0

1 release file

0.19.6

1 release file

0.19.5

1 release file

0.19.4

1 release file

0.19.3

1 release file

0.19.2

1 release file

0.19.1

1 release file

0.19.0

1 release file

0.18.1

1 release file

0.18.0

1 release file

0.17.0

1 release file

0.16.3

1 release file

0.16.1

1 release file

0.16.0

1 release file

0.15.0

1 release file

0.14.0

1 release file

0.13.0

1 release file

0.12.0

1 release file

0.11.0

1 release file

0.10.2

1 release file

0.10.1

1 release file

0.10.0

1 release file

0.9.0

1 release file

0.8.1

1 release file

0.8.0

1 release file

0.7.8

1 release file

0.7.7

1 release file

0.7.5

1 release file

0.6.5

1 release file

0.6.4

1 release file

0.6.3

1 release file

0.6.2

1 release file

0.6.0

1 release file

0.5.3

1 release file

0.5.1

1 release file

0.5.0

1 release file

0.4.2

1 release file

0.1.0

1 release file

0.0.65

1 release file

0.0.64

1 release file

0.0.63

1 release file

0.0.62

1 release file

0.0.61

1 release file

0.0.60

1 release file

0.0.59

1 release file

0.0.58

1 release file

0.0.57

1 release file

0.0.56

1 release file

0.0.55

1 release file

0.0.54

1 release file

0.0.53

1 release file

0.0.52

1 release file

0.0.51

1 release file

0.0.50

1 release file

0.0.49

1 release file

0.0.48

1 release file

0.0.47

1 release file

0.0.46

1 release file

0.0.45

1 release file

0.0.44

1 release file

0.0.43

1 release file

0.0.42

1 release file

0.0.41

1 release file

0.0.40

1 release file

0.0.39

1 release file

0.0.38

1 release file

0.0.37

1 release file

0.0.36

1 release file

0.0.35

1 release file

0.0.34

1 release file

0.0.33

1 release file

0.0.32

1 release file

0.0.31

1 release file

0.0.30

1 release file

0.0.29

1 release file

0.0.28

1 release file

0.0.27

1 release file

0.0.26

1 release file

0.0.25

1 release file

0.0.24

1 release file

0.0.23

1 release file

0.0.22

1 release file

0.0.21

1 release file

0.0.20

1 release file

0.0.19

1 release file

0.0.18

1 release file

0.0.17

1 release file

0.0.16

1 release file

0.0.15

1 release file

0.0.14

1 release file

0.0.13

1 release file

0.0.12

1 release file

0.0.11

1 release file

0.0.10

1 release file

0.0.9

1 release file

0.0.8

1 release file

0.0.7

1 release file

0.0.6

1 release file

0.0.5

1 release file

0.0.4

1 release file

0.0.3

1 release file

0.0.2

1 release file

0.0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page