Posts for Jigwally

Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
Well I'm referring to a 100 minute improvement, presumably more than just lag lol
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
1) The Japanese version seems to be considerably faster, someone on Nicovideo redid it & you can see the difference: https://www.nicovideo.jp/watch/sm34170505 2) I know since I submitted this that at least a couple of improved solutions were discovered to some of the levels, if you get in touch with Archanfel he probably knows which ones they are
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
CasualPokePlayer wrote:
If the author wishes, this movie file can replace this submission.
Sorry I forgot to respond. Yes this is fine. Thank you for the encodes and console verification!
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
Redid my solver & found a 9 frame improvement: http://tasvideos.org/userfiles/info/71734521751488662
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
FractalFusion wrote:
I didn't have a look, but how many frames did you need to wait to manipulate the card layout?
Not sure, I just kept the intro from the previous publication because I agree with their decision that this is the fastest possible board.
FractalFusion wrote:
No one except me cares anymore how TASers end their TASes, so you can use whatever ending criteria you like. However, it would be nice to provide a version of the TAS that has the music on. I miss that.
sure lol
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
I made a couple of new Solitaire TASes that each are faster than the published TAS by different metrics: http://tasvideos.org/userfiles/info/71423838930932281 This one I put in the last input at 2241 frames, but including the time it takes for the cards to move automatically to the foundations it's about 100 frames slower in actually getting all of the cards placed. http://tasvideos.org/userfiles/info/71426279299340207 Input on this one ends on a later frame than the published TAS (2468 vs 2273) but is overall faster by 25 frames. Of these I'm guessing the 2nd one is probably considered the more suitable one for publication.
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
Remaking the TAS has been harder than I anticipated, specifically the issue I mentioned with the ingots not spawning when too great a density of them are collected. Initially this was only an issue for a few levels & I was able to work around it but I'm having a lot more trouble now for certain stages. If I worked out a measure of what that density is I could write an A* search that works around that constraint but I don't know how long it would take to produce a decent solution. Which version of the TAS is to be made hinges on whether or not the 2nd set of levels is considered required for "all game content". The levels themselves look the same both times but the change in gameplay makes then technically different. However from a casual viewer's perspective the gameplay looks nearly the same & it wouldn't even be obvious the TAS is doing anything but replay the same exact levels twice unless they read the notes. And like I said in that version of the TAS without any resets you'd have to show the same Bonus stage 7 or 8 times which is very repetitive. For reference here are some of the solutions I produced that satisfy the "Ingot Flips Back Over" rule: https://imgur.com/a/xXZ000y So there's probably a case that the current submitted version is the better publication material. But if that's not the consensus then I might request this submission be cancelled so you aren't waiting on me to finish the other version.
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
In the current TAS only the first version of the stages are played. Without resetting you'd have to play the bonus stage 3 times (between each loop) to show all content. If I redo the TAS with the harder version of the stages I have to beat them all in a row without resetting, which means playing the Bonus Stage at least 7 times. (I think the Bonus Stage is identical regardless of the loop it's on so playing it a final 8th time may be redundant). Anyway I think I have a way to modify my current solver for the harder version of the levels. A valid solution has every ingot visited an odd number of times, but rarely will any ingot need to be visited more than once. So if I assume that the solution has each ingot visited exactly once, then I can modify the distance matrix to only reflect paths where no intermediary ingots are crossed. In other words, if it is impossible to go from ingot A to ingot B without crossing over ingot C, the distance between A and B is functionally infinite (999). So I'll try that out but I have to make a new movie from the start without any resets. All of my level solutions can very easily be copy-pasted with just minor modifications to account for RNG manip so that part will go very quickly.
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
I genuinely didn't know about that. Oops Okay, the problem of solving those levels then becomes a lot more complex & I'm not sure yet the best way to do it
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
The warps between levels are intentional. You are free to travel between levels but normally you are supposed to defeat each boss to get all the keys to unlock the final door. That door is skipped with damage boosts in the Any% run
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
You were right, doing a hard reset there instead reduces a lot of the lag. Edit: I accidentally introduced some additional frames while adjusting some of the levels for lag, I went through and fixed them: http://tasvideos.org/userfiles/info/64810349029646615
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
Newest version: http://tasvideos.org/userfiles/info/64785263837932039 Spikestuff pointed out to me that you can do a soft reset to the title at two points (between Easy/Kinoko Picross and between Star Picross/Time Trial) because reloading the save is faster than going through the text message. However when I tried doing this, I had to readjust input for a bunch of new laggy levels, and in fact there were so many laggy levels that I ended up losing time vs my non-reset version. So for now I have only added the single reset right before Time Trial mode. I still don't know exactly what causes certain levels to be laggy. Nothing obvious like delaying frames at different points seems to make a difference.
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
Fixed version http://tasvideos.org/userfiles/info/64703570145989235 Notes: - Switching from SGB didn't completely eliminate the laggy levels, just caused them to happen on different levels - Time Trial puzzle got changed as a result of input changes
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
Thanks, I'm halfway through fixing it
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
I'm going to cancel and resubmit, I've optimized the route considerably which requires a rewrite of the submission text.
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
My best guess is it's to do with SubNESHawk counting both controller polls as separate frames. My most recent revision doesn't seem to have that problem.
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
Not only that, but all of the Generals' names were originally written in Kanji so CHR $1000-$7FFF still holds all of the tile graphics for those.
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
The loop that writes the tile/pattern data for the graphic is in 6502 but most of the rest is in the VM bytecode using the standard sysops for nametable printing + palette change. First I used the bootstrap to write the data below & a pointer to the image data destination to $50 and then overwrote the jump address to go to the bottom function. $6000 = destination of tile table $6340 = destination of pattern table
Function $667E -> Uses PAD1 to print the above data. $667E-667F are overwritten with the last 2 bytes, then $6680 is overwritten with 0x60 to exit.

My issue w/ continually polling PAD1 to print data was that when the interrupt happened in the middle of the input getting polled, the results got screwed up. My workaround involves having input on PAD2 the entire time this loop runs. This loop never polls PAD2 input, so if $6F ever becomes nonzero this is a "flag" that the interrupt happened and that the value in $6E can't be trusted, in which case the game takes the input again.

667E LDY #$00
6680 TYA
6681 JSR $F9B9   ; Poll PAD1 input (updates in $6E)
6684 LDA $6F     ; Check PAD2 input (should be zero)
6686 BEQ $668E
6688 STY $6F     ; If PAD2 was updated, reset to zero and retake PAD1 input
668A BNE $6680   ; (Functional JMP)
668C LDA $6E
668E STA ($50),Y
6690 INC $50     ; Increment pointer
6692 BNE $66A0
6694 INC $51
6696 BNE $6680   ; (Functional JMP)
Palette Set @ 6698
I don't think the BG color I choose here matters since I have to run another function to actually get it to change.

30 10 00 0F 30 10 0F 00 30 00 10 0F 30 00 0F 10
Function $66A8 -> Sets palette BG to white
I don't 100% understand this but w/ trial & error I got it to work this way.

66A8 LDA PPU_STATUS
66AB LDA #$3F
66AD STA PPU_ADDR
66B0 LDA #$00
66B2 STA PPU_ADDR
66B5 LDA #$30
66B7 STA PPU_DATA
66BA JMP $F3AC
(66BD-66C6) [obsoleted code I didn't remove yet]
Function $66C7 (Written in VM bytecode)

66C7 AC 0B FA    / Call $FA0B (Clear sprites)
66CA AC 7E 66    / Call $667E (Print image data)
66CD AC A8 66    / Call $66A8 (Set nametable BG to white)
66D0 8E 98 66    / Push #$6698
66D3 8D 10       / Push #$10
66D5 60          / Push #$00
66D6 E9 81 D6 06 / Call $D681 (Update nametable palettes)
66DA 8E 40 63    / Push #$6340 (pattern table)
66DD 8E 00 60    / Push #$6000 (tile table)
66E0 8D 1A       / Push #$1A (height of 27 tiles)
66E2 8D 20       / Push #$20 (width of 32 tiles)
66E4 62          / Push #$02 (y-pos 2)
66E5 60          / Push #$00 (x-pos 0)
66E6 68
66E7 E9 E6 EE 10 / Call $EEE6 -> Sysop 0x08 (Print graphic to nametable)
66EB D6 EB 88 / Jump $66EB (Loop)
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
Since I can't write my own pattern tables I started on a method of drawing images using the existing CHR-ROM. Link to video
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
The main loop for objects' behavior is around 1F:E434. The address of each object's AI script is at $42A,X (low byte) & $413,X (high byte). I'm guessing this is like Gargoyle's Quest 2, where when an object advances to a different phase of its AI script this address gets overwritten w/ a new address. Object slot #0 is Mega Man, Object slots #1-3 are his shots Any new object spawns appear in the highest available spot.
     LDA #$16
     STA $008F ; current slot
     LDX $008F
     LDA $03A0,X ; ID of object 
     BEQ $E47A ; if slot if empty
     LDA $0441,X
     TAY
     JSR $CBC0
     LDA $042A,X
     STA $0008
     LDA $0413,X
     STA $0009 
     JSR $E482 ; runs function @ $0008
The aforementioned function seems to be called from within the script for the weapon energy object(s). If there are any other object/enemy scripts that make use of $0001, and they're in the object slot 1 above the one containing the weapon energy, it should carry over if we collect the energy on the same frame. Edit: This is where the game gets the initial function address for each object:
1D:81F0 - Create object type (Y) in slot (X)

TYA
STA $03A0,X - Object ID
LDA $82C9,Y - Use ID to load address from table
STA $042A,X - Set as initial address
LDA $83C9,X
STA $0413,X
LDA $84C9,X
STA $0441,X - ?
Starting address for a small weapon energy (ID 49) is 1D:944B
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
There's this one, I will try to add a little bit to it: https://datacrystal.romhacking.net/wiki/Mega_Man_6:RAM_map I did a lot of work on Little Mermaid & Gargoyle's Quest 2 so I'm familiar with some of this engine Since $0699 (Weapon selection) is one of the values in that range, you can modify it to glitch the game. Every frame the game runs a function from a jump table based on your weapon selection (1C: $8556,Y = low byte, $8560, Y = high byte). If your weapon selection is greater than 09 the game glitches because it calls a function built from values outside the table. Edit1: This is a little different than I'm used to, some object attributes don't have a strict definition. For example, $05C8,X seems to usually track the high byte of y-velocity but when the weapon energy object is at rest it's used as a timer for the blinking animation before it disappears and when it's picked up it's used to track which weapon to refill (since once it's fallen to the ground it no longer needs to track y-velocity which frees it up for other values) Also, usually x/y speed is an unsigned value and the direction(s) of movement are determined by bitflags in another attribute value. In this game they seem to have abandoned that and the pixel/frame speeds are signed to indicate direction. Edit2: I don't know how viable this is because we don't know the actual range of values we can have in $0001 yet but this could be a method for setting up arbitrary code. e.g. if it equals E7 it will run $049E which is in the range of objects' x subpixels. Edit3: When I wrote that I forgot that since you're adding the value of the pickup (2 or 10) up to the normal max (0x1B) that limits how many addresses you can index from the jump table.
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
That's the general function for weapon energy pickup. X is the object slot that the energy is in and $05C8,X tracks misc values for each object. In this case it uses it to keep track of which weapon was selected to add energy to afterward (@ 9500)
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
Sorry for sleeping on this but I got around to writing a bootstrap for total control. It's extremely unoptimized so it doesn't happen until 9:32. I can shave that down by a lot but you have to jump through some very specific hoops to write the data without crashes. The bootstrap I write to the zero page is in the Koei VM bytecode and writes 2 bytes every 2 frames:
0029:AC A3 FC / Wait for interrupt (update PAD1/PAD2)
002C:AA 6E 00 / Push PAD1/PAD2 to stack (Destination)
002F:AC A3 FC / Wait for interrupt (update PAD1/PAD2)
0032:A4 6E 00 / Load PAD1/PAD2 (Value)
0035:B1       / Pop pointer from stack, store 2-byte value to it
0036:00 00 00
On the first iteration, write this value to close the loop:
0036:D6 29 00 / Jump to $0029
Next I need to use this to write a more optimized loop in 6502. https://www.youtube.com/watch?v=U1nRBZ7I-XI http://tasvideos.org/userfiles/info/60215123580741291
Jigwally
He/Him
Experienced Forum User, Published Author, Active player (427)
Joined: 3/11/2012
Posts: 119
Seems more feasible to just make a game notes page on here or Data Crystal to share RAM maps. Thanks for letting me know about that though, I'm going to check it out & see if there are any useful notes on the games I'm working on.