• Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!

    You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!

Melee Bot Resources

paulpaul

Smash Rookie
Joined
Aug 28, 2019
Messages
4
HI. I've been trying to develop a SSBM Bot to play the game with machine learning. Not being able to script through Dolphin directly has been my biggest hurdle so far. I have found a lot of resources on here or other places from people who have already made bots, but I can't find a singular place with all the available resources. Is there an existing thread with all the compiled resources someone could link me to, or maybe an external document like the SSBM Data Sheet (1.02)? Once things get down to assembly language and reading from exact memory addresses, for instance, the threads become really hard to follow. D:

If anyone knows or can point me in the right direction, I'd appreciate it a lot!! I'm trying to code for Ness, just bc he's the glitchiest character and I love him :)
 

paulpaul

Smash Rookie
Joined
Aug 28, 2019
Messages
4
Okay no takers so far. I'm going to update this thread as I find things.

Melee Datasheet for game data memory addresses. Still unsure how to make use of these specific addresses.

This extensive thread about DOL mods. I'm hoping DOL stands for Dolphin, but I have to read more of it to find out for sure. There is a lot of information pertaining to memory addresses and how to modify them. It's a very old thread, but melee is an even older game.
Sham Rock's post on page five is worth looking at.

Assembly Guides. Here's a great thread with a lot of resources already, made for Assembly guides. I want my thread to be specifically for creating a bot though, so I don't think this is quite enough to delete this thread. Also it's 4 years old.

AltF4's SmashBot github repo. This guy did exactly what I want to do. He made some resources if someone wants to create their own bot, but the MemoryWatcher version of Dolphin is very outdated. I got it to compile Linux OS, but couldn't get the actual bot to take control. If anyone thinks they know something I did wrong on that, I'd love to hear it, but for now this option is only a reference.
 
Last edited:

SinsOfApathy

Smash Journeyman
Joined
Feb 24, 2015
Messages
474
NNID
Psion312
Paul,

I'm not sure if you're the guy I replied to on Reddit about the subject, but you could look into something like pattern scanning and hooking.

Dolphin has a Memory::GetPointer function that interprets the emulated addresses to its own virtual, and you can build a DLL hook to utilize that. That will give you the information needed to read/write from emulated memory. From there, you convert byteswap the endianess from BE to LE, assuming you're on that architecture.

This is my toy example with Melee:
https://github.com/PsiLupan/DolHook-Melee/blob/master/src/main.cpp

And here's a bot API for Guild Wars 1 doing similar.
https://github.com/GregLando113/GWCA
 

paulpaul

Smash Rookie
Joined
Aug 28, 2019
Messages
4
Hi! Sorry for such a late response, I was moving and doing university. You might have been! I post now and then about this on reddit.

I understood............. most! of those words. I can see how a GetPointer function could interpret emulated addresses, but I don't know how to set up a DLL hook, or even how it works really. Would I have to write my own, or could I find code for one I can use online somewhere? And I think I know what you mean by byteswap the endianess, like turn a backwards flowing address forwards, but what does that have to do with architecture, and why would an architecture make it so it has to be byteswaped or not?

I'm trying to read your code right now. I'm not very fluent in C++ and there are a lot of naming conventions I'm unfamiliar with, but I'll edit when I finish it!

edit: That was really interesting. It took a couple read throughs to get a good idea of what the code was doing, but I see it's getting a lot of info and doing a lot of gamestate checks by poking at various addresses. That is a big part of what I'm trying to grab so this seems like a great basis to eventually grab more exact game checks, like if the other player is doing a specific move. Like a like a frame-by-frame moveset checker could return what frame the opponent starts charging Fsmash. Am I thinking of that right?
 
Last edited:

SinsOfApathy

Smash Journeyman
Joined
Feb 24, 2015
Messages
474
NNID
Psion312
Hi! Sorry for such a late response, I was moving and doing university. You might have been! I post now and then about this on reddit.

I understood............. most! of those words. I can see how a GetPointer function could interpret emulated addresses, but I don't know how to set up a DLL hook, or even how it works really. Would I have to write my own, or could I find code for one I can use online somewhere? And I think I know what you mean by byteswap the endianess, like turn a backwards flowing address forwards, but what does that have to do with architecture, and why would an architecture make it so it has to be byteswaped or not?

I'm trying to read your code right now. I'm not very fluent in C++ and there are a lot of naming conventions I'm unfamiliar with, but I'll edit when I finish it!

edit: That was really interesting. It took a couple read throughs to get a good idea of what the code was doing, but I see it's getting a lot of info and doing a lot of gamestate checks by poking at various addresses. That is a big part of what I'm trying to grab so this seems like a great basis to eventually grab more exact game checks, like if the other player is doing a specific move. Like a like a frame-by-frame moveset checker could return what frame the opponent starts charging Fsmash. Am I thinking of that right?
For the DLL hook, I use Rafzi's hacklib, since it has some built in functionality. Other people tend to use minhook, like GWCA does that I linked.

PowerPC that the Wii and GC ran is Big Endian, whereas your typical x86 computer is Little Endian. If you don't byteswap and tried to use a something like frame data, you would a completely incorrect value because the different byte ordering.

There's an example of it in my code, I believe, but yeah, you'd have to find the first player pointer, then read the offsets of the Player struct to get frame data, action state, etc.. From there, you could interpret it however you like.
 
Top Bottom