Thanks for telling me this! I thought SGB was supposed to be emulated completely under SNES mode. Duh.
I tried the very first clipping for both SGB mode and monochrome mode, and they work the same. The GBC version doesn't behave differently under SGB mode ether. Therefore the conclusion is that SGB mode does not affect the layout of a glitch hell in a rom.
I was recently asked about this game in terms of "All Stages"/"100%" routing. Some discoveries as follows:
1. Secret doors in final boss stages count as boss defeated. Normal exits count as next level.
2. Stage ID addresses are 0x1510 (GBC) or 0x0510 (GB).
3. With respect to the above, this means if you can find a secret exit in the robot spear man stage (ID 29), you can trigger the credits. Beating it via normal exit OoB advances to ID 30 (Chapter 2 basement)
So with that said, from the submission text:
I can now say, sorry, me and mugg remembered it wrong.
4. If you tried the trick at the factory final stage (ID 49), you can advance to the Secret stage. If you managed to beat the secret stage, this occurs:
Then, you're stuck forever.
However, if you tried it AFTER beating the game once on the stage select, this happens instead:
5. Factory Final GBC OoB is mostly unbreakable blocks below the stage, and unreachable glitch blocks at the top. Even attempting to use the hammer NPC to get the bouncy status fails, since there's a ceiling of unbreakable blocks.
In GB, the glitched blocks are much lower, thus a secret exit (and trigger credits) can easily be reached
6. The same situation almost occurred with ID 29, but luckily there's an NPC that allowed you to reach an opening.
The closest normal exit I found in GBC was:
https://cdn.discordapp.com/attachments/688394402472788033/689339903649120267/Wario_Land_II_USA_Europe_exit.bk2
And for 100%:
https://cdn.discordapp.com/attachments/688394402472788033/689375423548882984/Wario_Land_II_USA_Europe_treasure__boss.bk2
This input file finds an OoB bonus door, then immediately goes to the boss room in the first room. While that is normally slower than using exit door, since getting the level select as fast as possible was apparently quicker to skip cutscenes, this may help.
7. I managed to find a workable OoB exit in the latest BizHawk version in GB for Chapter 2 To The Castle (ID 25):
In GBC, this completely breaks apart, since the red blocks vanish shortly after touching them from the sides or above.
8. For both "Defeat the giant spear man" and "Go through the grand hall" (IDs 27, 28), I found OoB bonus rooms right near a exit in GBC. Need to test GB as well.
9. The original script only works for GBC. After messing around, it appears the layout is similar, but with different addresses and IDs. So I changed it (among other things) to include GB support:
Download WL2Overlay.lua
Language: lua
local x, y, camx, camy, tref, ttype, ttypehigh, tcolor, warpdest
local address = {
gbc = {
x = 0x153c,
y = 0x153a,
camx = 0x660,
camy = 0x65f,
tref = 0x704,
warpdest = 0xa1,
stageid = 0x1510
},
gb = {
x = 0x053c,
y = 0x053a,
camx = 0x1652,
camy = 0x1651,
tref = 0x16EB,
stageid = 0x0510
}
}
local tiles = {
gbc = {
[0x47bc] = "Switch platform",
[0x49cb] = "Slideable slope (left)", --Press down to roll
[0x495e] = "Slideable slope (right)", --Press down to roll
[0x4a10] = "Platform",
[0x4a33] = "Platform (NPC)", --NPCs can walk on them, you cannot
[0x4a70] = "Breakable", --(ttype>0x4a70) and (ttype<0x4d9f) or (ttype==0x4a10)
[0x4d9f] = "Breakable",
[0x4da0] = "Breakable (NPC)", --throw npcs to destroy them
[0x4e8a] = "Water",
[0x4fbe] = "Minigame", --varies by stage
[0x4ecd] = "Minigame", --varies by stage
[0x4edb] = "Door",
[0x4ef6] = "Boss door", --varies by stage
[0x4f3a] = "Exit",
[0x4f60] = "Secret exit",
[0x4ffb] = "Switch"
},
gb = {
[0x47bc] = "Switch platform",
[0x49cb] = "Slideable slope (left)",
[0x495e] = "Slideable slope (right)",
[0x4a10] = "Platform",
[0x4a33] = "Platform (NPC)", --NPCs can walk on them, you cannot
[0x4a70] = "Breakable", --(ttype>0x4a70) and (ttype<0x4d9f) or (ttype==0x4a10)
[0x4d9f] = "Breakable",
[0x4d95] = "Breakable (NPC)", --throw npcs to destroy them
[0x4d99] = "Breakable (NPC)", --throw npcs to destroy them
[0x4e83] = "Water",
[0x4fb7] = "Minigame",
[0x4ed4] = "Door",
[0x4eef] = "Boss door",
[0x4f33] = "Exit",
[0x4f59] = "Secret exit",
[0x4cef] = "Breakable (Invisible)",
[0x4ff4] = "Switch",
[0x50fb] = "Water"
}
}
function bitswap (swappy)
nib2 = bit.band(swappy,0xF)
return (nib2*0x10+bit.rshift(swappy,4))
end
function gettile (wx,wy)
hix = bit.rshift(bit.band(0xFF00,wx),8)
hiy = bit.rshift(bit.band(0xFF00,wy),8)
lox = bit.band(0xFF,wx)
loy = bit.band(0xFF,wy)
ccea = bit.band(bitswap(bit.band(hiy,0x0F))+bit.band(bitswap(loy),0x0F)+0xA0,0xFF)
cceb = bitswap(bit.band(hix,0x0F))+bit.band(bitswap(lox),0x0F)
rawloc = ccea*0x100+cceb -- not the final location!!! can vary if above 0xa000
return (rawloc)
-- return (bit.band(0x2000 + 0x100*math.floor(wy/16+1) + math.floor(wx/16),0x7FFF)) works for most space, not glitch rooms
end
function tileid (ntile)
if (ntile >= 0xa000) then
memory.usememorydomain('CartRAM') -- where normal level data is
realloc = ntile - 0x8000
else
memory.usememorydomain('System Bus')
realloc = ntile
end
tlookup = memory.readbyte(realloc)
memory.usememorydomain('ROM')
local address = 0x7c002+tref+bit.band(tlookup*2,0xFF)
local result = memory.read_u16_le(address)
-- -- if result == 0x4f60 then
-- if result == 0x4f3a then
-- -- memory.write_u16_le(address,0x4f3a)
-- memory.write_u16_le(address,0x4f60)
-- end
return result
end
local game_address = address.gbc
local game_tiles = tiles.gbc
while true do
x = mainmemory.read_u16_be(game_address.x) -- position in level
y = mainmemory.read_u16_be(game_address.y)
camx = mainmemory.readbyte(game_address.camx) -- position relative to upper left camera edge
camy = mainmemory.readbyte(game_address.camy)
tref = mainmemory.read_u16_be(game_address.tref)
-- warpdest = mainmemory.readbyte(game_address.warpdest) -- sector coordinates for a warp (??)
-- 160x144
-- gui.drawText(3,130,string.format("%X",bit.rshift(warpdest,4))..' '..string.format("%X",bit.band(warpdest,0xF)))
for i = -1,17,1 do
for j = -1,17,1 do
ttype = tileid(gettile(x-camx+15+16*i,y-camy+15+16*j))
ttypehigh = bit.band(ttype,0xFF00)
if (ttype~=0x47ab) and (ttype~=0x49a7) and not ((ttype>=0x4e29) and (ttype<=0x4e39)) and not ((ttype>=0x5400) and (ttype<=0x54ff)) then
--if (ttype~=0x47ab) and (ttype~=0x4cf3) and (ttype~=0x4cef) and (ttype~=0x4d03) and (ttype~=0x4cff) and (ttype~=0x4e29) and (ttype~=0x4e35) and (ttype~=0x4f3a) then
-- if (ttype==0x4ecd) or (ttype==0x4edb) or (ttype==0x4f3a) or (ttype==0x4f60) then -- door, minigame, exit
-- tcolor = 'GREEN'
if game_tiles[ttype] ~= nil then
if (game_tiles[ttype]=="Door") then --Regular door
tcolor = 'BLACK'
elseif (game_tiles[ttype]=="Boss door") then --Boss door
tcolor = 'GREEN'
elseif (game_tiles[ttype]=="Minigame") then -- Minigame
tcolor = 'PURPLE'
elseif (game_tiles[ttype]=="Exit") then -- exit
tcolor = 'CYAN'
elseif (game_tiles[ttype]=="Secret exit") then --secret exit
tcolor = 'GOLD'
elseif (game_tiles[ttype]=="Water") then -- water
tcolor = 'BLUE'
elseif (game_tiles[ttype]=="Platform") then -- platform
tcolor = 'WHITE'
elseif (game_tiles[ttype]=="Platform (NPC)") then -- platform
tcolor = 'GREY'
elseif (game_tiles[ttype]=="Slideable slope (left)") or (game_tiles[ttype]=="Slideable slope (right)") then -- platform
tcolor = 'BROWN'
elseif (ttype>0x4a70) and (ttype<0x4d9f) or (ttype==0x4a10) then -- breakable
tcolor = 'PINK'
elseif (game_tiles[ttype]=="Breakable (NPC)") then
tcolor = "DEEPPINK"
else -- solid or unknown
tcolor = 'RED'
end
end
gui.drawBox((camx-x)%16-8+16*i,(camy-y)%16-16+16*j,(camx-x)%16+7+16*i,(camy-y)%16+16*j-1,tcolor)
end
end
end
gui.drawText(3,3,string.format("%X",gettile(x,y-32))..' '..string.format("%X",tileid(gettile(x,y-32))))
gui.drawText(3,12,string.format("%X",gettile(x,y-16))..' '..string.format("%X",tileid(gettile(x,y-16))))
gui.drawText(3,21,string.format("%X",gettile(x,y))..' '..string.format("%X",tileid(gettile(x,y))),"BLACK","BLACK")
gui.drawText(4,22,string.format("%X",gettile(x,y))..' '..string.format("%X",tileid(gettile(x,y))))
gui.drawText(3,31,"X:"..x.." Y:"..y,"BLACK","BLACK")
gui.drawText(4,32,"X:"..x.." Y:"..y,"WHITE")
emu.frameadvance()
end
Original script: http://tasvideos.org/userfiles/info/16322306121342073
Thanks very much for Slamo for the initial version!
10. For floating OoB doors, you need swimming status to enter them
11. Last night, when exploring Factory Final (ID 49) on GB, the glitched area was solidish, and easily reachable:
Attempting to record it from start of stage however, changed it into this:
Which made the glitched area much harder to reach. I have no idea what changed the layout, since the 1st attempt was from a savestate, not start of stage.
Lots of very interesting things and funny to see how broken this game can be. Are you working on a 100% run or do you planning to do this on the futur ? And would it be better to run it on GBC or GB for faster execution ?
GBC has a different OoB layout; for instance the glitched area in 2-2 in the current TAS still works in GB in BizHawk, but doesn't in GBC. However, certain tricks that do work in GBC (such as the one mentioned in the post above with bonus room leading to final boss room, and similar tricks in the 2 stages before it) can't seem to be done in GB (yet), or is slower. So might need to check every slow stage to see what is faster.
Not helped by the fact it seems the OoB layout sometimes changes in the same room, in the same game version. I just edited the post from before, but it seems in GB Factory Final, the OoB can be either extremely easy to reach, or mostly out of reach like in GBC, and I have no idea what caused the change.
Unrelated, but messing around while not recording changed all the bees into skull in 2-2:
I can't seem to replicate it however.
While routing for 100%, I asked TiKevin83 to check for if the OoB in this game was emulated right by given them input files for any% improvement. An input file that did not soft reset the game synced back, but the one that did use a soft reset to alter OoB layout did not. Since the Spearman stage for 100% needs reset to reach the OoB exit after obtaining the treasure, I'm uncertain if the route works on console. I gave him the input file, but since he's busy, I decided to work on the OoB-less run instead.
With that said, I rediscovered that from old posts, there's a 724 frame improvement to the previous TAS that does not use OoB exits. Given the links to the WIPs are dead, I decided to resync the current run (up to last boss, because diff rng ruined it) and see if the improvement could be refound:
http://tasvideos.org/userfiles/info/63000414314992766
Edit: 879 frames improved, mostly from using inputs from the latest run, + wallclip savings mentioned by MUGG.
https://youtu.be/-siFfVFZxUYhttp://tasvideos.org/userfiles/info/63043461467067961
Edit2: Improved 7 more frames by cancelling 1st dash jump instead of crouching in the giant spearman room with frostie
Also the 4 frame rule between transitions also affect the minigame screens. Since the number for the end stage minigame is determined at start of minigame, this means it can only be changed once every 4 frames
Edit 3: I investigated avoiding coins for the any%. Every time you have less than 50 coins you save 56 frames at the number guessing minigame since it just gives you a message "You have no coins" that can accept input sooner.
Stage 1 (One Noisy Morning) 0 coins
Stage 25 (To the Castle) 4 coins (3 from 1st screen, 1 from OoB)
Stage 26 (Storm the Castle) 45 coins
Stage 27 (Defeat the Giant Spearman) 1 coin (OoB)
Stage 28 (Through the grand hall) 19 coins, assuming 0 from blocks
Stage 29 (Kick em out!) varies, way more than 50 due to OoB
https://docs.google.com/spreadsheets/d/1XevsUFWknCozzJ7IRKbHigPpSeJnk5FJFZm4lNmFnjM/edit?usp=sharing
This means the main issue is stage 26. From the spreadsheet, I timed every screen in this stage. This was done on GBC instead of GB, since there was no lag in GBC, but the results apply as well.
Compared to ignoring coins, it seems to be fastest is skip 4 coins at beginning, then avoid as much coins as possible reset of stage. This will give 25 coins.
0 + 4 + 25 + 1 + 19 = 49 coins by 2nd last stage.
Last stage coins are unavoidable, so ignoring that.
This takes an additional 49 frames for 2-2, but saves 56 frames per end level for the next 2 stages, so it's a gain.
I wasn't going to post, but:
https://cdn.discordapp.com/attachments/280806848909541376/750422414109704350/Wario_Land_II_100_GBC.bk2
I decided to compare it with the 100% TAS that currently exists, and discovered that the 1st room of 2-1 (Stage ID 25) was slower than the existing run by 1 frame. Due to the 4 frame rule, this doesn't affect the run since it ends up taking the same amount of time to fade out.
However, when I tried to replace that particular room's input with the current published run's input to make it neater, I discovered the run the run desyncs next stage due to different RNG, despite everything else syncing:
Left: The WIP I posted.
Right: The same, except the 1st room of 2-1 has been changed.
Given I even got a different coin drop amount, this suggest it's possible to manipulate silver coins along with the minigame results without losing too much time by doing different things slower (while still within the 4 frame window) on a previous stage.
I do not know the RNG addresses for the game however, so the use of this might be limited to manual testing. Also I'm not changing anything before the robot spearman because I hate that boss.
Also for future reference on how I approached the boss:
See this antenna on top? It cycles through its animation every 12 frames or so. Note the fuel at start of cycle
If the fuel counter goes down every frame, dont press anything unless you have to. If it doesn't, try pressing buttons on TAStudios. Note the fuel counter by the start of the next cycle
In this case, it dropped by 3. Save. Then try other inputs & see if you can get the fuel counter lower at the same frame (eg. 252 instead of 253). Do this for every single cycle; it makes it more manageable to compare progress. Try to match the previous run's fuel in terms of it's antenna animation
These are the "milestone" points I aim for +/- 2. The bottom right panel is in the middle of a cycle, but if the robot stops 1 pixel earlier I wont be able to hit it 3 times.
The fuel for the top left in the previous run was 215 instead, but as long as you're +/- 2 from that you can make it
Afterwards you need to manipulate it such that the last 4-10 units of fuel ALL deplete with no delay, or else you won't be able to charge early. Failing to do so allows the robot to replenish their HP
When the robot is at the right hand side of the screen, you can move around a bit w/o affecting fuel drop rate. Be sure to position to somewhere close to the bottom left panel (1872 X or so) during this brief downtime
Joined: 4/2/2017
Posts: 13
Location: TASVideos.org, of course...
I suppose this could warrant a post.
Basically, I discovered(?) that you can suspend dash "storage"/wall clip state by sliding (I didn't exactly discover it, since it's a known trick in WL3, but I also sincerely doubt that I was the first to find it in this game either). This means that it is possible to clip out of bounds in the far right of the second room of the Really Final Chapter. Due to how the level is laid out in ROM, this allows us to get inside the tile data for the 5th room and enter a door to the 6th, skipping a couple rooms along the way and eliminating the need to deal with the quite slow 4th room, saving 3 in-game seconds from mugg's TAS.
User movie #637807299845550294Link to video
Another thing to note is that slide-buffering a clip makes finding wall clip positions significantly easier than fishing for a good lineup with the dashjump method (although maybe "easier" isn't what we want here since this method is not as direct or fast). It also allows clipping into spaces where there is not room to dashjump (an example that comes to mind is the tiny Wario room in 5-2 Storm the Castle, and I think possibly the top of the "bee bounce" room in 3-4).
I also found a way to get a wall clip with only 1 tile of walking space, similar to Wario Land 3's turnaround wall clips used in N4 in the Any% route. I don't know if there is any reason to use a trick like this, but I still made a quick movie just in case:
User movie #637807399158871261
And here is one last wall clip style that I don't think I've seen in this game yet — water clips (technically, they're water-buffered clips, since the actual clipping happens in the air still, but I'm just calling them what the WL3 community calls them):
User movie #637807409719924707
I'd be curious to see how any of these could be used in a full level TAS, although the last two that I shared may be too specific of use cases. Who knows?
Those are all amazing! In the GB 100% OoB run I'm making, almost every stage is basically
1st Room -> Bonus -> OoB exit
A better way to easily clip out would definitely help.
Additionally, some ideas for GBC in bounds:
1. "Kick em Out!": Instead of dropping down after the minigame, use the 1 tile clip method to get up?
2. "Storm the castle!": Is there any way to prevent backtracking after the minigame?
3. "Go down the cellar": No idea, but right now, the last room seems unbreakable. Not sure if there's a way to prevent getting crushed at the end.
The following applies to gameboy. I found out that when you ground pound in certain areas below the stage, you can crash the game. I checked why, and it was because it jumped to 0xE200
0xC504, and thus 0xE504 is the treasure flags. So there's a small spot to manipulate for a credits warp. Specifically:
C503 Amount of times saved
C504 Treasure flags for stages 0-7
C505 Treasure flags for stages 8-15
C506 Treasure flags for stages 16-23
C507 Treasure flags for stages 24-31
C508 Treasure flags for stages 32-39
C509 Treasure flags for stages 40-47
C50A Treasure flags for stages 48-49 (only bits 0,1 possible)
C50B Coins bank (Displays decimal value as a hex value. eg. 40 coins in decimal becomes 0x40)
C50C Coins bank
C50D Coins bank
C50E Coins overworld (Displays decimal value as a hex value. eg. 40 coins in decimal becomes 0x40)
C50F Coins overworld
C510 Stage ID (Displays decimal value as a hex value. eg. Stage 10 in decimal becomes 0x10)
C511
C512 Stage select flag (0 or 1)
C513 Puzzle flags for stages 0-7
C514 Puzzle flags for stages 8-15
C515 Puzzle flags for stages 16-23
C516 Puzzle flags for stages 24-31
C517 Puzzle flags for stages 32-39
C518 Puzzle flags for stages 40-47
C519 Puzzle flags for stages 48-49 (only bits 0,1 possible)
I couldn't figure out what to do to trigger the credits and avoid a crash however. I did find the following:
0xC004 - cutscene id
0 - none (skips cutscene)
1 - stage 0 (1-1)
2 - stage 5 (2-1)
3 - stage 10 (3-1)
4 - stage 15 (4-1)
5 - stage 20 (5-1)
6 - stage 25 (secret 2-1, you fell asleep)
7 - stage 30 (secret 2-1, you didnt fight snake)
8 - stage 35 (secret 3-1, you sunk the ship)
9 - stage 40 (mansion)
10 - stage 45 (factory)
11 - stage 50 (true final)
12 - crash
0xD6F3 - ending flag. If this is set to 1, and the ending id is a valid value, the ending is triggered at stage end.
0xD70A - ending id
0 - nothing
1 - normal 5-5
2 - secret 2-5 (you fell asleep)
3 - secret 3-5 (underwater)
4 - secret 5-5 (mansion)
5 - secret 5-5 (factory)
6 - true final
7 - reset game
I know it's impractical time wise to set up, but it's a different route that uses ACE, so I'm still interested in it.
Edit: 0xC000 to 0xFFFF area
https://docs.google.com/spreadsheets/d/1x0ahgWoO948yNwCFYOYbA7bYH6OOarJgoSSVkF_hyB0/edit?usp=sharing
most of it is undocumented however.
Edit 2:
ok
C503
Number of times saved
0x3C
inc a
set a from 0 to 1; assumes a was 0
C504
Treasure flags for stages 0-7
0xEA
ld [$D70A], a
loads ending 1 to ending id
C505
Treasure flags for stages 8-15
0x0A
C506
Treasure flags for stages 16-23
0xD7
C507
Treasure flags for stages 24-31
0x3E
ld a, $0B
loads 0x0B to register A
C508
Treasure flags for stages 32-39
0x0B
C509
Treasure flags for stages 40-47
0x00
nop
C50A
Treasure flags for stages 48-49 (only bits 0,1 possible)
0x00
nop
C50B
Coins bank
0x00
nop
C50C
Coins bank
0x18
jr $05
jump to C513 to avoid stage select opcode 0x01
C50D
Coins bank
0x05
nop
C50E
Coins overworld
0x00
nop
Skipped
C50F
Coins overworld
0x00
nop
Skipped
C510
Stage ID
?
Varies
Skipped
C511
0x00
nop
Skipped
C512
Stage select flag
0x01
ld bc, _ _ _ _
Skipped
C513
Puzzle flags for stages 0-7
0xEA
ld [$D6D8], a
Changes game state to 11
C514
Puzzle flags for stages 8-15
0xD8
C515
Puzzle flags for stages 16-23
0xD6
C516
Puzzle flags for stages 24-31
?
?
Remaining bytes for avoiding crash
C517
Puzzle flags for stages 32-39
?
?
C518
Puzzle flags for stages 40-47
?
?
C519
Puzzle flags for stages 48-49 (only bits 0,1 possible)