altf4 / libmelee Goto Github PK
View Code? Open in Web Editor NEWOpen Python 3 API for making your own Smash Bros: Melee AI that works with Slippi Online
License: GNU Lesser General Public License v3.0
Open Python 3 API for making your own Smash Bros: Melee AI that works with Slippi Online
License: GNU Lesser General Public License v3.0
FoD and Stadium, specifically.
FoD is easier, there's just two platforms and they change only in height. Finding their locations shouldn't be hard.
Stadium... is harder. There's a tree, and a windmill... I have no clue how it's stored or what the best way to read it would be.
I'm running into a problem with example.py
As far as I can tell, the setup looks good. Everything looks the same as it did when I used smashbot.
I recompiled the linked dolphin, and it loads melee 1.02 fine.
However when running example.py: Dolpgin can't start Melee as it errors out immediately with
Unknown Pointer 0x10000066 PC 0x8000522c LR 0x00000000
I can't find anyone else who has had this specific issue with Melee, only Paper Mario.
Any thoughts?
EDIT more info. This is specifically something that happens to dolphin itself upon running example for the first time that renders it unusable. But I can't find what happens in dolphin.py (I'm guessing) that causes it
Let's support reading from SLP files as a "console" backend. We can't meaningfully press buttons in this scenario, but it's useful for ML. Or any other applications that just want to read an SLP file from python
If you dash forward while not already in dashdance, you must dash forward initially for at least 3 frames before you can input a dash back. For any dashes which take place after a smash turn (i.e. an initial backdash, or any subsequent dashes), you can turnaround/dashback any time as soon as DASHING frame 1.
Right now, libmelee does not keep track of whether or not you're in this "initial dash" state
Melee does not store landing lag as simply as non lcanceled landing lag vs l canceled landing lag. For whatever reason, the stored landing lag animations are like, twice the duration of even a non l-canceled aerial, and it just skips frames for some reason. whenever you l-cancel, it just skips more frames at a time, and it's different for every aerial
For example
L canceled nair: (1, 5, 9, 13, 18, 22, 26) - 7 frames total, goes up by 4 each time
Non L canceled nair: (1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29) - 15 frames total, going up by 2 each time
L canceled dair: (1, 4, 7, 11, 14, 17, 21, 24, 27) - 9 frames total, going up by 3
Non L-canceled dair: (1, 2, 4, 6, 7, 9, 11, 12, 14, 16, 17, 19, 21, 22, 24, 26, 27, 29) - 18 frames total, going up by 1 OR 2
Issues related to installing are likely related to python 3.8.5 depreciated methods.
This is fixed by downgrading to python 3.7.
I compiled AltF4's version of Dolphin successfully, and running smashbot.py opens Dolphin, then I can select Melee from there using Open folder. However, I need to open the games directory to edit Gecko codes!! Without it I can't right click the Melee game button to change properties. Here is what my Dolphin looks like:
Did I not compile it right? The bot won't take control of Fox or move the cursor. Currently acts as if there isn't a bot, probably bc I don't have FD yet, not sure though. Any suggestions would be great, thanks.
It would be nice if I could identify what character is selected for the AI (I'm currently selecting it manually with a controller) instead of selecting it when calling the script (like in the example). The idea is that I will be able to change the RL player depending on the selection instead of restarting dolphin, which is kind of annoying. I would like to work on this, but, any ideas of where could I start @altf4?
Hi altf4,
I really appreciate the support of slp files in the console class.
I've noticed that older replay files (I've tested it with a file from Genesis 7) only ever have EventType
s PRE_FRAME
and POST_FRAME
(and GAME_END
once). The process is then stuck in this loop since frame_ended
won't turn True
.
Is there hope for these older replay files?
Some projectiles have neither hit nor hurboxes. Falco's Gun, for example, is its own "projectile". There's no reason to expose these over the libmelee API. Let's ignore all projectiles that have neither a hit nor hurtbox. They have no impact on the game and just mess up logic.
I'm not sure if you've been working on this or not but I was looking at the gamestate.py and was thinking why not just append the projectile objects themselves to the list?
Never mind the projectile list is already a list of projectile objects. What's wrong with appending that list to the gamestate list?
We need helper functions to be able to pull up information about every action in the game for every character. I'm imagining this would come in the form of a CSV file as the backend data, with helper functions to expose information including:
Hit/grab box sizes:
We need pywin32 for libmelee on windows, but only windows. Figure out how to add that to the pip install
Haven't tried since 0.52 but I would really enjoy being able to test bots against each other.
Do you plan on supporting a bot vs bot ecosystem?
(am attempting to adapt smashbot to play falco, have a friend who is thinking about a rest bot)
I followed your setup instructions by building dolphin from the commit here and installing your PyPI package. I run run ./dolphin-emu
and interact with the GUI just fine. However, when I try to start the game, I get the error
This does not seem to be a copy of Super Smash Bros. Melee. Please use regular Dolphin (https://dolphin-emu.org/) for running games other than Super Smash Bros. Melee.
I am confident it is not an issue with my ISO. I verified the checksum, and it works with both the official version of dolphin, as well as the slippi r18 build. My question is, should I be building dolphin from the exact commit I linked or is there a different version used to reproduce your results?
Run ./dolphin-emu
and manually select the ISO from the GUI. Running ./example.py -e PATH/TO/DOLPHIN
breaks with the same error
I should be able to launch the SSBM game either from inside dolphin or from the example.py
script
OS: Ubuntu 18.04
Python 3.6
Provide as much info as we possibly can about stage geometry for each stage. For an example, check out SmashBot C++ version:
https://github.com/altf4/SmashBot/blob/master/Util/GameState.cpp#L41
sys.exit(1)
is called without importing the sys package when exiting due to not finding Dolphin home directory.
Line 159 in af16292
NameError: name 'sys' is not defined exception is thrown instead of a graceful exit when the line is called.
Keep track of APM. Define what an "action" is in this context, too.
In RL, it's most convenient to train using time mode and with it to unlimited time.
Dude, this is an awesome idea! If you want some help, don't hesitate to share the roadmap 😃
Any familiarity with this issue?
libmelee git:(master) python example.py
Traceback (most recent call last):
File "example.py", line 2, in <module>
import melee
File "/Users/joeyleung/workspace/melee/libmelee/melee/__init__.py", line 10, in <module>
from melee import menuhelper, techskill, framedata, stages, dtmreader
File "/Users/joeyleung/workspace/melee/libmelee/melee/framedata.py", line 6, in <module>
from itertools import filterfalse
ImportError: cannot import name filterfalse```
Useful for RL warmup.
I am interested in adding the ability to modify game memory state (in order to implement training programs, among other things). Two questions:
Would the project owner (@altf4) be open to expanding the scope of the project to include this, or should I create my own fork?
Does Dolphin provide any mechanism for modifying memory address values?
Hi,
I tried to install the version of memorywatcher-rebased dolphin you linked, but it won't run properly on linux (ubuntu 18.04).
I then downloaded latest dolphin off github and rebased your changes on to it, however, the controller won't run. The code in example.py makes it all the way to the controller connection line but does not progress past that.
Do you have any fix for making the controller work? Any help would be amazing, as we are on a deadline for a project.
Thanks
The console documentation indicates that libmelee has yet to fully-support SLP files.
I was wondering what the current level of support is for SLP files. Can character positions (x/y) be retrieved with the current level of support?
In the character selection screen, it loops in the following block:
#Move up if we're too low
if ai_state.cursor_y < target_y - wiggleroom:
controller.tilt_analog(enums.Button.BUTTON_MAIN, .5, 1)
return
being, and not updating:
cursor_y: 1.9197228441864264e-40
cursor_x: 1.9196667922478534e-40
My version is:
─── dolphin-emu-nogui -version
Dolphin [memorywatcher] 5.0-523
We don't yet fully have support for all characters in the framedata. Currently missing:
Doc
Mario
Luigi
Bowser
Yoshi
DK
Ganondorf
Ness
Ice Climbers
Kirby
Link
Y Link
Pichu
Mewtwo
G&W
Roy
Of these, Ice Climbers is going to be the most challenging. Since there's two of them.... Making it so that it doesn't bork the whole API is going to be difficult. Much of the API and logic assumes that you only have one character at a time. I'll have to think about it.
Right now it uses gamestate.ai_state, but there are cases where you want several bots on several controllers.
Probably the best fix is for the Controller class to record the port and control using gamestate.player[controller.port].
Code currently has a lot of awkward path code. Switch over to fully using pathlib
Ran into a problem with libmelee when trying to set dolphin.run(render=False)
It work as intended but setting it back to true did not go back to original settings. It just continued to not render and run in lightning speed.
Tested: restarting my computer but it did not help.
Tested: going back to the original example code, did not work
What I needed to do in the end was going in to dolphin Options>Graphics Settings > General and change the back-end rendered manually
Libmelee needs a function to get the current location of Randall.
All that we ought to need is the current frame number to calculate the position.
Function should look like:
randall_position(frame)
And it should return a tuple (x, y) where X is the center of Randall and Y is the height of a player standing on Randall. The "center" of randall should be defined as the center point between the X positions of a character teetering on the edges.
It would be really nice to be able to get some values for the stage boundaries. (Blast zones)
IE: Final D: Left: -246.00, Top:188.00, Right: 246.00, Bottom: -140.00
I think I did this to myself, pretty positive actually.
But melee will pretty often skip the post-game altogether.
When a match is finished, the next frame is just the next match, skipping post-game, character select, and stage select.
The given example works fine, so its not my dolphin installation.
Nevertheless I can't find where I would have even enabled some sort of persistent game option.
There are some useful bits of derived information that ought to be exposed in an easy way. So that the caller doesn't need to constantly recompute it themselves:
Melee stores Sheik and Zelda as separate characters, both of which exist at all times. When you "transform", you're actually not changing into Sheik (in terms of the game's data structures) but rather Zelda goes into an invisible and inactive state. It's just like Nana/Popo.
libmelee currently doesn't even see Sheik / Nana, since we're only looking at one character. Look into what it would take to see Sheik / Nana. (It might be something as simple as an addition to Locations.txt, or it might be complicated and require a Dolphin patch)
We need to figure out what the minimum SLP version that libmelee is going to support, and reject things older than that.
Off the top of my head, 3.0.0 is probably it, since that's when a lot of important game state info got added.
In offline matches, what port your bot is playing on is pretty trivial to find. You have to configure it when you make the console and it doesn't change.
But in online matches, you're assigned a controller port essentially at random (it's not actually random, but it might as well be). So how are we supposed to know what port our bot and our opponent are on?
port_detector() is a little helper function that's pretty stupid. It just looks at the characters in the game and figures that your bot must bot on the port that is the correct character! If your bot plays Falco, then obviously it's the Falco in the Falco vs Marth.
But what happens when the match is a ditto? Well... we just sort of assume that the bot is on port one.
This is hard to fix, because the SLP spec only has player tags in the metadata field, which is computed after the game is over. We need to add it to the game start event, which is... tricky.
The code itself and a way to enable it
Is there a way to tell if a character is facing left or right on the screen? I am trying to be able to differentiate between di in/away rather than di left/right.
Let's generalize / cleanup the controller choosing code so that we can support multiple opponents and allies. Currently, libmelee assumes that there is exactly one AI player and exactly one opponent.
I'm bad at following written directions
Optional unit-circle based stick tilt, e.g. tilt_analog_unit(x, y) where x and y are unit vectors, or tilt_unit_degrees(float). tilt_unit_degrees could be useful for any change in degrees over time.
Character detection on Slippi occasionally faults if both players select the same character. (Or maybe the other player is also a bot who is performing the same character check...?)
controller.empty_input() renamed to controller.release_all()
Something basically like this:
https://youtu.be/_jdupqY9oxM?t=1m30s
Not sure of the best way to make it actually work yet.
An action's "action_counter" is an important number, to know what frame of an animation someone is in. Unfortunately, Melee is inconsistent on whether this counter starts at 0 or at 1. It depends on what animation it is.
Let's normalize this and make it so that every animation starts at frame 1. This is already (mostly) done in the C++ version of SmashBot here, but it needs to be ported in.
https://github.com/altf4/SmashBot/blob/master/Util/GameState.cpp#L1057
I know it's a little heretical to make something index from 1, but it makes our numbers make more intuitive sense. Don't think of this number as an index at all, in fact, but rather a counter. For instance, you may want to know when the hitbox of a particular attack first shows up. Suppose it's Fox's upsmash, which happens on frame 7. You'll do something like:
if opponent_state.action_frame == 7:
#do something here
I'd like to have Windows support in libmelee, but there's some roadblocks:
Dolphin talks to libmelee via its MemoryWatcher feature, using a Unix Domain Socket as the transport. As the name suggests, this doesn't exist on Windows. Some other roughly equivalent transport will have to be made there, and integrated into Dolphin's code.
Paths in libmelee will have to be updated to read Dolphin's config files on a Windows filesystem.
When trying to build from https://github.com/altf4/dolphin/tree/memorywatcher, I would get this error message when make
starting building the MemoryWatcher.cpp file.
/home/user/Projects/Smash/dolphin/Source/Core/Core/MemoryWatcher.cpp:147:74: error: too many arguments to function ‘void Memory::CopyFromEmu(void*, u32, size_t)’
if (!Memory::CopyFromEmu(&value, value + offset, sizeof(value), false))
^
In file included from /home/user/Projects/Smash/dolphin/Source/Core/Core/MemoryWatcher.cpp:14:0:
/home/user/Projects/Smash/dolphin/Source/Core/Core/HW/Memmap.h:75:6: note: declared here
void CopyFromEmu(void* data, u32 address, size_t size);
^~~~~~~~~~~
/home/user/Projects/Smash/dolphin/Source/Core/Core/MemoryWatcher.cpp:147:29: error: could not convert ‘Memory::CopyFromEmu(((void*)(& value)), (value + offset), sizeof (value))’ from ‘void’ to ‘bool’
if (!Memory::CopyFromEmu(&value, value + offset, sizeof(value), false))
~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/user/Projects/Smash/dolphin/Source/Core/Core/MemoryWatcher.cpp:147:74: error: in argument to unary !
if (!Memory::CopyFromEmu(&value, value + offset, sizeof(value), false))
^
Source/Core/Core/CMakeFiles/core.dir/build.make:5538: recipe for target 'Source/Core/Core/CMakeFiles/core.dir/MemoryWatcher.cpp.o' failed
I managed to fix this problem by instead using the memorywatcher-rebase
branch, and editing the MemoryWatcher.cpp file to match this commit: altf4/dolphin@97abbdd
Now I can run dolphin and use libmelee as intended.
After installing the package and running the example script, dolphin emulator keeps crashing with the error: Unknown Pointer 0x10000066 PC 0x8000522c LR 0x00000000
I've tried uninstalling with sudo apt-get purge --auto-remove dolphin
but this issue still persists even after reinstalling dolphin. Would appreciate any help so I don't have to reinstall Ubuntu.
I'm curious about writing a bot to play like a human. I would do this by playing many games and recording my inputs and making the bot "play like me" using supervised learning rather than reinforcement learning.
Is there an easy way to get controller inputs / actions from libmelee?
Thanks in advance,
Jack McKeown
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.