What's Aktan's method?
Right now i'm trying to figure out the randomly spawning guards on Surface. I went through some of the code using the Goldeneye Setup Editor and while it's extremely difficult to follow what's happening i could make out a rough algorithm:
(There are 4 spawning guards and each of them runs this code seperately)
1. Start cycle counter
2. If cycle counter > 120 continue else wait (simply wait 2 seconds)
3. Reset cycle counter
4. If cycle counter > 120 continue else wait (wait 2 seconds again, the game checks some objective bits during this)
5. Seed random Byte (I want to know this byte)
6. If Seeded byte > 200 continue (So i can know if this is true or false)
7. If Seeded byte > 50 continue (Dunno why they do this, should always be true since value is already determined to be bigger than 200??)8. Spawn Guard
This code determines WHEN one of the 4 guards spawn. When that happens, the game simply checks which "room" Bond is in, and has 4 pre-determined spawn locations for each room, i.e one location for each of the 4 guards. But since the guards spawn at diffrent times, they can still end up in seemingly random locations.
In my 1:44 run, Guard #4 spawned by the houses where the alarm and camera is, and this can only happen if Bond is located near the grenade launcher hut when 4th guard spawns.
Here's the code in it's original form:
8E00 Change Guard ID (00)
AE Reset Cycle Counter And Enable It
0240 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
B400007803 If Cycle Counter > Value, Return Value Loop B4 (000078)
0140 Go To Beginning, Then Return Value Loop
0203 Resume If Return Value Loop Met
9C000004000B Check If Objective Value, Return Loop If So (00000400)
AE Reset Cycle Counter And Enable It
020A Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
B400007807 If Cycle Counter > Value, Return Value Loop B4 (000078)
010A Go To Beginning, Then Return Value Loop
0207 Resume If Return Value Loop Met
310407 If Bond In Room With Guard ID, Return Value Loop (Spawned Guard) Path from Block [0414]
0103 Go To Beginning, Then Return Value Loop
0207 Resume If Return Value Loop Met
AD737061776E31 = spawn1
F329 If Player Pickups Disabled, Return Value Loop
33 Seed Random Byte
35C807 If Seeded Byte > Value, Go Into Return Value Loop (C8)
590129 Go Into Return Value Loop If Specified Weapon Is Out (01 Unarmed)
590229 Go Into Return Value Loop If Specified Weapon Is Out (02 Hunting Knives)
590329 Go Into Return Value Loop If Specified Weapon Is Out (03 Throwing Knives)
590429 Go Into Return Value Loop If Specified Weapon Is Out (04 PP7)
590529 Go Into Return Value Loop If Specified Weapon Is Out (05 PP7 (silenced))
591129 Go Into Return Value Loop If Specified Weapon Is Out (11 Sniper Rifle)
0207 Resume If Return Value Loop Met
35322A If Seeded Byte > Value, Go Into Return Value Loop (32)
590729 Go Into Return Value Loop If Specified Weapon Is Out (07 Klobb)
591829 Go Into Return Value Loop If Specified Weapon Is Out (18 Grenade Launcher)
590829 Go Into Return Value Loop If Specified Weapon Is Out (08 KF7)
022A Resume If Return Value Loop Met
BD15FF232804140000000104 Spawn Guard (Siberian Special Forces: Dark Grey Snowsuit, Mask) (Random Head)
0229 Resume If Return Value Loop Met
AD2D3E6661696C = ->fail
0103 Go To Beginning, Then Return Value Loop
0204 Resume If Return Value Loop Met
AD7331204F4B21 = s1 OK!
0103 Go To Beginning, Then Return Value Loop
020B Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
9C0000020007 Check If Objective Value, Return Loop If So (00000200)
010B Go To Beginning, Then Return Value Loop
0207 Resume If Return Value Loop Met
0103 Go To Beginning, Then Return Value Loop
04 Terminator
And here's the location code:
(Preset 0093 means the room with the grenade launcher hut, And Preset 00DB is the location around the camera/alarm houses)
0200 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
55002D30 Go Into Return Value Loop If Entered Room with Preset (Preset: 002D)
55004D31 Go Into Return Value Loop If Entered Room with Preset (Preset: 004D)
55005132 Go Into Return Value Loop If Entered Room with Preset (Preset: 0051)
55003333 Go Into Return Value Loop If Entered Room with Preset (Preset: 0033)
55006634 Go Into Return Value Loop If Entered Room with Preset (Preset: 0066)
03 Leave The Routine, But When Return Continue From Spot
55003635 Go Into Return Value Loop If Entered Room with Preset (Preset: 0036)
55007B36 Go Into Return Value Loop If Entered Room with Preset (Preset: 007B)
55009337 Go Into Return Value Loop If Entered Room with Preset (Preset: 0093)
5500DB38 Go Into Return Value Loop If Entered Room with Preset (Preset: 00DB)
55004A39 Go Into Return Value Loop If Entered Room with Preset (Preset: 004A)
03 Leave The Routine, But When Return Continue From Spot
5500D23A Go Into Return Value Loop If Entered Room with Preset (Preset: 00D2)
5500BA3B Go Into Return Value Loop If Entered Room with Preset (Preset: 00BA)
5500EB3C Go Into Return Value Loop If Entered Room with Preset (Preset: 00EB)
5500FC3D Go Into Return Value Loop If Entered Room with Preset (Preset: 00FC)
5500F13E Go Into Return Value Loop If Entered Room with Preset (Preset: 00F1)
0100 Go To Beginning, Then Return Value Loop
0230 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC000030 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 0030)
AC010042 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 0042)
AC020038 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 0038)
AC03007B Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 007B)
0100 Go To Beginning, Then Return Value Loop
0231 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC00002D Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 002D)
AC010066 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 0066)
AC020045 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 0045)
AC030093 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 0093)
0100 Go To Beginning, Then Return Value Loop
0232 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC00002D Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 002D)
AC010047 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 0047)
AC02007B Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 007B)
AC030038 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 0038)
0100 Go To Beginning, Then Return Value Loop
0233 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC00002D Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 002D)
AC010045 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 0045)
AC0200B5 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 00B5)
AC030038 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 0038)
0100 Go To Beginning, Then Return Value Loop
0234 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC00002D Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 002D)
AC01003C Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 003C)
AC0200B5 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 00B5)
AC030033 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 0033)
0100 Go To Beginning, Then Return Value Loop
0235 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC00004D Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 004D)
AC010045 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 0045)
AC020047 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 0047)
AC03003C Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 003C)
0100 Go To Beginning, Then Return Value Loop
0236 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC000030 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 0030)
AC0100A3 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 00A3)
AC02004A Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 004A)
AC0300BC Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 00BC)
0100 Go To Beginning, Then Return Value Loop
0237 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC00004D Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 004D)
AC010045 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 0045)
AC02003D Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 003D)
AC0300DB Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 00DB)
0100 Go To Beginning, Then Return Value Loop
0238 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC0000BC Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 00BC)
AC0100D2 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 00D2)
AC0200B5 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 00B5)
AC03007B Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 007B)
0100 Go To Beginning, Then Return Value Loop
0239 Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC0000EB Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 00EB)
AC01007B Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 007B)
AC020045 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 0045)
AC0300FC Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 00FC)
0100 Go To Beginning, Then Return Value Loop
023A Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC0000DB Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 00DB)
AC010066 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 0066)
AC020038 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 0038)
AC0300FC Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 00FC)
0100 Go To Beginning, Then Return Value Loop
023B Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC0000DB Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 00DB)
AC0100F1 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 00F1)
AC020051 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 0051)
AC030033 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 0033)
0100 Go To Beginning, Then Return Value Loop
023C Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC000051 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 0051)
AC0100D2 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 00D2)
AC020047 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 0047)
AC030045 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 0045)
0100 Go To Beginning, Then Return Value Loop
023D Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC0000D2 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 00D2)
AC010093 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 0093)
AC020040 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 0040)
AC03003F Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 003F)
0100 Go To Beginning, Then Return Value Loop
023E Resume If Return Value Loop Met
03 Leave The Routine, But When Return Continue From Spot
AC0000FC Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1001](P: 00FC)
AC0100B5 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1002](P: 00B5)
AC020038 Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1003](P: 0038)
AC03008F Set Guard ID #'S 2328 Value To Preset (Spawned Guard) Path [1004](P: 008F)
0100 Go To Beginning, Then Return Value Loop
04 Terminator
Anyway, i guess this is jibber-jabber for most poeple. My point is that the RNG which seeds the bytes could be very useful to understand. Not only for this level but for all levels.
Edit: I found the addresses of the 4 guards timers!
Edit2: Seems like these addresses are not static, so the addresses will be diffrent each time you play. Should be easy to find though since after you've gotten a bit into the level they start to continously count to 120 and then reset. Over and over and over...
Locking these values to 0(or sub 120) will hinder the guards from spawning completely. Would be great for DLTK lol if it was allowed. I guess this is a good step forward since we now know when their timers start(it's not immediately), and when the random seeding occurs. I'll continue investigating this..
These WIPs are insane. I can't believe you're actually saving time WITHOUT lookdown. Seriously, great job. I think on levels like Surface, if it's super laggy no matter what, then you should use lookdown there. Like, only do it if it makes a significant difference.
Thanks.
I honestly don't think lookdown makes as much diffrence as we thought. Surface will give a definite answer but i'd be suprised if i loose alot considering i've lost nothing so far.
--------------------------------------------------------------------------------------------
The guards timers on surface appareantly don't start until you enter one of these rooms:
So no random guards until then. Could be useful for DLTK since you can get the large key and second key(by luring the large key guard through window, like the TAS'es) before a single guard comes out. Also you can control their spawn locations by remaining in a single room for a while. It should be easy to get to safe too before any guards have spawned and are close enough to kill Bond.
Edit: Above statement is wrong, this provides no help for DLTK simply because 007 mode works diffrently than 00A(besides the guard settings). If you start up surface on 00A and just wait, no guards will come, ever. But on 007 they will appear. So on 007 their spawning works diffrently for some reason.
I wonder if there are any other fundamental diffrences between 007 and 00A?
Using .kkapture instead of mupens internal capture: http://tasvideos.org/forum/viewtopic.php?t=10779
It might work better, I think you tried encoding your last TAS with this method.
I've always thought it's because in DLTK we set their reaction speed to 100%.
Seems like you're doing a good job figuring out how the guards work.
Nope, even with normal 00A settings they spawn immediately. Also tested with reaction speed 0%.
Yeah i know pretty much everything about how they work but without the randomly seeded numbers i don't stand much chance manipulating them(except trial and error method which i'm trying to avoid).
This is probably well known, but there are several levels where body armor exists on 00, but not on 007. Iirc, these are:
Silo
Statue
Jungle (second armor)
Beyond that, I had never heard any other differences before. Really interesting research, Henrik! Encourages me to spend more time in GE Setup Editor and see if I can find any more differences.
Yeah you can really learn alot from the GE Setup Editor, and also memory watching although that's much harder. I also realized that the GE hacking community has already identified tons of memory addresses(although it seems to be diffrent then the emulated memory...) and figured out alot of the game's mechanics.
About RNG's, i've been trying for a while now to find the seeded values but without luck. When you don't know exactly when a value is seeded or for how long it remains unchanged or even how it behaves, how the hell do you find it? RNG's have been found for pretty much every RPG ever and lots of other games and i assume there must be similar issues there?? Surely there must be some general approach to this?
Alright, i made a post over at shootersforever forums and they knew precisely where i could find the random seeds. So after some converting to anti-ds mupen's address space:
008F0EF4
008F0EF6
(Unsigned short)
These can be read as a single double word or seperately. Locking these values can produce some cool effects such as guards throwing grenades over and over and over.
Joined: 1/16/2008
Posts: 358
Location: The Netherlands
(too lazy to test it myself + more a suggestion than a question)
Does shooting affect the RNG? (each shot has an inaccuracy-offset.... but is that based on an RNG or just a preset pattern? :))
I just see values that move around when I look at those addresses. How would you use them to get a grenade? Does it have to be some specific value? I would probably need some guard position addresses too... this feels a bit above my head, but it's great you found them so you can make use of them.
Presumably the guards have a list of behaviors they can choose from randomly, based on the RNG value. E.g. 0-10: crouch and shoot; 11-20: stand and shoot; 21-30: run to the side; 31-40: gun jams; 41-50: throw grenade, etc. So you have to get the RNG to the right value at the time the guard is choosing his behavior (obviously he's not choosing a new behavior every frame) if you want him to throw a grenade.
Probably the best way to figure this out is to manually set the RNG value and observe how the guards behave. For example, if you fix the RNG to 0, then the guards should always do the same action, assuming that the random number is the only input on their behavior. Actually behavior probably depends also on the guard's position with respect to the player (for example, IIRC guards never shoot unless they're on the same horizontal plane as the player), but at least for a given RNG value and situation the guard should always do the same thing. Anyway, once you've determined the values you need you can go about figuring how to achieve them without cheating.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
Well obviously they move around since they are randomly generated numbers. When for example a guard decides what action to use, they grab the first byte from one of the addresses and then compares it to some pre-determined values. So for example if a guard is gonna pull a nade, the byte must be a number between 0 and 10. 11-50 means sidestep etc...
Edit: yeah what Derakon said pretty much ^^ The Ge Setup editor can reveal exactly what numbers are needed for certain actions.
This is precisely what i did and when locking the value to 0 every guard who can throw a nade will always do so, no exceptions.
Surface 1 00A 1:43 (.533)
(Old run was 1:44.7 so this is 1.2 secs faster)
M64: https://www.yousendit.com/download/bHlDT215SWVCSWZIRGc9PQ
Finally!! This has taken longer because i can only work on weekends now but still a crazy amount of work put into this. I was forced to use lookdown for a very brief moment when entering the safe hut because lag was crazy there and i would've lost tons of time. Otherwise this was pretty much perfect.
Bunker is gonna be a nice vacation now...
Joined: 10/31/2005
Posts: 329
Location: The Netherlands
I hereby request individual level vids. I will watch it as a whole when it's done as well.
You might want to decide that before watching it yourself, lol. breaking your own ideas. :)
Joined: 1/16/2008
Posts: 358
Location: The Netherlands
Heh very smooth :D Seems that you took much more care in preserving 'fast-run' :)
Did you happen to play around with the juggle-the-key-out-of-the-hut idea? :D
I think the Large key is what opens the safe hut so juggling the key is useless. Also me and Simon tested it during last run so i'm pretty sure it's impossible(some keys can only travel up/down, not sure if that was the case here)
Bunker 1 Finished
Time: 54.7
Time is identical to my last run though i used the slower start to save real-time. 53 or low 54 might be possible with cinema watching, i found a few places where my old run lost time.
M64: http://data.fuskbugg.se/skalman02/44855346_Henrik%20-%20Goldeneye%20007%20-%20Bunker%201%20-%2054.m64
Edit: LOL i found my old files from last run and it appears that my rerecord count back then was nothing compared to now. I've used 40k more already :P
I can't download your bunker because I get a virus warning from that site. you could upload it here instead: http://dehacked.2y.net/microstorage.php
i made a ge tas too, i'll upload it today maybe , i found a small possible time saver u might not know.
i would rather see u go for ingame time