Just a quick one today, WumpaGem’s list of decomps that aren’t Clauded or anything, hosted on Backloggd. There’s a lot of them, of varying degrees of completeness: some are done, some are in alpha, some are only planned. Interesting, Twilight Princess and Majora’s Mask are playable, but Ocarina of Time is only planned, probably because Ship of Harkinian stole a lot of its energy but turned out to have been made with AI coding. Particularly, Mario 64 has five different recomps.
You wanna know something? I think everyone should learn to program. I don’t mean using some, the word I usually use is cockamamie, “AI,” that will produce brittle, inefficient, unmaintainable code if it doesn’t mess it up, but actually code. I think most of the difficulty with coding is actually in the languages. Woe betide the person trying to learn to program in C++ from scratch these days. C is much better, but still obtuse. Python is better, but also not great for systems or performance work.
The solution? Why, learn to code in assembly of course!
Aaaaand 90% of readers just clicked away. Hah.
But the funny thing is, for many languages, assembly is actually a little easier than them I’d say. When you’re working directly with the hardware, all the weird abstractions you have to learn fall away. It does mean you have to do everything, and I mean everything, yourself. But on the other hand, programming is largely the process of connecting building blocks together, tiny routines comprising larger ones. It takes longer to do it in assembly, and working with a lot of current-day hardware is trickier because you have to jump through more hoops to use it. But its difficulty, I think anyway, is a little overblown.
There’s a wealth of material to peruse, including videos walking you through coding a bunch of different architectures, including 6502, 8086, Z80, 6809, 68000, and even ARM, among others. Even if you have no interest in actually coding for these multifarious* chips, just knowing out they work may be very interesting to you, if not be actually useful someday.
Here, to get some idea of how understandable this will be to you, take a look at his series on assembly coding for the C64 (Youtube playlist, 13 videos, about 170 minutes in all), beginning here:
* That’s 17 points with no bonuses, but 67 if a bingo
Displaced Gamers‘ Behind the Code series, and its companion Talkin’ Code, are probably the best technical examinations of NES games on Youtube. They take games that were the bread and butter of the Famicom/NES in its heyday, products of skilled programmers some of whom had gotten started working on arcade games, and disassemble them, revealing both their the tricks of their trade and the quirks, and sometimes glitches, that made their work unique.
Their most recent examination is the best NES basketball game, Double Dribble. If you’re not familiar with it, it plays and feels an awful lot like it were an early version of NBA Jam, without the teams or players or personality sure, but it does play a mean arcade-style game, which makes sense since it was a port of an arcade game (one that plays, I should say, a hideous vocalized version of the Star Spangled Banner at game start).
Here is the video. (32 minutes) Discussion of the discussion is below it.
Okay, the first surprise is that it that whether the ball goes in or not depends entirely on physics. The game takes the angle of the player to the basket (gotten from the X and Y position of the shot on screen) and sends the ball towards the basket using a lookup table to tell how the ball should move. When the ball arrives, whether it goes in depends on whether the ball is close enough to the center of the basket.
Double Dribble actually just sends the ball towards the basket, and if it’s close enough to the hoop (less than four pixels away), it goes in. Basically, the spot on screen the ball leaves from is what determines whether it scores. Affecting that is that there’s a limited number of discrete angles the ball can be thrown at. Displaced Gamers runs through the math, which is fairly involved, but in short, if you throw at the wrong combination of angle and distance, the ball just won’t go in.
More than that. The big discovery made by Displaced Gamers is that the two hoops aren’t the same! Due to flaw in the math, both hoops’ centers are essentially shifted to the right slightly, and both are also easier to hit when shots are made from the top of the screen, above the basket.
This is only a couple of points from the video. It’s full of the kinds of shortcuts that time-pressed programmers from the age of 8-bit consoles often had to use to make their code work. If you’re allergic to discussions of math (especially trigonometry) you might want to skip this one, but I think it’s worth a look.
A 6502 is not a bad little machine, but it does require efficient coding to get decent real-time results. NESHacker dives into basic Mario-style platformer movement in a 10-minute video
The main portion of the video goes into subpixel movement, a term you may have heard speedrunners use. Many NES platformer heroes don’t jump immediately to movement when a control is pressed, but instead increase acceleration, and that acceleration is measured, in the case of Mario, in 16ths of a pixel.
The process of conversion is pretty slick though. It doesn’t use floating point math but fixed point. Mario’s position isn’t stored just in hardware screen coordinates but in a number with four extra bits off the right side. This larger number is what acceleration math is performed on, and when it comes time to position Mario’s sprite matrix (he’s not properly a sprite because he’s made of several), the code divides by 16 by just rolling the bits to the right, which is a very time performant operation on a 6502.
Other useful tricks are explicated, like storing controller states in a single byte (easily done since NES controllers have precisely eight buttons) and jumping. It’s not a general guide into general platformer implementation, but that’s okay, as there already exists a terrific example of that.
The chief difference between normal, sequential programming and game programming is that most video games have to make a framerate target, and have to split their processes between frames. Lots of little things are usually happening concurrently, and you can’t rely on normal program flow to keep track of things. Instead, each of those little processes has to remember what it’s doing between frames, and that memory takes the form of state machines, reminders of what each routine is in the middle of doing.
Drawing it out with circles like in this video I think makes it seem a bit more complicated than it actually is, but it does require a different way of thinking about your code than you may be used to in other programming disciplines.
Displaced Gamers’ Behind the Code series is back, with an under-the-hood look at another NES Capcom game, following their examinations of Ghosts & Goblins and Strider, links are to our previous pointers to their peerless product.
G&G was implemented by popular early NES anonymous developer and target of player recrimination Micronics, but Commando can’t use them as an excuse, as it was developed in-house at Capcom. They were still learning the ropes of the NES at the time (Strider has no such excuse), and it shows. Displaced Gamers thinks that the game was shipped while the programmers were still working on optimizing it. As they do sometimes, DG implemented their own optimizations, improving the game substantially. You can see the product of their work in a 31-minute video they made about it, here. There is a substantial amount of 6502 assembly code involved, but if you skip around I think you might be able to get the gist of why the glitches happen, and how Displaced Gamers fixes them.
As was often the case with your jankier NES games, the scroll stutters and character chaos were caused by the game failing to make its VBLANK timing targets. Thing is, despite the glitches, NES Commando is arguably the best version of the game! Characters sometimes disappear from the screen and backgrounds turn into garbage, but there’s so many cool secrets and things to find in it that I can forgive Capcom for it.
Note that Displaced Gamers doesn’t release patches with their fixes, preferring to focus on making videos. Their code is presented on-screen though, so it’s possible for others to insert the changed programming on their own. I hope someone does this soon, as a fixed version of NES Commando would be nice to play.
Via Kottke on Mastodon.* Alex Harri wrote an image-to-ASCII renderer that can translate generated 3D models in realtime, and on this page they explain how it works and some of the finer points of that conversion, specifically how not to make the rendered images seem blurry, instead giving edges clean outlines. It’s worth a look even if you’re not a programmer, and just want to see how the process is done. While it does descend into pretty heavy math later on, it starts out pretty approachable, and has interactive demonstrations throughout.
Render captured from the interactive toy on the linked site.
* Bluesky has a lot more users, but Mastodon is used by a good number of highly interested and knowledgeable people, especially people who care about the health of the web, although that’s also because I follow a lot of people like that on Mastodon. Overall I find it a good idea to read both.
The Amiga has hardware sprites, but they’re fairly limited. Most programmers prefer to use its powerful blitter hardware to simulate sprites, drawing them to screen memory much more rapidly than non-blitter hardware can. For more information, I refer you to the video.
That’s it for today, but there be something more substantial tomorrow….
People familiar with MS-DOS should be right at home, although some commands are different. (That’s because MS-DOS changed them; it was originally made as a CP/M clone.) One major difference is the absence, in this version, of disk directories. Instead there were up to 16 numbered “user areas,” each its own individual region on the disk, kept separate from the others. CP/M was an amazingly compact system, a single floppy disk could host a half-dozen compilers and have room to spare.
#2: Speeding Up PETSCII
Commodore BASIC was notoriously slow, but also feature-poor. A version of the same Microsoft BASIC that was co-written by Bill Gates himself, and was later ported to MS-DOS as QuickBasic. This page is a collection of different ways to speed up printing PETSCII characters, covering several optimization techniques, one of them, avoiding IF statements, being non-obvious.
This one, I won’t lie to you, is pretty dry. It’s an hour and a half of the Retro Game Mechanics Explained narrator describing, in precise detail, how Super Mario Bros. 2 builds each of its rooms from a couple hundred-or-so bytes in the game’s ROM. It’s an hour and 39 minutes, actually:
Even I began to drift off a few times through this one. It is exhaustive, and exhausting, but it’s very thorough.
I won’t even try to explicate it all in text, but here’s a few interesting tidbits of information:
Super Mario Bros., the original, built its levels on the fly. As you scrolled forward, the engine read the upcoming data and constructed it up ahead, off screen, in real time, always keeping ahead of the screen’s edge. This is why you can’t scroll backwards, the list is designed to be read going left to right. SMB2 instead includes extra RAM in the cartridge and uses it as a memory buffer to hold the entire current room, up to 10 screens in size. When you enter an area, the game takes a moment to construct the map in that buffer, and copies it to the PPU’s video RAM as you scroll around.
Instead of with stored as-is tilemaps, SMB2’s, as well as basically all of Nintendo’s scrolling games at the time, are constructed, made out of tile objects with different locations and parameters attached to them. This saves a substantial amount of ROM space, and functions as a kind of bespoke data compression.
The rooms are built screen by screen, although it’s possible for some items to extend horizontally or vertically outside of its home screen.
The format makes it seem like vertical rooms were designed first, and horizontal scrolling areas were then added to that functionality.
There are weird special cases everywhere in the building code! Some objects only work on certain levels, or serve different purposes in different worlds.
Birdo’s color, and behavior, depends on its initial spawning X tile position. If it’s 10 she’ll be a pink Birdo; if it’s 11 she’ll be red, and all other values mean a grey Birdo will be generated.
On the enemy list, entity numbers 92-127 are the same as the entities numbered 64 less than them, but with the property that, when they are despawned, the level ends! This property is used for world-ending bosses, but any entity in that range will end the level when it leaves play, even Mushrooms if one such existed.
Crawgrip, the boss to World 5, was added to Super Mario Bros. 2 during its conversion from Doki Doki Panic. The decorative rock background objects in its boss arena are especially hacky, like they were hastily added.
The stars in the sky in the night levels have a bug in their generation that prevents any from appearing on the first screen of their areas. They also aren’t placed specifically, but using a pseudo-random generation algorithm that always uses the same seed, so they’ll always appear in the same places in the sky.
Games From Scratch is a prolific Youtube channel dedicated to helping solo and small team gamedevs with tutorials and tools. They really do post frequently, so if I linked to everything they made it’d overwhelm the blog, but it’s been a while since I referred to them, and they just made a nice omnibus video of free tools. There is a sponsored section in it, but if that kind of thing bothers you I suggest using the browser extension SponsorBlock, which shows time-wasting sections on the Youtube timeline in different colors.