tatatat0
Smash Journeyman
- Joined
- Jan 28, 2015
- Messages
- 412
Hey
Achilles1515
, where did you even find the data for AI at? Do you have any notes on how it is structured?
![Achilles1515](/data/avatars/s/64/64966.jpg?1360760931)
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!
Yeah, my other point was about how Article FP and some other things have redundant pointers. I understood why the Entity struct did that, at least in the context of items and whatnot.Just wanted to chime in that the entity data is not always immediately after the entity structure. This is normally the case for entitys not spawned at the beginning of the match, like items and characters (multi-man matches for example). I just fixed a bug in the newest 20XX where Crazy Hand in Classic Mode was not dying properly. I was loading the internal character ID from 0x64(r3), when I should have been doing it the way the game does; lwz r4,0x2c(r3) and then lwz r4,0x4(r4). Crazy Hand's data was not immediately after his struct because he gets spawned mid-match.
Nothing to report on the vanilla AI. I know nothing about it. For the 20XX AI, I just wrote a custom function to follow my own logic for button presses.HeyAchilles1515 , where did you even find the data for AI at? Do you have any notes on how it is structured?
Alright, I finally figured out what was wrong with the code you gave me.To get rtStart, you needed to add 0x20 to the pointer in the header. All pointers don't count the header so that they're relative to the start of the data block.
As I mentioned, this function won't touch the subactions or anything else that's not a pointer referenced by the pointer/relocation table (aside from moving them ahead in the file by 0x3C if they originally appeared at or after 0x4a30). It just adds more space to the structure at the specified place, and adjusts the other structures so that their pointers are correct, which is still necessary if you want more commands than there's space for. I don't know what you want to do with the subactions though.
Also, btw, instead of outputting to a text file and then copying over the data to another file using a hex editor, you could use the write method to open the new file in binary mode, and then write bytes to the file rather than hex. To do this, instead of using "w+" for the second argument to write, use "w+b". And then when you write the data to it, use "datfile.write( bytearray.fromhex(datData) )". bytearray.fromhex() encodes the data as a byte array. I noticed you don't have the new header being output to the new file, which you could do at the same time, e.g. "datfile.write( bytearray.fromhex(datDataHeader+datData) )".
# If the pointer appears after the change, update its address in the relocation table accordingly.
if rtEntryValue >= offset:
newRtEntryValue = rtEntryValue + diff
datData = replaceHex( datData, rtEntryAddress, "{0:0{1}X}".format(newRtEntryValue, 8) )
entriesUpdated += 1
def extendDataSpace( offset, diff):
""" This function will expand the data area at the given offset, starting at the first argument. The second argument is the amount to increase by.
All pointers occurring after the sum of the two arguments will be recalculated. """
def replaceHex(hexData, offset, newHex): # Input takes a string, int, and string, respectively.
offset = offset * 2 # Doubled to count by nibbles rather than bytes, since the data is just a string.
codeEndPoint = offset + len(newHex)
"""
print(type(hexData))
print (offset)
print(codeEndPoint)
"""
return hexData[:int(offset)] + newHex + hexData[int(codeEndPoint):]
"""
def deHex(hex_num):
numerals = []
for i in hex_num:
numerals.append(i)
numerals.reverse()
new_values = []
for i in range(0,len(numerals)):
try:
new_values.append(numerals[i] * (16 ** i))
except ValueError:
num_val = numerals[i]
if num_val == "A":
new_values.append(10 * (16 ** i))
elif num_val == "B":
new_values.append(11 * (16 ** i))
elif num_val == "C":
new_values.append(12 * (16 ** i))
elif num_val == "D":
new_values.append(13 * (16 ** i))
elif num_val == "E":
new_values.append(14 * (16 ** i))
elif num_val == "F":
new_values.append(15 * (16 ** i))
new_number = 0
numerals=[]
for i in new_values:
new_number + i
return new_number
"""
global datDataHeader, datData, rtData, after
if datDataHeader != '' and datData != '' and rtData != '' and after !='':
#After is the data right after the rtData
# Update the file header with the new file size and start of the relocation table.
filesize = int(datDataHeader[:8], 16)
newFilesize = filesize + diff
rtStart = int(datDataHeader[8:16], 16) # Size of the data block
newRtStart = rtStart + diff
datDataHeader = replaceHex(datDataHeader, 0, "{0:0{1}X}".format(newFilesize, 8) + "{0:0{1}X}".format(newRtStart, 8))
# For each entry in the relocation table, update the address it points to, and the value of the pointer there, if they point to locations beyond the extended space.
entriesUpdated = 0
pointersUpdated = 0
for nib in range(0, len(rtData), 8):
rtEntryNum = (nib/8)
rtEntryAddress = rtStart + (rtEntryNum * 4)
rtEntryString = rtData[nib:nib+8]
rtEntryValue = int(rtEntryString, 16) # i.e. the pointer address
"""
if nib >= 200:
print ("rtEntryString: ", rtEntryString)
print ("rtEntryValue: ", rtEntryValue)
input("S")
exit()
"""
pointerString = datData[rtEntryValue * 2:(rtEntryValue + 4) * 2] # Multipled by 2 because this is per character/nibble, not per byte.
"""
print ("rtStart: ", rtStart)
print ("Num: ", rtEntryNum)
print ("String: ", rtEntryString)
print ("Address: ", rtEntryAddress)
print ("Start: " , rtEntryValue*2)
print("End: ", (rtEntryValue+4)*2)
print ("Len: ", len(datData))
print ("Pointer string: ", pointerString)
print ("Len of pointer string: " + str(len(pointerString)))
print (type(pointerString))
"""
pointerValue = int(pointerString, 16)
# If the pointer appears after the change, update its address in the relocation table accordingly.
if rtEntryValue >= offset:
newRtEntryValue = rtEntryValue + diff
datData = replaceHex(datData, rtEntryAddress, "{0:0{1}X}".format(newRtEntryValue, 8))
#print ("rtEntryAddress: " + str(rtEntryAddress))
#print ("Old data: ", rtEntryValue)
#print ("New Data: ", "{0:0{1}X}".format(newRtEntryValue, 8))
#input("S")
#exit()
entriesUpdated += 1
else: #doesn't just ignore unused stuff
datData = replaceHex(datData, rtEntryAddress, "{0:0{1}X}".format(rtEntryValue, 8))
# If the place that the pointer points to is after the space change, update its value accordingly.
if pointerValue >= offset:
newPointerValue = pointerValue + diff
datData = replaceHex(datData, rtEntryValue, "{0:0{1}X}".format(newPointerValue, 8))
pointersUpdated += 1
# Fill the newly extended space with zeros. (Values doubled to count by nibbles rather than bytes, since the data is just a string.)
datData = datData[0:offset * 2] + '0'.zfill(diff*2) + datData[offset * 2:]
datfile = open(str(random.randrange(0,10)) + str(random.randrange(0,10)) + str(random.randrange(0,10)) + str(random.randrange(0,10)) + str(random.randrange(0,10)) + ".txt", "w+")
datfile.write(datDataHeader + datData + after)
datfile.close()
http://smashboards.com/threads/craz...-editing-program.389500/page-22#post-20923497Is there any way to translate the units of hitbox size into direct x/y size used for player positions?
Any idea why it is that number? I mean there has to be something special about that particular number. Hmmm. Well still, thanks for the info!
Nope.Any idea why it is that number? I mean there has to be something special about that particular number. Hmmm. Well still, thanks for the info!
That is a texture for "magnifying glass" character.for sh*ts and giggles i tried this and replaced the png but nothing happened, ganon is still ganon, what did i go wrong?
Any idea why it is that number? I mean there has to be something special about that particular number. Hmmm. Well still, thanks for the info!
When in doubt, take number and do this: 1.0 / numberNope.
Hey, pay up on that script mate. Its still not working. Did you leave something out of it that seemed to be out of context or did the script even work in the first place.Do my eyes deceive me...?
The renowned and rare revel reappears! (And ripe with reciprocal revelations.)
It definitely works on my end, since I've used it to create several working files (which I've also shared as part of various hacks, and no one mentioned that the files didn't work). There are a number of things you're doing differently than my implementation. And I've never done anything with subactions, meaning A) I don't know about those, and B) the function isn't going to touch them (unless there's anything in the rtTable pointing to something within them). As I said in the beginning though, if you'd like, you can send the file to me and tell me what area you'd like to extend and I can do it. Or if you still want to get your script working, PM me and I'll help you work on it.Hey, pay up on that script mate. Its still not working. Did you leave something out of it that seemed to be out of context or did the script even work in the first place.
Awesome video! The kill at 1:15 was my favorite. Did you make this the SDR male wireframe toggle?What if Wire Frame was Angry?
SuperMaleWireFrame: https://drive.google.com/open?id=0B33JtWjcXD2WUUh6NUhSQlNmcmc
Filesize: Relocation Table Address: End of Relocation Table: Relocation Table Entries:
Melee: 0x3F70A 0x3BD00 0x3F6D8 0xE7E
PoR: 0x5C49 0x4C58 0x5C38 0x3F8
It seems more like he physically swapped the characters being played in whatever wireframe mode he is playing. I think this because of the sound effects of the "wireframes", the different stock icons, and the fact that the wireframes can use special moves while he seems to not be able to.Awesome video! The kill at 1:15 was my favorite. Did you make this the SDR male wireframe toggle?
The dat file format is not exclusive to HAL. HAL was involved in the creation of a library called sysdolphin which was used by numerous developers on nintendo platforms as a starting point for development on the system at the time. So there can be seen a number of games that have similar formats. Sonic Unleashed and Pokemon Colosseum use modified versions of the formats, and i am sure there are many others that originally started with them. Melee just happens to also use the library. You can find references to sysdolphin within the binary.Now I have heard before that .dat files are a proprietary or otherwise unique format created by HAL laboratory, but I think this proves otherwise.
SDR?Awesome video! The kill at 1:15 was my favorite. Did you make this the SDR male wireframe toggle?
He means the SDR toggles in 20XX. I believe it is hold L/R while selecting a character or something like that to use the SDR toggles.SDR?
I used 20XX.
Oh, I see.He means the SDR toggles in 20XX. I believe it is hold L/R while selecting a character or something like that to use the SDR toggles.
This sounds really interesting and I could give you some more info on it but I bet someone likeHey everyone! Me and a buddy have been really interested in neural networks lately so we want to try and make a neural network that learns to play Melee. We're CS majors so we know a decent amount. We are trying to extract data from melee to use to train the neural network. Some examples of data we want would be to feed to the neural network would be the percentage of each player and their position and current state. We have all the Dolphin source code running and debugging at the moment. We'd like to edit the source code to log the data we need to a file. Ideally this file would have a log of data for every frame during a game: percentages, positions, ect. Does anyone have any experience with the Dolphin source code that would know the best way to implement this? Or if you have any better ideas to how to do this that would be great too.
Source/Core/Core/GeckoCode.cpp uses every method you'd need to do it on Dolphin through Windows or Linux.Hey everyone! Me and a buddy have been really interested in neural networks lately so we want to try and make a neural network that learns to play Melee. We're CS majors so we know a decent amount. We are trying to extract data from melee to use to train the neural network. Some examples of data we want would be to feed to the neural network would be the percentage of each player and their position and current state. We have all the Dolphin source code running and debugging at the moment. We'd like to edit the source code to log the data we need to a file. Ideally this file would have a log of data for every frame during a game: percentages, positions, ect. Does anyone have any experience with the Dolphin source code that would know the best way to implement this? Or if you have any better ideas to how to do this that would be great too.
Source/Core/Core/GeckoCode.cpp uses every method you'd need to do it on Dolphin through Windows or Linux.
If you want to do it outside of Dolphin, look into Dolphin's memory watcher used by other bots.
Thanks for the info guys! I've seen that table before tatatat0 and it's extremely useful. Seems like I'll be able to get all the character data I need from it. I might have slightly mislead you though. I don't really need help with any of the Melee ASM code. I've probably done more ASM coding than anything else, and have made some Gecko codes and small mods for melee in the past for fun. Also, we aren't planning on doing any modifications to the melee code, at least not for now. We just need to read some of the character data memory addresses every frame and log them.This sounds really interesting and I could give you some more info on it but I bet someone likeAchilles1515 or @Dan Salvato would love working on it with you directly, since they have more experience on the ASM side of this. Anyways, if you want to check some stuff out yourself you can look at https://docs.google.com/spreadsheets/d/1JX2w-r2fuvWuNgGb6D3Cs4wHQKLFegZe2jhbBuIhCG8 . Hopefully you guys can make a youtube video of something of this when you are done, because this sounds like an amazing idea that I actually think has been talked about before but never done. Actually maybe I can give you a hint on the basis of how you could gather this data. You'd want to start by every frame iterating through the character's datas at (
0x80453130,
0x80453FC0,
0x80454E50,
0x80455CE0
) respectively.
Percent can be gathered at 0x60 from the address pointed to, stocks left at 0x8E, Suicides at 0x8C. Some other useful stuff might be the total player attack count at 0xE8,
Total Connected Attacks at 0xF0,
Total Damage Received at 0xD1C, and Total Damage Given at 0xD28)
Now after you gather whatever you want from there you're going to want to go to the address pointed to at 0xB0. in there at 0xB0 and 0xB4 you can find the horizontal and vertical position of the player respectively. I'm assuming thats the sort of data you would need.
http://www.gc-forever.com/yagcd/chap4.html#sec4What I am struggling with is editing Dolphin to do this. The Dolphin source code is slightly big and overwhelming so I'm not exactly sure where to look. So far my search has led me Memmap.cpp where I am looking at the Read functions. They seem to return the value at the GC memory address passed to them, which I think is exactly what I want. However, it says that GC RAM exists from 0x00000000 to 0x02000000 but the memory addresses in the Melee spreadsheet are all around 0x80xxxxxx. Now, before I embarrass myself, I'm almost positive I ran into this exact problem when I was doing work with Melee ASM, but it has been a long time and I don't remember what I ended up figuring out.
I'm not sure if what you are doing is similar to Playfun and MarI/O, which are two examples of neural networks that I have seen, but there is a lot of things you could base fitness or "What is good" for the AI to potentially learn. I don't really know what it would be called because I haven't done indepth research into this topic really but I think you can understand. If you do get that input working there are a lot of other things that could be factors or w/e you want to call them for "what is good" or things for the bot to potentially watch like doing different things during action states(Jumping, running, etc..), stale moves (such as having more of the same move in the stale move index lowering fitness or something), knockback angle being launched from (at 0x18A8 from character data), hitlag currently being suffered at (0x19BC), shield size at (0x19F8), and maybe some other stuff. I don't really know what you are planning to do or how much data you plan on letting the AI use but there is a lot of possibilities for data to be read in various ways. Like it could learn DI patterns, SDI, Not shielding at low shield size, or being a dumbass and getting its shield broken. Anyways, thats all I have for input on the subject probably, as I have no clue how such a AI would be formatted or structured. Seems pretty neat though.Thanks for the info guys! I've seen that table before tatatat0 and it's extremely useful. Seems like I'll be able to get all the character data I need from it. I might have slightly mislead you though. I don't really need help with any of the Melee ASM code. I've probably done more ASM coding than anything else, and have made some Gecko codes and small mods for melee in the past for fun. Also, we aren't planning on doing any modifications to the melee code, at least not for now. We just need to read some of the character data memory addresses every frame and log them.
What I am struggling with is editing Dolphin to do this. The Dolphin source code is slightly big and overwhelming so I'm not exactly sure where to look. So far my search has led me Memmap.cpp where I am looking at the Read functions. They seem to return the value at the GC memory address passed to them, which I think is exactly what I want. However, it says that GC RAM exists from 0x00000000 to 0x02000000 but the memory addresses in the Melee spreadsheet are all around 0x80xxxxxx. Now, before I embarrass myself, I'm almost positive I ran into this exact problem when I was doing work with Melee ASM, but it has been a long time and I don't remember what I ended up figuring out.
BTW, our goal with this project is to have a neural network learn how you play and inherit your play style, which neural networks are extremely good at. If it is successful, a pro could use our project and let a neural network learn their play style. This neural network could be distributed so that anyone could "practice against the pro". That's the dream anyways :D
Again, thanks for the help guys!
Those are NN are running on deterministic games. Most NN aren't very good with non-determinism, which any game involving another player is (unless it's only fighting Melee's bots). That's why for the most part, I think it's a square peg in a circular hole issue, as a I said to the last few people talking about NNs.I'm not sure if what you are doing is similar to Playfun and MarI/O
Regarding modifying the angle/positions of char select icons, Im fairly certain each one is a bone struct. So yeah, just keep backtracking from the texture struct.What do we know about MnSlChr's file structure?
I know @zankyou was able to modify the angle/positions of the selection icons, but I'm doubting that that was done using the Texture Structures (though I haven't found the time to test that yet).
And I knowAchilles1515 found data on the selection regions (including position data), but that was in RAM only.
Specifically, I'd like to know more about the structures. (i.e. does it have object/material structures? what else is above those if they're there?) I'm starting to look into it myself, but I thought I'd first ask if there's already any info documented on it.
I wrote some notes on it, check the here.Regarding modifying the angle/positions of char select icons, Im fairly certain each one is a bone struct. So yeah, just keep backtracking from the texture struct.
But idk about overall root structure.
I've looked over the video myself when it was first released and concluded that very little to none of the things it shows would actually be possible right now. It is really cool though.