Joined: 4/20/2005
Posts: 2161
Location: Norrköping, Sweden
Thanks a lot. :)
I'm wondering though, what do you mean by this:
DROPS(?):
(1C 23 22 24 1C 1D 25 23 24 1C 1D 22 1D 25 1D 22
24 23 1C 22 25 23 25 1D 1D 25 23 1C 23 1D 22)
$1C 5 16.1% Diamond
$1D 7 22.6% Gold
$22 5 16.1% Large Medikit
$23 6 19.4% Small Medikit
$24 3 9.7% Large Gas Container
$25 5 16.1% Small Gas Container
I take it that the first numbers are values of a memory address, but which address? Could you give an example perhaps?
Oops, actually these values are taken from the rom. When the game decides on an item drop it randomly takes one of those values. Based on the multiple occurences of the same values I tried to estimate how likely it is (theoretically!) for each of these items to appear - at least after the game has decided something SHOULD appear. Also, you won't find the 1-up in this list because it's hard-coded into the drop generation routine at an additional very small chance.
Not really helpful and not even verified information, just ignore it :)
It was fun to discover all this, though. XD
EDIT: If you're searching for on-screen objects in memory, watch the address range $0420-$042F which holds all of the Object IDs. If one of them is, for example, $24 you've got a large gas container floating around somewhere!
Joined: 4/20/2005
Posts: 2161
Location: Norrköping, Sweden
Allright, after much work I managed to shave off another 18 frames from level 1. Some of the ideas I had didn't work out. One idea I had was to do like miau did in his movie and jump over the first banana skid (around frame 2000), which saved about 4 frames. However, I lost these frames due to bad luck and lag later on, so I didn't implement this.
Also, I found that miau's zipping trick is a little slower than the way I did in my movie, so I'm keeping it as it is. :)
Here's the WIP.
There are mainly two differences in this movie compared to the previous one:
First of all, I use an arrow to get up faster around frame 4000. This saved about 11 frames. The two enemies that I manipulated to drop big gas took a really long time and a lot of effort to manipulate. They just refused to drop any big gas. :( I managed to make them drop it after some time though, without wasting more than 3-4 frames manipulating luck.
The other change is the first boss battle which is now 7 frames faster. The strategy is different this time around - I keep to the low ground. :) Thanks to miau, I now have the memory addresses for both boss HP and their invulnerebility period. Using these, I now know that the first boss battle is frame perfect, unless someone finds a glitch or something to kill the boss faster than normally intended.
EDIT: I didn't want to doublepost, so here's a big edit instead:
First of all, you can forget about that improved movie I made, the one I posted in this post. It didn't work out with luck, and by "didn't work out" I mean that it wastes hugh amount of time to get a big gas refill. I needed a big gas refill from the second enemy on the second stage. This gas refill is crucial to get. however, I spent about 2 hours trying to get it, and my best attempt wasted 11 frames to get it. This means I'm only 7 frames ahead.
Then I reviewed my previous movie and saw that I had great luck overall, so I'm keeping to it. To put things short, even though the first level can be done at least 18 frames faster, I lose time beating it that way because of really bad luck on the next level.
I would give my right arm for the memory addresses that determines item drops...
In any case, I have a new WIP up. It beats the first 4 levels now, and is about 11 seconds faster than Walker Boh's run. Here's the WIP
Looks good, although this constant running and jumping lack variety that any platformer TAS should have.
Edit: Wait, I found something.
Here's quick and dirty explanation of RNG in Darkwing Duck.
Well, bad news. Value generated by RNG is pretty determined by the time you call RNG (when you shoot an anemy).
The game uses two numbers - Adding value at 0xE5 and Result value at 0xE6.
To make things more unpredictable, every single frame the game rotates E4,E5,E6 and E7 values to the right (ROR instruction - mostly like dividing by 2).
After using RNG, the game crops random value to a number of 00-1F (thus 32 different meanings) and then uses it as an offset for RandomItem_Table. Or don't drop an item at all.
Here's actual code snippet.
875F:
LDA E5 ` A = E5
ADC E6 ` A = A+E6
STA E6 ` E6 = A
CMP 7F ` if A < 127 then no items for you!
BCC Return
AND 1F ` else crop this "random" value
TAY ` make index (offset) from value
LDA 87A2+Y ` A = Base_Address_of_Table + Offset
Then game generates new object with ID = A
The Table itself is stored at 0x187B2 in ROM file. There are 32 bytes like this:
1C 23 22 24 1C 1D 25 23 24 1C 1D 22 1D 25 1D 22 24 23 1C 22 25 23 25 1D 1D 25 23 1C 23 1D 22 1D
1C - Diamond
1D - Gold
* 1E - DW doll (1 life)
22 - Full life restore
23 - Little life restore
24 - Big gas tank
25 - Little gas tank
Erm... Then at 187D2 there's another 32 bytes - similar table for case when ID=38, I haven't figured when it's used. But there seem to be other tables like this.
Anyway, I don't see a way to manipulate 0xE6 other than just pausing the game. Uh, at least now you can plan all the manipulations more carefully.
Seeing that "WaterDog" brought back some good memories of the TV show.
The run looks pretty damn good. If only there wasnt that crazy stupid lag, at one part of the run.
Unavoidable obviously
Joined: 4/20/2005
Posts: 2161
Location: Norrköping, Sweden
Wow, thanks a lot AnS. I owe you one. :)
I'm wondering though, how do I check the value of address 0xE5, 0xE6 and such? Can I find them in the memory viewer? Or are they in the ROM? If so, how do I find the values of the addresses in the ROM?
So to sum things up, I first check the values of 0xE5 and 0xE6, add those up and look at the result. What do I do with the result after that?
I'm sorry for not knowing these things, though I'd like to learn someday. :)
EDIT: jaysmad, I believe you're talking about the start of level 3. I know it lags like hell there, but as you can see, there's really nothing I can do about it since the enemies are too far up to be killed... At least it's only one room.
EDIT 2: Allright, I have a new WIP for you. :) I just completed level 5 now, so only 2 more levels to go! I'm a whole ~14 seconds ahead now, which is a lot more than I anticipated. There are a few places in level 5 that are obviously faster than in Walker's run. Enjoy!
Here's the WIP.
Huh, don't know what I was thinking about, but yesterday I was wrong with quick conclusions.
RNG subroutine is called every time you kill an enemy, so of course you can manipulate E6 (Result value) almost like I did in
Hi no Tori TAS.
I think you should return to that fastest WIP (which completes first stage 18 frames faster), because you don't need to wait 11 frames to change bad luck into good. Luck is programmable here. In any case you meet bad tendency with E5 and E6, you can return little earlier in the game and manually change E6 by killing some enemy - and by timing your hit (last hit) you can vary E6 value.
Well, theoretically you can 'programm' these E5 and E6 by well-planned actions, but it's too tedious.
I have easier advice: when you need to get Gas tank from enemy but think that it's impossible without waiting several frames, first try to change PREVIOUS actions - like killing previous enemy little later/earlier, or just leaving him. This way you'll change E6 somehow - you don't even need to know how actually you changed it, the result can be achieved by several blind tries.
Of course, there might be a case when you stiil need to lose couple of frames, but if you try more (rewriting more earlier parts of movie) you can have perfect luck without noticeable slowdowns.
So, I'd recommend you to manipulate item drops not by waiting some frames, but mostly by experimenting with previous enemies (who just can't drop item for you - for example, their item would fall into spikes or if you need to backtrack for their item).
But if you see an enemy in convinient place (where you could take its item without slowing down) - try to use every such enemy. I've noticed that you missed several enemies even at first stage - with little bit more patience you could get free Gas tank from them!
BTW, the possibility of receiving Big Gas container is 12/256. Not that little, so why not to rewrite everything from the beginning? ;)
Here I tested your fastest WIP and with little effort found a way to get Gas tank from second enemy (although losing 1 frame).
It's RAM, so you can see them in Memory Viewer or Memory Watch (FCEU 9816). But they won't say much about current luck situation, because they need to be treated as binary values and behave very confusing.
Well, as I said, it's kinda hard to predict how to change RNG values exactly. Not only every defeated enemy changes E6 value, but the game changes E5 and E6 every frame, and it's easier to use lot of rerecords for usual luck manipulation.
But take into account that luck mostly depends on how you treated pevious enemy/es, so there's no need to lose frames by waiting right before current enemy.
I hope you'll make unbeatable TAS. :)
Joined: 4/20/2005
Posts: 2161
Location: Norrköping, Sweden
Allright, thanks. I guess I'll take a look and see if I can improve the movie a little more then. ;)
Three questions though:
1. Can you manipulate how enemies behave by killing the previous enemy on a different frame? For example, around frame 4500 there are two enemies on platforms above me. I need to manipulate these two to not shoot a lot while I'm moving past them, because if they shoot it will cause lag. As it is right now, I wait a few frames for them to move as I want them too.
2. Does movement in any way affect randomness? I mean, does it matter if I make small jumps or high jumps when moving forward?
3. Does it matter on what frame the enemy enters the screen? If the enemy enters the screen at frame 100 and I kill him on frame 150, will he drop the same item as if he entered the screen on frame 101 and I kill him on frame 150?
Joined: 4/20/2005
Posts: 2161
Location: Norrköping, Sweden
I can answer that in Ans' place: Yes, he does. Miau found these addresses too, and came to the conclusion that they affected randomness somehow, but he didn't know how. After looking at these values in the memory watch, they don't make any sense to me at all. :) They change (seemingly) randomly every frame.
Right now I'm 23 frames ahead of my old run. I'll see if I can finish level 2 today.
It depends. Only several types of enemies use RNG, others just use player coordinates to make decisions. These shooting ones use RNG at the moment of respawn or turning back. So to manipulate these guys you need to experiment with other shooting guys (earlier at the game). because there's no other enemies that use RNG in the level.
Here's how you can make enemies call RNG later/eralier then usually:
* encounter them in different frame (lose frames - no way)
* kiil them before thay call RNG again (for these shooting guys - shoot him before he turns back) or keep them on screen for calling RNG several times
* somehow slow them down (for example, these guys duck when you shoot, so after that they gonna call RNG later)
* since all such enemies use one RNG values (E4 and E5), you can combine measures to achieve different results (for example, shoot first enemy and leave second, then vice versa, then both and so on).
Note that while you can't affect E4/E5 (values for enemy behavior) by changing E6 (by killing enemies little earlier/later), but manipulating E4/E5 will dramatically affect E6, thus changing luck for item drops.
It doesn't.
If that enemy uses RNG to make random decisions (you can easily spot such enemies) then yes, because frame of creating enemy object = frame of using RNG first time, so E5 depends on this, therefore E6 will be affected.
So it actually matters when you reach any shooting guy - by changing time of encounter you can also manipulate item drops (but indirectly).
Joined: 4/20/2005
Posts: 2161
Location: Norrköping, Sweden
Okay, thanks for the information. :)
I've redone level 2 now. In total, I gained 20 frames on this level. I won't go into detail, if you have any questions you can post them here. I'm now 38 frames faster than my previous attempt.
Here's the WIP.
EDIT: AnS pointed out that I should end the second boss battle while on the ground. It took some time to manipulate the boss to behave in a way so I could end the battle on the ground, but I managed to do so after some time. It saved another 19 frames. This means that I'm 57 frames ahead of my old run now! :)
Here's the WIP.
EDIT 2: I have some very good news. I'm almost done with level 3 now, but because I won't have time to work anymore with this run today, I thought I'd give you all an update:
So far I've gained 11 frames on level 3, now 68 frames ahead, due to minor optimizations here and there. But the best thing is that I've been extremely lucky with gas refills. I have around 40 more gas than in the current run right now! :D This means that I won't have to worry about getting a lot of gas in the upcoming levels, which is nice if I end up with really bad luck.
Meh, why not, I'll post the current WIP now anyway, even if level 3 isn't totally finished yet:
Here's the WIP.
Joined: 4/20/2005
Posts: 2161
Location: Norrköping, Sweden
Hehe, yeah. ;) But seriously, I did in fact need at least 15 gas to kill the first boss as fast as possible, and I don't think I would be able to get those drops without wasting those frames, because there are no enemies that I can kill (to manipulate RNG) right before those two I get gas from.
Either way, I think I wasted about 5 frames or so (in total) waiting for good drops in level 1, I can live with that. :) I sure won't redo 3 levels for those 5 frames anyway, should it prove that I could in fact get those drops without waiting as long.
EDIT: Level 3 done now. I gained another 3 frames, so I'm 71 frames ahead of my old WIP now. Here's the WIP.
I've watched level 3 and come to thinking that you hesitate to spend arrows freely. :) I'd use them everywhere (even for the sake of 1 frame improvement), but also constantly refill weapon meter with the help of every second enemy I see. You know, there's no such thing as good or bad luck - the game's luck is always "average", and it's only a matter of rerecords to determine luck that you need.
Here I improved level 3 by 95 frames, still having original amount of arrows before the boss.
Joined: 4/20/2005
Posts: 2161
Location: Norrköping, Sweden
:O Very nice! :) Good use of arrows there. Thanks a lot. :)
EDIT: Hmm, did you test if you could save some time by grabbing the platform around frame 15700 a little later. I do that in my movie, and thanks to this, I don't need to ride the platform for as long, which isn't very good because it moves so slowly. Perhaps you even saved a few frames grabbing it a little earlier?
Hmm, did you test if you could save some time by grabbing the platform around frame 15700 a little later. I do that in my movie, and thanks to this, I don't need to ride the platform for as long, which isn't very good because it moves so slowly. Perhaps you even saved a few frames grabbing it a little earlier?
I saved 1 frame by making platform start moving earlier. At first I tried to touch it even earlier (by the most left corner), then jump down and then jump higher and grab this platform by rightmost corner, but it proved to be impossible because of spikes. Although this trick may be useable somewhere later in the game.
Joined: 4/20/2005
Posts: 2161
Location: Norrköping, Sweden
I just found a new trick! It can save around 9 frames each time it's executed. I don't know why I didn't think about it earlier....
The trick is only useful when you want to move up as fast as possible. After you've grabbed a platform and jump up, you will first jump up a bit, so you're over the platform, then start falling down and land on the platform. The trick is to shoot an arrow on the wall next to you, so you land on the arrow. By doing this, you don't have to fall as long!
I made a short .fcm showing this trick: Here it is.
So, the "problem" now is that I know I can improve level 2 by at least 13 frames, maybe a little more. So it looks like I'll have to go back if I want those frames...
So it looks like I'll have to go back if I want those frames...
You see, it's more like those frames want you. :) And Soviet Russia has nothing to do with that, read my PM for details.
So... everything from the beginning again?
Joined: 4/20/2005
Posts: 2161
Location: Norrköping, Sweden
AnS wrote:
Randil wrote:
So it looks like I'll have to go back if I want those frames...
You see, it's more like those frames want you. :) And Soviet Russia has nothing to do with that, read my PM for details.
So... everything from the beginning again?
Yep. I think I'll do some more testing and stuff before I start the movie. I don't want to find yet another trick to make me start over again...
I did some research for feasel locating the way health and gas are stored to assist in making game genie codes.
The health, which has a maximum of 4 HP, is stored in four bytes, one for each health part. Here is a table:
.............address...health...damage
highest...0x05B4...0x80.....0x82
.............0x05B8...0x81.....0x83
.............0x05B6...0x81.....0x83
lowest....0x05B2...0x80.....0x82
When damage is done, it starts from the highest position and goes down the list until it finds a byte that has the health value set, and then marks it as the damage value. When getting a health drop, it starts from the lowest position and goes up looking for a damage value to set to the health value.
So to do infinite health in an emulator, only 0x05B4 has to be set to 0x80. A game genie code that feasel made is XKNYKPKL.
For gas ammo, it is stored in two bytes: 0x0060 is the tens position, 0x0061 is the ones position. A value of 0x0070 represents 0, 0x0071 is 1, 0x72 is 2, etc.
A useful lua function to display the ammo in a HUD would use:
ammo = (memory.readbyte(0x0060) - 112) * 10 + (memory.readbyte(0x0061) - 112)
An interesting note about infinite ammo is that it uses the memory values for the display to determine if there is enough ammo to shoot. That memory address pair is 0x05BE for tens, 0x05C0 for ones. If the main pair only is set using cheat codes, switching to the regular weapon and back resets the ammo value for the display. If the display pair is set, the displayed numbers will always show up, which makes it difficult to know what weapon is chosen.
An infinite ammo game genie code that feasel made is VVKAXOVK. This increments instead of decrements, but it was done to minimize the number of codes necessary.
Joined: 4/15/2013
Posts: 331
Location: In the attic
http://tasvideos.org/userfiles/info/18557461694126948
This is a little test I made for a Pacifist run. Like with other runs of this type, the objective is to complete the game while defeating as few enemies as possible - in this run, only one regular enemy is killed.
I started making this movie mainly because I was bored one day. It's not optimal enough to submit (there are a few issues with damage routes and stuff) but nonetheless I'm quite pleased with how it turned out.
Sometime later on I might redo this. Depends on how I'm feeling, at the end of the day.
Joined: 4/17/2010
Posts: 11475
Location: Lake Chargoggagoggmanchauggagoggchaubunagungamaugg
Made my evening! Loved it! Especially the boss fights (especially you know which one).
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
http://tasvideos.org/userfiles/info/18557461694126948
This is a little test I made for a Pacifist run. Like with other runs of this type, the objective is to complete the game while defeating as few enemies as possible - in this run, only one regular enemy is killed.
I started making this movie mainly because I was bored one day. It's not optimal enough to submit (there are a few issues with damage routes and stuff) but nonetheless I'm quite pleased with how it turned out.
Sometime later on I might redo this. Depends on how I'm feeling, at the end of the day.
This was very neat. The nice thing about Darkwing Duck is that the enemy placement makes a pacifist run very nontrivial, and this run shows some excellent dodging as a result.
However, could you maybe have avoided killing one dude by getting to the area with more health? Just curious.