Posts for Omnigamer


1 2
5 6 7
11 12
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
The puzzle pieces are really always in the same order for each picture? That seems like a poor design decision, but I guess it simplifies things. Are the specific puzzles always fixed as well, or can they vary for each boss? That makes sense for the Auto powerup then. I wouldn't completely disregard it however; there may be some situations in which it can save some frames, especially if you are close to finishing but don't have enough special meter to get helper, or helper would be ineffective in the remaining time. I'm pretty sure you can't, but just to double-check your cursor is locked when you select a piece with Auto, correct?
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
A bit late, but temp encode: Link to video Looking really smooth! I tried a few of the things but you're right, they are more or less impossible. I may be able to pick out a few of the minor optimizations though. In other news, I'm almost to the point where I'm satisfied with my runs. Managed a 23:59 RTA recently, unfortunately Stage 8 is still a major headache and a few other errors keep me from being satisfied. Probably won't be long though. Older video below that is mostly up-to-date with the exception of skipping another wind cycle in Stage 7. Use it as a reference if you'd like. Link to video
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Hello, I'm definitely interested in something for Pieces. There are some important things to consider though, that may take quite some time to investigate, the main one being RNG Mechanics. This will matter a lot for determining puzzle piece order, and probably somewhat for the helper as well. If it can be manipulated so that you get a lot of the upper pieces early on then you can probably gain some good time. But I'm sure there's also a tradeoff in terms of helper efficiency, since you can still move faster to the lower spots, so maybe a higher turnover rate is better by leaving the top spaces empty. I think there's one other power that may be helpful as well, if I remember right you just click on a piece and it flies to its location. Again, just needs lots of testing. Overall I think this should be a lot of fun to optimize though. Figuring out how to manipulate the RNG will go a long way.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
The benefit in doing it in water is that the same timer carries over when you jump out. So even though blowing a bunch of bubbles isn't that useful, maintaining double or triple flame as soon as you jump out can have its uses. As for the above post, I just meant that the game tracks which attacks have "hit" something already. Since each flame is a separate full attack, both can hit. The game doesn't have invulnerability timers in the normal sense; you can do damage as fast as you can generate new attacks. An update on boss strategies, for real-time this ends up only affecting Sethron 1 and 2. I came up with some strats for using it on the other bosses, but with real-time constraints it's just not consistent or fast enough to make a difference. In the process of testing though I worked out a new strategy for Hell Hive that involves hitting openings twice in the same cycle. There's just enough time to start a new (regular) flame if you hit with the trailing end of a first flame as the openings become vulnerable, which is enough to count as hitting it twice. This can also be done with double flames, but I wasn't able to work out a consistent strategy for taking damage against the bees. The new strat is about ~6 seconds faster than the older one. Minor other route changes: -In Stage 5 I take the first skateboard and jump to get a flame, pick up the following flame, then bounce and jump to the pool below where there's a third flame and invulnerability. This replaces getting a different and slower flame later in the stage. Hard to explain, but if you explore that area it will make sense. -Stage 6 has an area where I need to freeze a spitter in order to jump up onto some branches. I now try to set up double flame in the water immediately prior and freeze him quicker. -Not a change, but I tested death abuse on Stage 7 to manipulate wind patterns. While the manipulation works, it is slower than just waiting it out since there aren't any quick ways to die near the checkpoints. On hard mode I'm not even sure which checkpoints still exist, so probably not useful to you. -I still have some more tweaking to do in Stage 8 to account for best average times and manipulating elevator cycles. I'll report back soon?
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
So I came across a bug during practice tonight that seems like it will shake up my strategies on every boss. Example below: Link to video Theory: with level 4 or 5 flame, the flame is out longer than your hitstun timer. When hitstun wears off it removes the flag that says "can't shoot fire" before the flame finishes. So then you can perform another fire while the first one is still out. However, when that first one finishes it again unsets the "can't shoot fire" flag, and thus you can keep doing it. What this also means is that with the correct timing, you can get even 3 or maybe 4 flames out simultaneously. Each flame counts as its own separate attack, so they all can damage bosses regardless of per-attack invulnerability. In real-time only 2 is practical, but for a TAS this opens up a lot of doors. Triple flame can decimate most bosses. Note that with flame level 4, probably only the double flame is possible. The timing is pretty tight as-is. In any case, I can confirm that double hits work for all the bosses, although with varying degrees of difficulty. I'll keep experimenting and eventually post my new strats once they're finalized, but the TAS can abuse this in ways I couldn't hope to pull out real time. EDIT: Just found out that you can also trigger it in water even though you have no hit animation. So yeah. May be useful in some areas. This makes it possible to set up a rhythm for even level 1 flame.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Temporary Encode: Link to video Gotta say, really impressive stuff. I have to try some of that out, but a lot of the momentum preservation stuff looks awfully tricky for real-time. We'll see what happens though. Keep it up!
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Yes, I worked that momentum boost and a few others into my route. I'm consistent with it in practice, but for whatever reason I don't get it often during attempts. Another note about the crushers is that if you jump while underneath them you will not be crushed if they start to fall. The hitbox I think is only active at the bottom. I made another few minor changes in the latter stages that save a few seconds, usually the difference between taking a high and low route. Stage 9 for example has an upper route with an extra vine swing that somehow turns out to be 2-3 seconds faster. I should probably work on writing these changes down...
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Noticed something that is *probably* useless, but worth noting anyway. If you're next to spikes like in stage 2, doing a kick and then a roar in the first few frames will start the kick, but then cancel it with the roar. If you're holding forward you'll move a bit into the spikes, but then when the roar finishes you'll spend about half a second in the "falling" animation despite being on the ground. Also, the first vine you need to swing from in Stage 2 can be done in 4 swings instead of the usual 5. Probably a few other places this can be done as well. It may not actually be faster depending on how much the speed boost and better positioning help, but just a heads-up before you get too deep into your next WIP.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Agreed on the bad game design notion, it's difficulty through nuisance. I imagine even the final run for that stage will look a bit rough since the enemies are just so uncooperative and attacking a lot of them is counterproductive. I think there may be some fun abuses to the bouncing though, depending on what enemies let you get away with.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Wow, looking really impressive! I'll have to give some of those a go when I get back to practicing. I'm curious if some of there are some similar ways to abuse the momentum in stage 9, although the stage layout is a lot different. I can't think of places in other stages where the spike ledge-jumping would apply, but I'll keep my eyes open for that too.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Very interesting on the above. Can it only be done on colliding with something, or is it possible any time when losing the board? For example, could you launch the board mid-jump and then jump again after? I made a YouTube compilation of my improvements so far: Link to video It doesn't take into account a route change in stage 8 to get the last flame powerup, but I believe it still gains time over that.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Nothing changed in Level 1. The setup for the boss skip is actually pretty easy in real-time; you just walk at him, kick, and then keep walking. After I figured it out, I was able to do it every time after. It requires three damage boosts though, and an optimal method should be able to do it in 2. I'm also working on a hitbox viewer for the game. Their data structures are fairly straightforward, although the actual hitbox calculations and flags are a bit wonky. I'll work on it a bit more. Also as a note, Rex's speed address is 2 bytes and changes by stage. I've included in my script something that displays his speed beneath him so it should be easy to track. I'll release the script after I've squashed a few more bugs.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
A couple of new finds: -Boneyard boss can be completely skipped. For whatever reason, one frame of his animation does not have the invisible wall. During that time you can get a pixel inside of it, and then the next damage boost will push you the rest of the way through. A pretty big timesaver, and removes probably the biggest point of RNG in the run. -A newer strat against the Tumor boss helps tremendously. Turns out you can hit both sides of him at the same time with full or 3/4 flame. I need to time out what the actual differences are, but it may be enough to justify getting another flame and full roar. At least in my testing it takes the time to finish him down from about a minute to ~20 seconds if done well. Again, the detours will need to be timed out, but it's a start. -A couple other minor route modifications throughout. Basically a few more shortcuts and a couple of uses for the "tube jumping" technique I described earlier.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
To be honest, the difference in time between collecting and not collecting powerups is not so small that you'll need to do stringent frame analysis. For whatever reason they made damage specific to the enemy being hit, and collecting powerups changes the amount in unpredictable ways. I will need to check my notes, but for example on the Pterodactyl boss he takes something like 1, 2, 5, 10, or 42 damage depending on your flame powerups. That's a lot of extra hits to get the equivalent damage between even level 4 and level 5 flame. This compounds with the bosses that have invulnerability between cycles. Pterodactyl is the most pronounced difference, but the only boss I worked out to be faster without getting full powerups is the Tumor boss in Stage 8, and that was mainly because all of the other flame powerups are way too far out of the way. But yeah, it won't be a difference in number of frames, I expect it to be on the order of seconds at least.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Hey Exxonym, yeah I will be running the game at AGDQ. I actually worked on re-learning the first half of the game last night and found a few time-savers in the process. It amounts to about 3-4 seconds overall, but any improvement is improvement. If you want to investigate things further, by all means. The game is too silly not to have one or two crippling oversights.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Augusto wrote:
Thanks for reply. Is an surprise for me see that YM2612 is more of 40 KHZ. Sega had droped the high frequency in some consoles revisions ? About sound the original model allways sounds better than others revisions. Now understand that low quality voices in some Genesis games is because Z80 control the DAC and coders avoiding large rom space that not is an issue on SNES because use compressed sound data. God bless you.
Original Genesis models used a circuit that cut acted as a low-pass filter to a fairly narrow band, I forget the exact range. The circuit (and chip) changed in later revisions which shifted the band around a bit, but in general the circuit was never great hence why many people dislike audio on later models if they are used to originals. Any of the FM chips should be able to reproduce a full 22 kHz (aka 44.1 kHz sample rate) with the right circuit attached (see Mega Amp and others like it).
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Looking it over, I think somehow some of the comparators got screwed up in posting them on the site. The line it's complaining about is shown as: if(drop_sub<0x20>0) then which should be: if( drop_sub>0 and drop_sub<0x20) then I don't know why it changed in the course of posting. I'll put it on pastebin when I get home. A brief scan of the rest of the script seems like that should be the only issue. It happens again in a commented line, but that shouldn't matter. EDIT: Aha, it did it again! Yeah, it is interpreting some of it as HTML where I have stuff in carrot braces. Swapped order above should fix it. EDIT2: Pastebin of the code available here: http://pastebin.com/LSB8Jmjm
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Script below. Here's the lowdown on drops though: -Each enemy type has a set variety of drops. Almost every single variety is dependent on whether you have upgraded saber; if you don't that will always be the drop. If you have the saber, it will always be only one other thing (for a specific enemy group). -The one enemy group that does not conform to this are the cannons in Bruford. They alternate between bomb and HP based on the RNG ($5C). You cannot get saber upgrade from them. -My statements above were mostly correct for drops, however for enemies that have a drop rate below 4 they are unaffected by difficulty. Basically, enemies that drop every 3 hits or every 1 hit will always remain that way. -You can use bombs to activate the enemy bug I describe above (especially for enemies that blow up instantly), however note that only 4 powerups can be on the screen at one time. Thus if they have 4 enemies left to cause a drop and there are 4 enemies on-screen, using a bomb will cause all of them to drop. One more thing to mention about difficulty: as far as I've been able to tell so far the only other gameplay difference beyond enemy speed and drop rates is with the final boss. The window to attack the core is significantly smaller on Hard. So about the script. It tracks a lot of things, but most of it should be pretty self-explanitory. Blue is good, Red is bad. Purple are typically projectiles, however some non-damaging debris also falls under this category. Green boxes are player attacks. White means the entity is invulnerable. The white number underneath enemies is their HP. The color-coded number below it is the number of enemies to kill before a drop is triggered. Green means a saber upgrade, Red is a bomb, Purple is HP, and Blue is Big HP. Extra lives cannot drop from enemies. If you see lone red pixels around, that marks the center (according to the game) of an enemy. There are some artifacts here and there, such as hitboxes that cannot actually hurt you and stray purple debris. In any case, enjoy. Let me know if something is broken.
while true do
	
	camx = mainmemory.read_u16_le(0x000548)
	camy = mainmemory.read_u16_le(0x00054A)
	
	textX=30
	textY=50
	
	hp = mainmemory.read_u8(0x001F3A)
	gui.text(textX,textY,string.format("HP:  %d",hp))
	diff = mainmemory.read_u8(0x001F0F)
	
	memory.usememorydomain("CARTROM")
	
	hitbox_left = mainmemory.read_u16_le(0x000270)
	hitbox_right = mainmemory.read_u16_le(0x000272)
	hitbox_up = mainmemory.read_u16_le(0x000274)
	hitbox_down = mainmemory.read_u16_le(0x000276)
	
	if(mainmemory.read_u8(0x000E1D)~=0xFF) then
		attack_right = mainmemory.read_u16_le(0x000280)
		attack_left = mainmemory.read_u16_le(0x000282)
		attack_up = mainmemory.read_u16_le(0x000284)
		attack_down = mainmemory.read_u16_le(0x000286)
	
		
			gui.drawBox(attack_left-camx,attack_up-camy,attack_right-camx, attack_down-camy,"green")
			
	end
	
	if(mainmemory.read_u8(0x000E1E)~=0x00) then
		gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"blue")
	else
		gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"white")
	end
	
	
	hitbox_left = mainmemory.read_u16_le(0x000278)
	hitbox_right = mainmemory.read_u16_le(0x00027A)
	hitbox_up = mainmemory.read_u16_le(0x00027C)
	hitbox_down = mainmemory.read_u16_le(0x00027E)
	
	if(mainmemory.read_u8(0x000E3D)~=0xFF) then
		attack_right = mainmemory.read_u16_le(0x000288)
		attack_left = mainmemory.read_u16_le(0x00028A)
		attack_up = mainmemory.read_u16_le(0x00028C)
		attack_down = mainmemory.read_u16_le(0x00028E)
	
		gui.drawBox(attack_left-camx,attack_up-camy,attack_right-camx, attack_down-camy,"green")
	end
	
	if(mainmemory.read_u8(0x000E3E)~=0x00) then
		gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"blue")
	else
		gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"white")
	end
	
	
	
	
	for i = 2,0x0F,1 do
		
		if(mainmemory.read_u8(0x000e00+(i*0x20))>0) then
		
		ID = mainmemory.read_u8(0x000e00+(i*0x20))*4
		
		NEWDC = mainmemory.read_u8(0x000e1c+(i*0x20))*4
		
		pos_x = mainmemory.read_u16_le(0x000e10+(i*0x20))
		pos_y = mainmemory.read_u16_le(0x000e12+(i*0x20))
		
		offset_x = memory.read_u8(0x038A00+NEWDC)
		length_x = memory.read_u8(0x038A01+NEWDC)
		offset_y = memory.read_u8(0x038A02+NEWDC)
		length_y = memory.read_u8(0x038A03+NEWDC)
		

		drop_offset = memory.read_u8(0x0091eb+ID)
		if(drop_offset >=0x04) then
			if(diff==0x00) then
				drop_sub = bit.rshift(drop_offset,1)
			elseif(diff==0x10) then
				drop_sub = drop_offset + bit.rshift(drop_offset,2)
			else
				drop_sub = drop_offset
			end
		else
			drop_sub = drop_offset
		end
		
		gui.drawPixel(pos_x-camx, pos_y-camy,"red")
		
		if(mainmemory.read_u8(0x000E0C+(i*0x20))==0) then
			mycolor = "red"
		else
			mycolor = "white"
		end
		
		if(bit.band(mainmemory.read_u8(0x000e07+(i*0x20)),0x40)~=0) then
			gui.drawBox(pos_x-camx+offset_x-length_x,pos_y-camy-offset_y,pos_x-camx+offset_x, pos_y-camy-offset_y+length_y,mycolor)
		else 
			gui.drawBox(pos_x-camx-offset_x+length_x,pos_y-camy-offset_y,pos_x-camx-offset_x, pos_y-camy-offset_y+length_y,mycolor)
		end
		
		damage = mainmemory.read_u8(0x000e14+(i*0x20))
		max_hp = mainmemory.read_u8(0x000e15+(i*0x20))
		
		drop_index = mainmemory.read_u8(0x000e17+(i*0x20))
		drop_count = mainmemory.read_u8(0x000d00+drop_index)
		drop_type = memory.read_u8(0x0091ec+ID)
		
		if(drop_type == 0x05) then
			if(mainmemory.read_u8(0x000e19)==0x01) then
				drop_color = "red" -- Bomb
			else
				drop_color = "green" -- Sword Up
			end
		elseif(drop_type == 0x01) then -- HP Up
			if(mainmemory.read_u8(0x000e19)==0x01) then
				drop_color = "purple" -- HP Up
			else
				drop_color = "green" -- Sword Up
			end
		elseif(drop_type == 0x03) then -- Big HP Up
			if(mainmemory.read_u8(0x000e19)==0x01) then
				drop_color = "blue" -- Big HP Up
			else
				drop_color = "green" -- Sword Up
			end
		elseif(drop_type == 0x07) then -- HP or bomb?
			if(bit.band(mainmemory.read_u8(0x00005c),0x01)==0) then
				drop_color = "purple" -- HP Up
			else
				drop_color = "red" -- Bomb
			end
		else
			drop_color = "white"
		end
		
		
		if(max_hp-damage < 128 and max_hp-damage ~= 0) then

			gui.drawText(pos_x-camx, pos_y-camy,string.format("%d",max_hp-damage))
			
		end
		
		if(drop_sub<0x20>0) then
			if(((drop_sub-(drop_count))%drop_sub)~=0) then
				gui.drawText(pos_x-camx, pos_y-camy+10,string.format("%d",(drop_sub-(drop_count))%drop_sub),drop_color)
			else
				gui.drawText(pos_x-camx, pos_y-camy+10,string.format("%d",(drop_sub)),drop_color)
			end
		end
		
		end
	end
	
	for i = 0,0x0f,1 do --was 7
		--if(i<8>=0x0c) then
			ID = mainmemory.read_u8(0x000c00+(i*0x10))
			if(ID>0) then
			
				addr_offset = mainmemory.read_u8(0x000c0e+(i*0x10))*8
			
				pos_x = mainmemory.read_u16_le(0x000c05+(i*0x10))
				pos_y = mainmemory.read_u16_le(0x000c07+(i*0x10))
			
				offset_x = memory.read_u8(0x009045+addr_offset)
				length_x = memory.read_u8(0x009047+addr_offset)
				offset_y = memory.read_u8(0x009049+addr_offset)
				length_y = memory.read_u8(0x00904B+addr_offset)
			
				gui.drawBox(pos_x-camx+offset_x,pos_y-camy+offset_y,pos_x-camx+offset_x+length_x, pos_y-camy+offset_y+length_y,"purple")
				
				--gui.drawText(pos_x-camx, pos_y-camy,string.format("%d",mainmemory.read_u8(0x000c01+(i*0x10))))

			end
		--end
	end
	
	emu.frameadvance()
end
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
zeromus wrote:
update: problem doesnt occur on any windows 8.1 machines we tested on. not that many users of the cutting edge OS, youll have to wait for a developer to repro it or avoid using MS cutting edge unless you like bugs.
OK, this is what I wanted to know. I'll try a few more things since it seems specific to my setup and not a universal Win 8.1 thing. Thanks! EDIT: Somewhere between reinstalling my audio drivers, reinstalling bizhawk prereqs, and tweaking some settings, it came back. All's well.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Small update to the script. I investigated several things that difficulty impacts, but the only notable things so far are enemy speed and drop rates. I will need to double-check for speed, but I believe the speed changes are the same for Easy and Normal and only speed up for Hard. Drop rates are a bit more interesting. Drops are calculated per specific enemy types but also per specific screens. This means killing a bunch of the same enemies in the same general area will push thier "counter" towards new drops. There can only be three drops per area enemy type though; this is hardcoded. But anyway, there is a table corresponding to enemy types and drop rates. If Easy, this drop rate is cut in half (rshift, so the rounding is beneficial). Normal it is left as is. Hard adds 25% (base + rshift x2) to this value. I have not spent any time looking into what sources the drops themselves other than checking into $76, which counts up every time a new drop appears, even if not dropped by an enemy. This controls what item is spawned, but there are some other factors that affect it that I'm not sure of. I have an updated script that takes everything into account, but I will hold off on posting it until I understand what actually drops better. EDIT: I also forgot to mention a bug/feature of the way it calculates the drop counter for a particular group. The counter is incremented as soon as a particular enemy's HP drops to 0. However, the code to calculate whether or not to spawn a drop does not execute until the unit has finished exploding. For some enemies this is instantaneous, but others that "fall back" when hit have quite some delay before spawning an item. So consider this scenario: enemy counter is at 0 initially. This enemy type will drop something when the counter is at 2. Two enemies approach. You kill the first, counter rises to 1. While the enemy is falling back, you kill the other enemy. The counter now rises to 2. Now the first enemy finishes exploding and spawns an item, since the counter is at 2. But when the second enemy finishes exploding, the counter is still a 2. Both enemies will thus spawn a drop. This also does not count towards the "no more than 3" drops requirement; if you could find a setup to kill 4 enemies and end up on the magic number by the time the first one explodes, all 4 will drop something. This also means there can be events where an enemy that should drop something will not because you kill another enemy too quickly. This does use up one of the "only 3 drops" so be careful on that.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
I always run in compatibility modes. EDIT: May have misunderstood. I use compatibility cores. Windows Compatibility settings also do not have any effect.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
I recently changed to Win 8.1 x64, but it seems that the most recent and past BizHawk versions aren't correctly registered with the Windows audio stack? It worked fine on Win 8 and 7, so I'm a liitle curious why it would suddenly drop out. To be clear, audio still plays, but according to Windows there's no audio playing at all. There's also no BizHawk application source listed in the volume mixer. Reinstalling the prereqs didn't change anything. Is there some other .NET package I need to install or anything else along those lines?
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
Hello! I made a hitbox script for Run Saber. They handle things in interesting ways... For example, rather than giving an enemy an additional hitbox for an attack or making complex shapes from multiple hitboxes, they just cycle through some offsets and sizes depending on the current animation without changing the center. This is most evident with the first miniboss and the lightning in Stage 2. What this also means is that there are plenty of gaps to abuse, especially for a TAS. They might have screwed up in a few places as well... [URL=http://www.makeagif.com/TulvQy][/URL] Code below. I make no claims about it being clean or efficient or complete, but it should be reasonable for now. Developed and tested on BizHawk 1.8.4, although some minor modifications should make it suitable for other versions/emulators.
while true do
	
	camx = mainmemory.read_u16_le(0x000548)
	camy = mainmemory.read_u16_le(0x00054A)
	
	textX=20
	textY=40
	
	hp = mainmemory.read_u8(0x001F3A)
	gui.text(textX,textY,string.format("HP:  %d",hp))
	
	memory.usememorydomain("CARTROM")
	
	hitbox_left = mainmemory.read_u16_le(0x000270)
	hitbox_right = mainmemory.read_u16_le(0x000272)
	hitbox_up = mainmemory.read_u16_le(0x000274)
	hitbox_down = mainmemory.read_u16_le(0x000276)
	
	if(mainmemory.read_u8(0x000E1D)~=0xFF) then
		attack_right = mainmemory.read_u16_le(0x000280)
		attack_left = mainmemory.read_u16_le(0x000282)
		attack_up = mainmemory.read_u16_le(0x000284)
		attack_down = mainmemory.read_u16_le(0x000286)
	
		
			gui.drawBox(attack_left-camx,attack_up-camy,attack_right-camx, attack_down-camy,"green")
			
	end
	
	--gui.text(textX,textY+14,string.format("X: %X",camx))
	--gui.text(textX,textY+28,string.format("Y: %X",camy))
	if(mainmemory.read_u8(0x000E1E)~=0x00) then
		gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"blue")
	else
		gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"white")
	end
	
	
	hitbox_left = mainmemory.read_u16_le(0x000278)
	hitbox_right = mainmemory.read_u16_le(0x00027A)
	hitbox_up = mainmemory.read_u16_le(0x00027C)
	hitbox_down = mainmemory.read_u16_le(0x00027E)
	
	if(mainmemory.read_u8(0x000E3D)~=0xFF) then
		attack_right = mainmemory.read_u16_le(0x000288)
		attack_left = mainmemory.read_u16_le(0x00028A)
		attack_up = mainmemory.read_u16_le(0x00028C)
		attack_down = mainmemory.read_u16_le(0x00028E)
	
		gui.drawBox(attack_left-camx,attack_up-camy,attack_right-camx, attack_down-camy,"green")
	end
	
	if(mainmemory.read_u8(0x000E3E)~=0x00) then
		gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"blue")
	else
		gui.drawBox(hitbox_left-camx,hitbox_up-camy,hitbox_right-camx, hitbox_down-camy,"white")
	end
	
	
	
	
	for i = 2,0x0F,1 do
		
		if(mainmemory.read_u8(0x000e00+(i*0x20))>0) then
		
		ID = mainmemory.read_u8(0x000e00+(i*0x20))*2
		
		NEWDC = mainmemory.read_u8(0x000e1c+(i*0x20))*4
		
		pos_x = mainmemory.read_u16_le(0x000e10+(i*0x20))
		pos_y = mainmemory.read_u16_le(0x000e12+(i*0x20))
		
		offset_x = memory.read_u8(0x038A00+NEWDC)
		length_x = memory.read_u8(0x038A01+NEWDC)
		offset_y = memory.read_u8(0x038A02+NEWDC)
		length_y = memory.read_u8(0x038A03+NEWDC)
		
		gui.drawPixel(pos_x-camx, pos_y-camy,"red")
		
		if(mainmemory.read_u8(0x000E0C+(i*0x20))==0) then
			mycolor = "red"
		else
			mycolor = "white"
		end
		
		if(bit.band(mainmemory.read_u8(0x000e07+(i*0x20)),0x40)~=0) then
			gui.drawBox(pos_x-camx+offset_x-length_x,pos_y-camy-offset_y,pos_x-camx+offset_x, pos_y-camy-offset_y+length_y,mycolor)
		else 
			gui.drawBox(pos_x-camx-offset_x+length_x,pos_y-camy-offset_y,pos_x-camx-offset_x, pos_y-camy-offset_y+length_y,mycolor)
		end
		--gui.drawText(pos_x-camx, pos_y-camy,string.format("%d",i))
		damage = mainmemory.read_u8(0x000e14+(i*0x20))
		max_hp = mainmemory.read_u8(0x000e15+(i*0x20))
		
		if(max_hp-damage <128>0) then
		
			addr_offset = mainmemory.read_u8(0x000c0e+(i*0x10))*8
		
			pos_x = mainmemory.read_u16_le(0x000c05+(i*0x10))
			pos_y = mainmemory.read_u16_le(0x000c07+(i*0x10))
		
			offset_x = memory.read_u8(0x009045+addr_offset)
			length_x = memory.read_u8(0x009047+addr_offset)
			offset_y = memory.read_u8(0x009049+addr_offset)
			length_y = memory.read_u8(0x00904B+addr_offset)
		
			gui.drawBox(pos_x-camx+offset_x,pos_y-camy+offset_y,pos_x-camx+offset_x+length_x, pos_y-camy+offset_y+length_y,"purple")

		end
	end
	
	emu.frameadvance()
end
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
zeromus wrote:
0a. This does seem jacked up. following are notes for future debugging: 0b. check line 590 in Watch.cs. cheat.PokeValue() happens, and then return true; note that theres no way to get to PokeByte below. Was PokeValue intended to internally do the PokeByte()? 0c. It appears (to the hex editor) as if the value is truly frozen. Is this because the involvement of the cheat layer? Imho, it should read back out from the core directly instead of trying to create a fraudulent reality 1. By "No frame limiter setting" you clearly mean speed setting, and when theres nothing checked, it's because youve used the -/+ hotkeys to change it to a value not in the GUI. "unpredictable" in this case should mean "completely predictable based on the value you left it at" 2. Dont do that. 3. It's changed to be relative to the client window and not (brokenly) relative to the emulator output. Since gui.text isnt capable of scaling, and is intended to be more primitive than the other drawing functions, it occurs in client-window-space. So the coordinates you enter there will be fixed even as you resize your window. If you want the text to appear at a certain point in the game world, youll have to use a different lua drawing function. More generally, anything related to lua drawing is subject to change at any time, since it's all in a state of half-brokenness.
1. You're probably right, I think I had enabled global hotkeys just before I started seeing it so it was probably picking up inputs from presses intended for other programs. 3. Noted. I'll just adjust my older scripts then.
Experienced Forum User, Published Author, Player (33)
Joined: 2/16/2012
Posts: 282
got4n wrote:
Issue: RAM Watch freezing not working BizHawk version : 1.8.4 Game: Rayman 2 Platform: N64 Domain : RDRAM
Also reporting the same issue with 1.8.4 working with SNES RAM in Run Saber. Some other stuff: -Loading 1.8.4 sometimes causes it to load with no frame limiter setting ("Speed 100%") and thus has some unpredictable results. With clock throttle it was giving less than 1 fps until I forced the limiter on. -Related to the above, I muted audio while "Audio Throttle" was selected. It didn't do anything to immediately, but closing and re-opening the program made it run at an unlimited frame rate, again until I forced it back. -For Lua scripting, the gui.text function seems to have changed scaling. I now need to give values about twice what I had before to get the same position in the game window (both x and y). This may have been an intentional change, but scripts made for older versions of bizhawk now don't match up.
1 2
5 6 7
11 12