hohav / py-slippi

Python library for parsing SSBM replay files
MIT License
56 stars 25 forks source link

==================================== ⚠️ py-slippi is no longer maintained

I recommend peppi-py <https://github.com/hohav/peppi-py>_ instead.

========= py-slippi

Py-slippi is a Python parser for .slp <https://github.com/project-slippi/slippi-wiki/blob/master/SPEC.md>_ game replay files for Super Smash Brothers Melee <https://en.wikipedia.org/wiki/Super_Smash_Bros._Melee> for the Nintendo GameCube. These replays are generated by Jas Laferriere's Slippi <https://github.com/JLaferri/project-slippi> recording code, which runs on a Wii or the Dolphin <https://dolphin-emu.org/>_ emulator.

Installation

Requires Python >= 3.7. To install, run the following command (optionally inside a virtual environment <https://packaging.python.org/tutorials/installing-packages/#optionally-create-a-virtual-environment>_):

pip install py-slippi

API Docs

See the Module Index <https://py-slippi.readthedocs.io/en/latest/py-modindex.html> for detailed API docs, starting with slippi.game <https://py-slippi.readthedocs.io/en/latest/source/slippi.html#module-slippi.game>.

Usage

py-slippi supports both event-based and object-based parsing. Object-based parsing is generally easier, but event-based parsing is more efficient and supports reading partial or in-progress games.

Object-based parsing::

>>> from slippi import Game
>>> Game('test/replays/game.slp')
Game(
    end=End(
        lras_initiator=None,
        method=Method.CONCLUSIVE),
    frames=[...](5209),
    metadata=Metadata(
        console_name=None,
        date=2018-06-22 07:52:59+00:00,
        duration=5209,
        platform=Platform.DOLPHIN,
        players=(
            Player(
                characters={InGameCharacter.MARTH: 5209},
                netplay_name=None),
            Player(
                characters={InGameCharacter.FOX: 5209},
                netplay_name=None),
            None,
            None)),
    start=Start(
        is_frozen_ps=None,
        is_pal=None,
        is_teams=False,
        players=(
            Player(
                character=CSSCharacter.MARTH,
                costume=3,
                stocks=4,
                tag=,
                team=None,
                type=Type.HUMAN,
                ucf=UCF(
                    dash_back=DashBack.OFF,
                    shield_drop=ShieldDrop.OFF)),
            Player(
                character=CSSCharacter.FOX,
                costume=0,
                stocks=4,
                tag=,
                team=None,
                type=Type.CPU,
                ucf=UCF(
                    dash_back=DashBack.OFF,
                    shield_drop=ShieldDrop.OFF)),
            None,
            None),
        random_seed=3803194226,
        slippi=Slippi(
            version=1.0.0),
        stage=Stage.YOSHIS_STORY))

Frame data is elided when you print games, but you can inspect a sample frame with e.g. :code:game.frames[0].

>>> from slippi import Game
# pass `skip_frames=True` to skip frame data, for a significant speedup
>>> Game('test/replays/game.slp', skip_frames=True)

Event-driven API::

>>> from slippi.parse import parse
>>> from slippi.parse import ParseEvent
>>> handlers = {ParseEvent.METADATA: print}
>>> parse('test/replays/game.slp', handlers)
Metadata(
    console_name=None,
    date=2018-06-22 07:52:59+00:00,
    duration=5209,
    platform=Platform.DOLPHIN,
    players=(
        Player(
            characters={InGameCharacter.MARTH: 5209},
            netplay_name=None),
        Player(
            characters={InGameCharacter.FOX: 5209},
            netplay_name=None),
        None,
        None))

👉 You can pass a stream to :code:parse, such as :code:sys.stdin.buffer! This is useful for e.g. decompressing with :code:gunzip, or reading from an in-progress replay via :code:tail -c+1 -f.