Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
So a few years ago, I picked up drawing as a hobby again after not having regularly done it for a long time, using a basic Wacom tablet I've acquired in the meantime. I'm mostly creating lineart drawings of characters with designs I find appealing, featuring more than just ponies this time around. Here's a small sampling of what I've drawn over time:
Click for links to the full-sized versions.
I find it quite relaxing and rewarding, even if some drawings turn out better than others. I also find these pages work well as a pseudo-diary for me, recording some of what comics, cartoons or games I happen to be into at that particular time. That said, I still have a long way to go as far as actually improving as an artist is concerned.
Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
I've got something that may be interesting. By triggering memory corruption from going out of bounds, it is possible corrupt some of the memory values which the game uses to index into various jump tables. This normally causes the game to freeze, but it may be possible to redirect the game to jump into RAM, where it might be used to read code from the controller input variables located from $26 to $29.
Link to videoInput File
In this case, I use it to write the following code into memory:
ASL $18
DEC $18
This sets the gamestate variable from 4 to 7, which triggers a debug stage select menu, which allows me to warp straight to Dracula, completing the game in 01:12.83.
There is one major caveat though:
The way this works is that the player state variable at $0565 is corrupted to 1, when it should normally be a multiple of two, which causes the game to swap the low and high byte of two adjacent pointers. This causes it to jump to $388A, which then causes the game to execute code from open bus. It is only by luck that it eventually somehow ends up at $0020 in RAM, which is close enough to where I can manipulate it. This means that the method shown here does not work on console. I have already had Alyosha gracefully test the warp for me on console, which wasn't successful This means another way needs to be found that avoids going through open bus.
How to go from here
To find another ACE exploit that doesn't go through open bus, one would need to check what other parts of the code use these two jump handlers: CV3 Disassembly. They are located at $E86D and $E886 in ROM respectively. It would then be necessary to check if any address used as an index here can be corrupted through memory corruption, and to see if it could be corrupted to a value that jumps to a useful location in memory. However, because it is so hard to find specific, targeted memory corruptions, I am leaving it at this and posting it here for posterity. Maybe in the future, a real ACE run can come from this that can be synced on console.
As for triggering a complete credits warp, this may also be possible, but here there is also a caveat. The memory layout of the affected variables is as follows:
$26: P1 Buttons Pressed
$27: P2 Buttons Pressed
$28: P1 Buttons Held
$29: P2 Buttons Held
This means that any bits that are set in $26 and $28 must also be set in $27 and $29 respectively. This severely limits what code I can write. In particular, there is no simple "LDA / STA"-type combo that would work here, as the opcode matrix of the 6502 is simply not laid out right. This means that any way to set the gamestate variable directly to $0C (game ending) would depend on the contents of the registers at the moment this code is executed, which didn't work out when I tried. Another option might be jumping to some location in the ROM that sets the gamestate variable, but there was again no apparent option when I tried.
Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
Once again, it goes to show that you cannot take anything in a game for granted. These improvements are so unexpected, and yet so cool.
Outstanding work. Spectacular stuff. Yes vote for sure.
Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
I've been busy trying to write a number of Lua scripts for this game with the aim of helping to explore memory corruption. The ultimate aim of both scripts is to help with exploration in the glitched worlds, and for possibly finding new effects or a faster wrong warp. I'm not sure how useful they'll end up being, but oh well. They certainly turned out way more complex than I anticipated:
LinkCorruption Visualizer
This script informs you when whenever memory gets corrupted when being out-of-bounds. It shows which values get corrupted in the form of a RAM heatmap. It also shows some of the game's internal state that is relevant for determining which values actually get loaded.
It also includes a map viewer to help with navigating the glitched worlds.
Video DemonstrationMap Viewer
This is a stand-alone version of the map viewer. It's supposed to help with navigating the glitched worlds, as it turns out that even if you get stranded somewhere, there's often stairs that take you further. It also shows the raw contents of the tile buffer at $6E0, which is important for scroll glitching.
Video DemonstrationEdit:
While I'm at it, I've also started writing a Stair Dismount Guide.
Been meaning to do that for a while now.
Edit 2:
I also turned the Fast Charswitch mod from last page into a Lua script that pokes the necessary values in game, which allows me to distribute it to others, which I couldn't do with the modified ROM. You can find it here.
Video Demonstration
Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
For what it's worth, I find it amusing to beat the game while doing as badly as possible, but I agree there was more appeal to actually seeing the minigames themselves, since I didn't know Tengoku before.
Ultimately, there's not much to say about this submission. It's a purely mechanical demonstration of its goal. The only question about it is whether it's publishable by the current site rules. I haven't kept up with that, so idk.
From what I've seen, there are more interesting ways to TAS Rhythm Heaven.
Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
Oh dude, oh dude, oh dude, totally did not expect this submission. Watching as soon as I can.
Edit: Oh yes, that was marvellous. Another great TAS once again. Gladly voting yes for this.
Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
It's rare that I actually download a movie to watch in emulator, but this one sure made me.
As I mentioned in the discussion thread, the previous Mega Man 7 TASes are some of my favorite TASes on the site, and also some of the TASes that made the biggest impression on me when I was joining the site, so I'm incredibly glad to see this TAS improved. Absolute yes vote, and thank you for making this run!
Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
I'm most reminded of [3685] NES Street Fighter 2010: The Final Fight "warp glitch" by MESHUGGAH & Challenger in 06:50.22. The glitch is cool to see, but once you know it, the novelty wears off fast once you realize this is how every stage is gonna be beaten. The victory fanfare also sounds a lot less pleasant than on NES. At least, unlike when the Street Fighter 2010 movie was submitted, this cannot obsolete the NES version.
Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
Re: Super Castlevania 4: Simon actually moves at 1.25 pixels per frame, so every 4 frames, he will move for 2 pixels instead of 1, which also causes the camera to move at 2 pixels on that frame. I can't see anything unusual in those screenshots.
Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
Well, I wasn't quite done yet...
Link to videoUser movie #638543431070982544
Turns out, you can use the breakable blocks glitch to create a crevice that is small enough for Simon to zip in, with the help of also scrolling some of the tiles offscreen. The damage boost you see to activate the zip is frame-precise.
It's useless here, but maybe there's some more potential in other places. Of course, the specifics will vary a lot depening on the surrounding geometry. Possible further things to look into would be doing the zip without a damage boost, doing the zip without doing any tile unloading, or doing the zip in such a way that you can get Simon below his starting position, so he zips along the floor in the ground, rather than through the elevated tiles. There's definitely more, I'm sure of it.
In doing so, I also managed to unravel a little more about how the breakable block glitch works in general. Get ready for an overly complex writeup:
There's actually 4 separate objects involved, a "spawner" object that manages the state of the entire wall, and which turns into the item when the wall is destroyed, and three separate block objects, one for each tile:
What now happens is that when the camera is more than 224 pixels away, the game begins unloading the objects. The game tries to unload one object on each frame. If an object cannot be unloaded because it is still in range, the game moves on to the next object on the next frame. Using this, it is possible to exit the blocks' loading range on the exact frame the game tries unload a specific block. Using this, it is possible to partially unload pieces of the wall.
If the spawner object gets unloaded, not much of interest happens. The spawner gets reloaded once you enter its spawn range a second time and then creates a duplicate set of blocks over the still existing blocks. This creates the effect that the blocks still produce hit sparks even after they are already destroyed: the second block doesn't realize its corresponding tile was already destroyed and remains active.
Where things get interesting is when the spawner remains intact, but some of its blocks get unloaded. When the lowest block is missing, tile corruption can happen. What I still haven't figured out is why exactly the specific types of corruptions you see happen. There's a few different patterns, and which pattern you get is based on what other objects (excluding candles and some other "static" objects) are currently loaded when the block gets destroyed. This part still comes down to essentially trial and error, but at least the tile corruption itself is easier to set up now.
It's much easier to see what's going on with an object viewer. Object memory starts at 0x440, and each object is 64 bytes in memory. With this, it's easily possible to trigger tile corruption on demand, when previously it was random and incredibly finnicky and inconsistent to perform.
This is false. So far as I can tell, the glitch works exactly the same on the U and E versions of the game.
By making the camera scroll upwards before jumping down, it is possible to get Simon very close to the lower edge of the screen. In theory, if Simon is low enough, this can be used to clip through any floor, although usually Simon will then just fall to his death.
The edges of these floors are actually sloped tiles that are less than 16 pixels tall. This seems to be the secret sauce that allows Simon to clip in.
The specifics are very precise, and it is hard to apply this trick to other areas, in part, because there's only few instances of free 4-way scrolling in the game, but also because it very much depends on the specific geometry of the area, Simon's position, and how exactly the camera behaves.
In this case, we got a new zip, although it's cut short by the spikes ahead. Some more understanding of how OOB movement works might allow Simon to go past the spikes.
I also suspect a damage boost may be used to clip Simon into any flat floor too, not just sloped floors as in this example, since they interrupt his fall, but haven't managed to get it to work yet.
A bit more poking reveals that you need at least -9 Y speed to go through, while Simon usually only gets -8 from rings. I suspect the ceiling is only 8 pixels thick at the staircase, and the ring's position allows Simon to partially clip into the ceiling, allowing him to make it through with just -8. Still no explanation why it's so ungodly precise with regards to subpixels though.
Update: A full zip is possible by using the aforementioned 'clip through the ground + damage boost' method using the lowest bone pillar in the stage.
Welp. See y'all in a few years again.
Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
Recently, I've been playing a bunch of custom Doom wads, and one of the things that stuck out most to me was the breadth and quality of custom soundtracks talented composers would make specifically for those wads. So here is just a small sampling of many of the fantastic MIDIs that dedicated composers made over the years. WAD or Map titles (where applicable) are put after each entry.
Mark Klem - Hidden Anger (Memento Mori)
Jeremy Doyle - Quarry (Icarus: Alien Vanguard)
James Paddock - Sanctified (Plutonia 2)
Petter Mårtensen - Temple of Judgment (Hell Revealed II)
B.P.R.D - The Mucus Flow (The Mucus Flow)
There's also the MIDI Pack for the Master Levels for Doom 2 by Peter Lawrence, which I cannot link a single track of, because so many of them are so good.
i could link more.
Editor, Experienced Forum User, Published Author, Skilled player
(1439)
Joined: 3/31/2010
Posts: 2108
I've dabbled in NESdev before and been interested in the limits of raw PCM on a NES, and all I can say is, I am completely stunned. This is so completely ridiculous I cannot even comprehend it. Interleaving APU and PPU writes like this is not something I would've thought would be possible, but the result looks and sounds stunning.
I am completely in awe. Hats off to you.
Thanks also for the really long and detailed write up explaining every step of the way. Breaking down all of the programming steps really helps to understand what is going on.