Joined: 6/24/2007
Posts: 119
I am interested in this but will need some help. Would anyone be interested in watching this if I finish it? It would be good to have the memory addresses such as x,y position of Barry and his stored energy. Also, it would be very helpful if there is a lua script to show the hitbox height of goons as well as their x distance from Barry. This is because Barry's long jump appears to be in a symmetric parabola and he can jump over some goons when they are in their attacking sprite. Thanks.
Active player (279)
Joined: 4/30/2009
Posts: 791
Yes, I'd be interested in this at least - one of the GB games I had growing up. Easy way to find x/y positions is to search for them yourself. VBA's RAM Search feature is all you need. Have Barry move slightly left and right to search for x, and jump to search for y. Once you figure out these basics, it may help you get to understanding more memory addresses
Editor, Skilled player (1203)
Joined: 9/27/2008
Posts: 1085
A lua script for hitboxes is actually a pretty tall request. Sure, you paint boxes, how hard can that be? Unfortunately, the person making the script has to find out how the game handles it. Where in memory it is. All that stuff. And code up a script to handle that. Since this thread creation, I was working at the script. No, not every minute of the day, but I spent a fair amount of time on it. This should give an idea on the effort needed to fulfill your request. I did not mention I was working on it so that there would be no chance to disappoint you should I fail on the script. I must warn, however, I did not get the camera worked out fully. Expect glitches with the lua display. Still, this is probably more than what you had before. EDIT: The warning applies less now. I've faked up a good upper byte for the camera now. I assume Barry is always onscreen, and pick an upper byte for the camera accordingly. Download TheFlashHitboxes.lua
Language: lua

local R1u, R1s= memory.readbyte, memory.readbytesigned -- 1 byte local R2u, R2s= memory.readword, memory.readwordsigned -- 2 byte Little endian --***************************************************************************** local function u2R(a) return R1u(a)*256 + R1u(a+1) end -- 2 byte Big endian local function s2R(a) return R1s(a)*256 + R1u(a+1) end -- 2 byte Big endian --***************************************************************************** --memory.readword fails. Numbers in The Flash are big endian. --***************************************************************************** local function HexStr(v) --***************************************************************************** -- Returns a string. If it's negative, specifically forces a negative sign -- instead of returning "FFFFFFxx" stuff. local str= "" if v < 0 then str= "-" v= -v end return str .. string.upper(string.format("%x",v)) end --***************************************************************************** local function GuiTextRight(x,y,str,c1,c2) --***************************************************************************** -- The default for gui.text is left-justified. This is right-justified. -- Specify the right-side pixel instead of the left. -- Ideal for when you are listing numbers, as the magnitude of each digit are -- aligned for easy comparison. str= tostring(str) x= x - (#str)*4 gui.text(x,y,str,c1,c2) end -- 0xC2A0 -- Start of the array containing character information. -- Data size is 0x36. So the second character has info stored in 0xC2D6 -- Apparently, there's room for 23 of these things. --***************************************************************************** local function PutHitbox(obj, CamX, CamY) --***************************************************************************** -- Paints a hitbox. It wants the object base address and camera position. gui.box( math.floor(u2R(obj+0x10)/16) - CamX, -- Left math.floor(u2R(obj+0x12)/16) - CamY, -- Top math.floor(u2R(obj+0x14)/16) - CamX, -- Right math.floor(u2R(obj+0x16)/16) - CamY, -- Bottom 0, -- Fill color (Transparant) 0x0040FFFF -- Border color (Blue) -- If you need 0x80 red or higher, switch to strings "#FF0000FF", as -- a numeric 0x800000FF fails due to the 80Red glitch. ) end --***************************************************************************** local function FakeCamPos() --***************************************************************************** -- Gets the camera position. Actually, fakes the camera position. This uses -- Barry's position to produce the upper byte for the camera. local obj= 0xC2A0 -- The Barry object is located here -- But first, check if Barry exists... Assume he's always the first object. if R1u(obj) == 0xFF then return R1u(0xC145), R1u(0xC146) end -- Now we assume the camera has the greatest possible value that's less than -- Barry's position. local CamX, CamY= R1u(0xC145), R1u(0xC146) local UpperByte= math.floor((u2R(obj+1)/16 - CamX)/256) CamX= CamX + UpperByte*256 UpperByte= math.floor((u2R(obj+3)/16 - CamY)/256) CamY= CamY + UpperByte*256 return CamX, CamY end local StartAddr= 0xC2A0 --***************************************************************************** local function IterateObjects() --***************************************************************************** -- Will go through all 23 objects. local CamX, CamY= FakeCamPos() for i= 0, 22 do local obj= StartAddr + 0x36*i if R1u(obj) ~= 0xFF then -- Does the object exist? PutHitbox(obj, CamX, CamY) end end end gui.register(IterateObjects) -- I prefer the gui over "boundary" -- 0xC2A0 [size=0x36][count=23] Object Array -- +0x00,1x Object ID. 0xFF = No object All 2-byte values -- +0x01,2u X position are assumed to be -- +0x03,2u Y position big endian unless -- +0x05,2s X velocity noted otherwise. -- +0x07,2s Y velocity -- +0x08, -- +0x09, -- +0x0A, -- +0x0B, -- +0x0C, -- +0x0D, -- +0x0E, -- +0x0F, -- +0x10,2u Hitbox, left -- +0x12,2u Hitbox, top -- +0x14,2u Hitbox, right -- +0x16,2u Hitbox, bottom -- +0x18,2u Hitbox, left (mirror?) -- +0x1A,2u Hitbox, top (mirror?) -- +0x1C,2u Hitbox, right (mirror?) -- +0x1E,2u Hitbox, bottom (mirror?) -- +0x20, -- +0x21, -- +0x22, -- +0x23, -- +0x24, -- +0x25, -- +0x26, -- +0x27, -- +0x28, -- +0x29, -- +0x2A, -- +0x2B, -- +0x2C, -- +0x2D, -- +0x2E, -- +0x2F, -- +0x30, -- +0x31, -- +0x32, -- +0x33, -- +0x34, -- +0x35,
Incidentally, the upper byte of the camera position does not need to exist in the game. The hitboxes themselves have all the information necessary to tell when there's a collision, and this does not require a camera. And if that upper byte does not exist, a strange method will need to be used to fake one up to get rid of most of these glitches. Said strange method is using Barry's position to guess the actual camera location.
Joined: 6/24/2007
Posts: 119
I appreciate the script, was planning on looking at the fighting game hitbox one to try to figure it out. I will try it out and feedback. I was actually thinking of doing the TAS via scripts. eg keep velocity high and frame advance, and have scripts for the long jump, running and kicking keypresses. Would this be a good method?
Editor, Skilled player (1203)
Joined: 9/27/2008
Posts: 1085
Now you're asking about something that goes beyond just information. A script that handles keypresses for you is either a macro (largely independent of internal game states, generally a static set of keypresses that can apply to many situations) or a bot (typically reads game memory to calculate what to do or to determine whether success happened). Producing a botting script is outside of my comfort zone. And asking me to make such a script would involve sinking far more of my time than I'm willing to give. In particular, I would have to spend days studying the game mechanics, among other things, to come up with a reasonable bot that can handle a single jump. It's not a bad idea to have scripts that can handle things for you, anything that would be simple yet tedious or repetitive to do manually... Provided that you can get access to such a script. Regardless, if you still want to produce the scripts yourself, I will be happy to walk through the process with you. If not, that's fine too, as either way you go, you'll spend some time on the game to get a well-optimized TAS going.
Joined: 6/24/2007
Posts: 119
No I meant I will do it myself, just whether it is an efficient way or is there an easier way. You have done a lot already thanks.
Editor, Skilled player (1203)
Joined: 9/27/2008
Posts: 1085
Ah, I misunderstood. Whether it's efficient generally depends on how many places you can rely on the script. If the game is short, it's usually best to just do things manually, since you won't be doing that manual work too often anyway. But there are still some short runs (Wizardry for NES) that needed extensive botting. And you're welcome. Hope to see how much use you get from the hitbox script. (Some information scripts can still get pretty tricky. One I'm holding on to, for a different game, allows me to see off-screen hitboxes and calculates the exact RNGs for upcoming item drops. It has proven its necessity in the TAS numerous times.)