It is currently Fri Nov 24, 2017 10:28 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 35 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Wed Sep 06, 2017 10:48 am 
Offline

Joined: Wed Jul 19, 2017 10:23 am
Posts: 68
In the NES game Journey to Silius a few people have experienced a wrong death warp, meaning once you pass a check point, if you die, then you will spawn at that check point. But a few people have had the game place them at the upcoming check point instead even though they never actually went that far in the stage. Without in-depth knowledge of assembly I ask for some mild assistance to determine what memory addresses are read at the time of death and how the game determines where to place the character after the death event. I suspect that it may be a single address that controls this but it may very well be something different. No one has been able to determine how to duplicate this phenomenon beyond the few times that people have seen it happen to them. Any help would be greatly appreciated. Here are some memory addresses that may be related to it. This is an NES programming mystery to be solved... who wants to solve it?

0506 - X Position (Cam) ; Unsigned 1 bit
0500 - X Position ------; Unsigned 1 bit
0501 - X Position (Sub) ; Unsigned 1 bit
0507 - Y Position (Cam) ; Unsigned 1 bit
0504 - X-Speed ---------; Signed 1 bit
001F - Boss HP ---------; Unsigned 1 bit
00B0 - Player HP -------; Unsigned 1 bit
00B1 - Player Ammo -----; Unsigned 1 bit


Top
 Profile  
 
PostPosted: Wed Sep 06, 2017 12:39 pm 
Offline
User avatar

Joined: Sat Jul 12, 2014 3:04 pm
Posts: 950
Not sure this is the best place for it, but…I wish you luck. I might be able to look into it later.

I'd check… http://datacrystal.romhacking.net/wiki/ ... _to_Silius doesn't have a ROM nor RAM map, oh. A thread on TASvideos has a handful more memory addresses.

I see you got the list of "useful addresses" from one of the latest TAS submission texts…including that "1 bit" claim. I suspect those are 1-byte variables instead.


Top
 Profile  
 
PostPosted: Wed Sep 06, 2017 2:44 pm 
Offline

Joined: Wed Jul 19, 2017 10:23 am
Posts: 68
Thanks for the links. I will post any findings here regarding this matter. Please feel free to look into how the game determines where you appear after a death. Finding out how this wrong warp occurs would be huge, and it is only a matter of someone who knows how to pick this apart, someone knowledgeable would be able to do it rather quickly.


Top
 Profile  
 
PostPosted: Wed Sep 06, 2017 4:40 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5842
Location: Canada
What I'd suggest for step 1 is just record an FCEUX movie until you make the bug happen. Stop there and save the movie. (Or if this bug is exploited by an existing TAS, tell us where to get the .FM2 and at what frame it happens.)

That is basically required work for investigating this problem, and it's not something you have to have expert knowledge to do. Once you have a recorded case of the bug, give that to an expert.


Top
 Profile  
 
PostPosted: Wed Sep 06, 2017 5:06 pm 
Offline
User avatar

Joined: Thu Jan 03, 2008 1:48 pm
Posts: 543
Check the checkpoints. See if there are some flags/registers set in memory in correspondence to those flags. Find the address; edit the value of the address; kill the player. Does the spawn location change?


Top
 Profile  
 
PostPosted: Wed Sep 06, 2017 6:39 pm 
Offline

Joined: Wed Jul 19, 2017 10:23 am
Posts: 68
So far no one who TASed this game has been able to reproduce the bug. I spent two hours doing random things in the same spot, mimicking a video that captures this phenomenon and so far no results. So I moved on to looking at RAM addresses, particularly any value changes at the moment of when I pass through a check point, hoping that I would be able to see if there are ways to manipulate this address via game play, something I may be able to catch while doing trials. I have started the process messing with a lua script to write in values to different addresses to see if I can narrow a few of them.


Top
 Profile  
 
PostPosted: Wed Sep 06, 2017 7:40 pm 
Offline

Joined: Wed Jul 19, 2017 10:23 am
Posts: 68
Here is an example of what I mean by a wrong warp, finally was able to have it happen so now I can maybe cross reference the ram addresses in each state, hmmm, is there a quick way of doing that?

https://www.youtube.com/watch?v=xCHi_bzwrjU


Top
 Profile  
 
PostPosted: Wed Sep 06, 2017 9:56 pm 
Offline

Joined: Wed Jul 19, 2017 10:23 am
Posts: 68
Ok so I made some progress. Memory Address 017E determines the next spawn. This value goes up the farther you progress in the level, so what causes the wrong warp is that sometimes this value increases quicker than usual but I have not been able to isolate what influences this value to duplicate it. So if the value is 4 when you die it will put you back at the beginning of the level at value 0, but if you die at 6 then it puts you back at 5. So in the video above the value of the next spawn point is 10, and in the case where it does not work that value is only at a 9 so it places me back at 5, and in the case where it does work then that value is 11 so it places you at 10. :D Now to isolate why it increases quicker in the latter case.


Top
 Profile  
 
PostPosted: Wed Sep 06, 2017 10:39 pm 
Offline

Joined: Wed Jul 19, 2017 10:23 am
Posts: 68
This is the state of the debugger when a value increments this address but I am not sure what I am looking at here. Any thoughts?


Attachments:
execution.PNG
execution.PNG [ 11.27 KiB | Viewed 1041 times ]
Top
 Profile  
 
PostPosted: Thu Sep 07, 2017 2:18 am 
Offline
User avatar

Joined: Thu Jan 03, 2008 1:48 pm
Posts: 543
OK. Here's some stuff:
Code:
Macro Frame Location = $30
Micro Frame Location = $31
"Ground level" Baseline Value = $32
Walking speed value added to $31 = $34
Lives = $53
Energy = $B0 ; #$FF-$#81 or #$00 = death / $#80 off-screen / #$01-#$7F = positive health
Gun Types Available = $B7 (bitwise)
Selected Gun Type = $B8
Restart Spawn Point = $B9 ; non-zero spawn again
Spawn at Boss = $153 ; #$10 or greater = Boss
P1 Control Values = $162/$163 ; mirrored for DPCM input corruption?
P2 Control Values = $164/$165 ; mirrored for DPCM input corruption? (Used?)
Level Checkpoint for Respawn = $170
Scrolling Boundary = $177; 0 = on / 1 = off
Area Checkpoint for Respawn = $17E ; not all values are respawnable

Titlescreen B Presses for Secret = $301 ; restarts if non-B pressed


Spawn locations are checked up with an indirect value that points to a table of "valid" checkpoint locations per level...
(Thought about if values could be changed during that sequence or read from others... Seems not.)
This is that routine:

Code:
  LDA #$00    ;             
  STA $BF     ; Turn character control on. / no control if nonzero             
  LDA $0170   ; What level should we be at?  ($0170 is only manipulated with an INC clause.)   
  ASL A       ; Shift value of level bitwise to left             
  TAY         ; Transfer shifted level value to Y             
  LDA $0153   ; Are we at a boss level?             
  BEQ $DCE9   ; If so, continue down; if not, skip ahead to Spawn Locations.             
  TYA           
  CLC                     
  ADC #$0A               
  TAY                     
  LDA $DD37,Y ; Data table Address of Spawn Locations LSB (little endian) plus Y           
  STA $00     ; " "             
  LDA $DD38,Y ; Data table Address of Spawn Locations MSB (little endian) plus Y           
  STA $01     ; " "             
  LDY #$00                 
  LDA ($00),Y ; Load the spawn location token to $02 and clear Y             
  STA $02     ; " "             
  INY         ;             
  LDA ($00),Y ; Load the value of the address of the spawn token plus 1.           
  CMP $017E   ; What's the achieved, current checkpoint location?           
  BCS $DD0A   ;             
  INY         ;             
  INY         ;             
  INY         ;             
  INY         ;             
  INY         ;             
  DEC $02     ;             
  BNE $DCFA   ;             
  INY         ;             
  LDA ($00),Y ; Check for the closest, valid checkpoint location value           
  STA $017E   ; compared to the data table and store it.               
  INY         ;             
  LDA ($00),Y ; If loaded a 00 value and stored into $0177, it's a boss level.           
  STA $0177   ; " "           
  INY         ;             
  LDA ($00),Y ;             
  STA $0500               
  AND #$F0                 
  STA $30                 
  INY                     
  LDA ($00),Y             
  STA $0502               
  AND #$F0                 
  STA $32                 
  LDA #$00                 
  STA $0501               
  STA $0503               
  STA $31                 
  STA $33                 
  RTS                     
 


Now... I've debugged the first level through a routine and the only way $017E is written to is an INC function, which happens after so many bytes (compared to a ROM address table) are reached. Is there a particular level where the death skip is reported more frequently?
Code:
  LDA $017B ; if $017B is nonzero then run the INC $017E routine!               
  BNE $DFEA ; " "               
  LDA $30   ; Where is the player? Increments when scrolls left.             
  LSR A     ;  MS(nibble) of $30 is the checkpoint value.             
  LSR A     ;               
  LSR A     ;               
  LSR A     ;               
  STA $00                 
  LDA $32 ; is player on the screen or not?                 
  AND #$F0 ;               
  ORA $00                 
  STA $00                 
  AND #$01                 
  TAX                     
  LSR $00                 
  LDY $00                 
  LDA ($54),Y             
  AND $E06B,X             
  CPX #$01                 
  BEQ $DFDE  ; skip to checking if it's #$0F or greater.
  LSR A                   
  LSR A                   
  LSR A                   
  LSR A                   
  AND #$0F  ;               
  CMP #$0F  ;               
  BEQ $DFEB ; go to scrolling/walking routine and do not increment. :(             
  STA $0177               
  INC $017E ; increment the checkpoint!               
  RTS

Dude, it looks like we'd need to find out how to continue incrementation of $30 in order to increment $017E... That or find a way to fake the game out to think it's scrolling when it's not.


Top
 Profile  
 
PostPosted: Thu Sep 07, 2017 6:08 am 
Offline

Joined: Wed Jul 19, 2017 10:23 am
Posts: 68
The following link is to the video I did showing the death warp. Now, I have found that for some reason when you take a hit in the face at the bottom of the 2nd elevator it may cause address 017E to jump, and when it does I have observed that it can increase as much as 6, so instead of having a value of 8 at that point in the stage you end up with a 14! This is what enables you to die later in the stage when the value hits 26 and it will warp you forward to where that value is usually achieved. I also created a tas video attached that shows this occurring in level 4. You will just need to watch it up to that point, see video link for reference. And see what is happening in the ram as to why this spike in value occurs. That would be awesome!

https://www.twitch.tv/videos/172953158


Attachments:
zakem66v1-journeytosilius wrong warp good.fm2 [494.57 KiB]
Downloaded 17 times
Top
 Profile  
 
PostPosted: Fri Sep 08, 2017 1:30 am 
Offline

Joined: Wed Jul 19, 2017 10:23 am
Posts: 68
This is the Trace Logger Data for the single frame when the extra increment occurs. This is when you are hit by the enemy and you boost backward scrolling the screen.
Code:
A:12 X:DD Y:00 S:F3 P:nvUbdIzC  $DEFC:18        CLC
A:12 X:DD Y:00 S:F3 P:nvUbdIzc  $DEFD:69 E0     ADC #$E0
A:F2 X:DD Y:00 S:F3 P:NvUbdIzc  $DEFF:A9 FF     LDA #$FF
A:FF X:DD Y:00 S:F3 P:NvUbdIzc  $DF01:65 30     ADC $0030 = #$60
A:5F X:DD Y:00 S:F3 P:nvUbdIzC  $DF03:4C 08 DF  JMP $DF08
A:5F X:DD Y:00 S:F3 P:nvUbdIzC  $DF08:29 F0     AND #$F0
A:50 X:DD Y:00 S:F3 P:nvUbdIzC  $DF0A:85 02     STA $0002 = #$20
A:50 X:DD Y:00 S:F3 P:nvUbdIzC  $DF0C:A5 30     LDA $0030 = #$60
A:60 X:DD Y:00 S:F3 P:nvUbdIzC  $DF0E:29 F0     AND #$F0
A:60 X:DD Y:00 S:F3 P:nvUbdIzC  $DF10:C5 02     CMP $0002 = #$50
A:60 X:DD Y:00 S:F3 P:nvUbdIzC  $DF12:F0 03     BEQ $DF17
A:60 X:DD Y:00 S:F3 P:nvUbdIzC  $DF14:20 B5 DF  JSR $DFB5
A:60 X:DD Y:00 S:F1 P:nvUbdIzC  $DFB5:AD 7B 01  LDA $017B = #$00
A:00 X:DD Y:00 S:F1 P:nvUbdIZC  $DFB8:D0 30     BNE $DFEA
A:00 X:DD Y:00 S:F1 P:nvUbdIZC  $DFBA:A5 30     LDA $0030 = #$60
A:60 X:DD Y:00 S:F1 P:nvUbdIzC  $DFBC:4A        LSR
A:30 X:DD Y:00 S:F1 P:nvUbdIzc  $DFBD:4A        LSR
A:18 X:DD Y:00 S:F1 P:nvUbdIzc  $DFBE:4A        LSR
A:0C X:DD Y:00 S:F1 P:nvUbdIzc  $DFBF:4A        LSR
A:06 X:DD Y:00 S:F1 P:nvUbdIzc  $DFC0:85 00     STA $0000 = #$60
A:06 X:DD Y:00 S:F1 P:nvUbdIzc  $DFC2:A5 32     LDA $0032 = #$20
A:20 X:DD Y:00 S:F1 P:nvUbdIzc  $DFC4:29 F0     AND #$F0
A:20 X:DD Y:00 S:F1 P:nvUbdIzc  $DFC6:05 00     ORA $0000 = #$06
A:26 X:DD Y:00 S:F1 P:nvUbdIzc  $DFC8:85 00     STA $0000 = #$06
A:26 X:DD Y:00 S:F1 P:nvUbdIzc  $DFCA:29 01     AND #$01
A:00 X:DD Y:00 S:F1 P:nvUbdIZc  $DFCC:AA        TAX
A:00 X:00 Y:00 S:F1 P:nvUbdIZc  $DFCD:46 00     LSR $0000 = #$26
A:00 X:00 Y:00 S:F1 P:nvUbdIzc  $DFCF:A4 00     LDY $0000 = #$13
A:00 X:00 Y:13 S:F1 P:nvUbdIzc  $DFD1:B1 54     LDA ($54),Y @ $806A = #$21
A:21 X:00 Y:13 S:F1 P:nvUbdIzc  $DFD3:3D 6B E0  AND $E06B,X @ $E06B = #$F0
A:20 X:00 Y:13 S:F1 P:nvUbdIzc  $DFD6:E0 01     CPX #$01
A:20 X:00 Y:13 S:F1 P:NvUbdIzc  $DFD8:F0 04     BEQ $DFDE
A:20 X:00 Y:13 S:F1 P:NvUbdIzc  $DFDA:4A        LSR
A:10 X:00 Y:13 S:F1 P:nvUbdIzc  $DFDB:4A        LSR
A:08 X:00 Y:13 S:F1 P:nvUbdIzc  $DFDC:4A        LSR
A:04 X:00 Y:13 S:F1 P:nvUbdIzc  $DFDD:4A        LSR
A:02 X:00 Y:13 S:F1 P:nvUbdIzc  $DFDE:29 0F     AND #$0F
A:02 X:00 Y:13 S:F1 P:nvUbdIzc  $DFE0:C9 0F     CMP #$0F
A:02 X:00 Y:13 S:F1 P:NvUbdIzc  $DFE2:F0 07     BEQ $DFEB
A:02 X:00 Y:13 S:F1 P:NvUbdIzc  $DFE4:8D 77 01  STA $0177 = #$02
Breakpoint 0 Hit at $DFE7: $017E:EC-W--
Logging finished.

And this is the last segment in the Debugger. There must be a reason why sometimes it will increment many times in successive frames upon taking this hit and sometimes it does not. Any thoughts?
Code:
07:DF8E:60        RTS -----------------------------------------
 07:DF8F:A5 32     LDA $0032 = #$20
 07:DF91:29 0F     AND #$0F
 07:DF93:C9 0F     CMP #$0F
 07:DF95:D0 0D     BNE $DFA4
 07:DF97:20 D6 E0  JSR $E0D6
 07:DF9A:A5 32     LDA $0032 = #$20
 07:DF9C:29 F0     AND #$F0
 07:DF9E:09 0E     ORA #$0E
 07:DFA0:85 32     STA $0032 = #$20
 07:DFA2:D0 D6     BNE $DF7A
 07:DFA4:A5 33     LDA $0033 = #$00
 07:DFA6:18        CLC
 07:DFA7:65 35     ADC $0035 = #$00
 07:DFA9:A5 32     LDA $0032 = #$20
 07:DFAB:69 FF     ADC #$FF
 07:DFAD:29 0F     AND #$0F
 07:DFAF:C9 0F     CMP #$0F
 07:DFB1:D0 C7     BNE $DF7A
 07:DFB3:F0 C2     BEQ $DF77
 07:DFB5:AD 7B 01  LDA $017B = #$00
 07:DFB8:D0 30     BNE $DFEA
 07:DFBA:A5 30     LDA $0030 = #$60
 07:DFBC:4A        LSR
 07:DFBD:4A        LSR
 07:DFBE:4A        LSR
 07:DFBF:4A        LSR
 07:DFC0:85 00     STA $0000 = #$13
 07:DFC2:A5 32     LDA $0032 = #$20
 07:DFC4:29 F0     AND #$F0
 07:DFC6:05 00     ORA $0000 = #$13
 07:DFC8:85 00     STA $0000 = #$13
 07:DFCA:29 01     AND #$01
 07:DFCC:AA        TAX
 07:DFCD:46 00     LSR $0000 = #$13
 07:DFCF:A4 00     LDY $0000 = #$13
 07:DFD1:B1 54     LDA ($54),Y @ $806A = #$21
 07:DFD3:3D 6B E0  AND $E06B,X @ $E06B = #$F0
 07:DFD6:E0 01     CPX #$01
 07:DFD8:F0 04     BEQ $DFDE
 07:DFDA:4A        LSR
 07:DFDB:4A        LSR
 07:DFDC:4A        LSR
 07:DFDD:4A        LSR
 07:DFDE:29 0F     AND #$0F
 07:DFE0:C9 0F     CMP #$0F
 07:DFE2:F0 07     BEQ $DFEB
 07:DFE4:8D 77 01  STA $0177 = #$02
>07:DFE7:EE 7E 01  INC $017E = #$08
 07:DFEA:60        RTS -----------------------------------------


Top
 Profile  
 
PostPosted: Fri Sep 08, 2017 2:41 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1835
Location: DIGDUG
Perhaps this subroutine is called more than once. Please don't post an trace of multiple frames (if so).

There's nothing here that explained why.

Check the code is that is calling this subroutine.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Fri Sep 08, 2017 7:50 am 
Offline

Joined: Wed Jul 19, 2017 10:23 am
Posts: 68
Pertinent Information
017E Spawn Location
0177 Scroll Boundary
0030 Macro Frame Location
0031 Micro Frame Location
0032 Vertical Location
0034 Run Speed

Basic Observation #1
The Run Speed value is added to Micro Frame Location each frame. The Run Speed value has an acceleration stage such that it increases, 4, 8, 12, 16, 20, 24, and then fluctuates between 22 and 26 each frame.

Basic Observation #2
While your character jumps the Run Speed value will fluctuate between 21, 22, and 23, so the length of a jump will also influence the final value of the Micro Frame Location upon reaching the Scroll Boundary.

Basic Observation #3
When the Scroll Boundary value changes, the code increments Spawn Location by 1.

Basic Observation #4
When the Micro Frame Location value exceeds 255 it will roll over to 0 and this will increment Macro Frame Location by 1.

Basic Observation #5
Every 16 counts on the Macro Frame Location value will increment the Spawn Location by 1. The Macro Frame Location value increases with scrolling to the right, and decreases with scrolling to the left. Likewise every 16 counts on the Vertical Location will also increment the Spawn Location by 1. Vertical Location increases with scrolling down and decreases with scrolling up.

Interestingly I can see what is occurring in order for this glitch to work but I do not understand why it happens. And if I could understand why then perhaps that knowledge could be used to determine if it could be exploited in other areas of the game and if so then where.

When you reach the top of the 2nd elevator in Stage 4, when you reach this Scroll Boundary the Macro Frame Location value seems to reach 96 every time, as the Micro Frame Location rolls over around this time. Depending upon the Run Speed values through this section of stage 4, as well as the value changes when in a jump animation, or knock backs, this may cause the Micro Frame Location value to roll over to 0 or it could go as high as 24 depending upon the Micro Frame Location value the previous frame. Such that if the Micro Frame Location value were 230 and the Run Speed was 26 then on the following frame the Micro Frame Location value will roll over to 0. Likewise, if the Micro Frame Location value was 254, then it would roll over to 24 with a Run Speed of 26 the previous frame.

Therefore, when you reach the top of the 2nd elevator in Stage 4, the Micro Frame Location value could be anywhere between 0 and 25.

When you reach the bottom of the 2nd elevator and get hit by an enemy bullet the screen will scroll to the left, and the Micro Frame Location value will decrease by 4 every frame while in the damage animation which scrolls the screen. Depending upon the Micro Frame Location value, such that if it were 24, then it would reach 0 after 6 frames. Interestingly enough each time the Micro Frame Location value decreases by 4 while the Macro Frame Location value is 96, the Spawn Location value will increment by 1 each frame.

Therefore, for some reason, once the Macro Frame Location reaches 95, the Spawn Location will no longer increment even though your character is in the same damage animation scrolling the screen. In other words, it is related to screen scrolling but the magic number seems to be Macro Frame Location value 96. As long as this value is 96, the Spawn Location value will increment by 1 each frame, otherwise it will not.

Here is a video of me demonstrating these additional increments: https://www.twitch.tv/videos/173221791

Here is a video of me demonstrating the strategy I developed in order to get the best death warp 50% of the time: https://www.twitch.tv/videos/173225643


Last edited by CLChambers00 on Fri Sep 08, 2017 9:39 am, edited 2 times in total.

Top
 Profile  
 
PostPosted: Fri Sep 08, 2017 7:56 am 
Offline
User avatar

Joined: Thu Jan 03, 2008 1:48 pm
Posts: 543
Yes... Also remember that $32 (Vertical (up/down) frame location) is a part of the equation regarding checkpoint value incrementation. I've noticed areas in Level 2 simply by falling down gaps that the checkpoint counter increases.

(I've even tried seeing if for some reason someone could trigger a boss spawn on death as well.)

Edit: Yeah... I meant up/down. (Gotta get my sleep more regular. :))


Last edited by B00daW on Fri Sep 08, 2017 9:42 am, edited 1 time in total.

Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 35 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Pokun and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group