Discord Minesweeper is a Perl script I wrote that builds on one of my previous projects, WebService::Discord::Webhook. It generates Minesweeper boards and posts them to a Discord channel. Each square contains a bomb, number, or blank space, made using the Emoji images. Using Discord’s “spoiler” tag (wrapping text in double pipes,
), the squares can be individually uncovered, thus making a playable game without even leaving chat.
I ran this script for a few months, posting one board a night, but users eventually got sick of it and deleted the webhook… well, perhaps there are other games that could be done this way? I think a Blackjack simulation would work: you are dealt some face-up cards, optionally some more (covered) to flip, and once you’re finished you can reveal the dealer’s hand to see who won.
An exchange on Twitter led me into a trap that consumed a week of my time – the Sega Genesis / Mega Drive version of Back to the Future: Part III shipped with a bug that caused completely wrong colors to display. Evidently the programmer(s) were confused about the proper format of color data on the Genesis. While color values should be stored in two bytes as
, this game instead uses the incorrect format
– all values shifted right by one bit. The end result is that the game displays at half brightness, and lower contrast.
I naively assumed this would be a simple fix: in fact, some prior discussion pointed out that color tables are stored plainly in the file, and even provided addresses to fix some of them. Of course, things are never as easy as they seem. Using a hex editor I changed some color palettes, then used the BlastEm emulator (its debugger is okay) to test, and made two discoveries:
the list in the forum post is incomplete, and I needed to do further digging to uncover the rest of the palettes, and
even with the palettes fixed, colors still didn’t display correctly. Any code that sets the palette (e.g. when fading to/from black) still used the old, wrong format. So while the data was correct, it still displayed wrong.
At this point I decided to see how Ghidra would fare on 68000 code. With the help from some scripts from zznop (to parse Genesis ROM headers, and to generate a new checksum after modification), I spent a couple days working at a disassembly of the ROM. Ghidra works well for this, but it has some quirks: it does not properly handle 24-bit addresses, it sometimes needs a kick with the “disassemble” key to force it to parse a block of obvious code, and the “address table” checkbox on Auto-Analysis causes far more pain than benefit – don’t use that!
In the end I produced a disassembly that was quite revealing. The game doesn’t have a lot of code re-use, it was apparently written in isolated stages and then combined together at the end. Functions for palette fades and “cutscene” display are duplicated in each segment. Finding palette setting code wasn’t too difficult once a palette were found, and usually looked something like this (taken from a “Fade To Palette” routine):
A bit hard to see maybe, but the important parts are that it’s processing the values in B, G, R order, by using “(component)
“, and incrementing if less than the desired value. This is the wrong bitmask. Changing to 1111 (i.e.
) allows fading through the full gamut, and everything now displays as intended. I was also able to reference the SEGA logo (at game boot), which DOES have proper colors, to double-check that I had this implemented correctly.
Finding the other places in the code where this happens is pretty trivial. A search for
reveals the rest. With that fixed, I regenerated the checksum and wrote a new ROM, then used LunarIPS to make an IPS patch for distributing the fix.
The last step was to port the changes to the EU version of the game. Fortunately, the data is the same, and a Perl script with find-replace made locating the offsets easy. A new IPS patch, a README file, and we’re ready to ship.
All told, this was actually a fun rabbit hole to get lost in, and I did pick up a lot about Ghidra and 68000 assembly that I had been wanting to learn anyway. If only it didn’t come right in the middle of NaNoGenMo… 🙂
Modest Bricks is a Tetris clone. Originally written in 2005, it uses SDL 1.2 and the SDL_Mixer library for sound effects and music. This was one of the first “serious” games I wrote – though I did a number of QBasic and Visual Basic things before, I had never attempted a game in C, or with this level of polish. I wrote this for a few reasons:
Learn SDL and practice game dev in C, tools used (at the time) by Professionals to make Real Games
Make the source available so I could teach and demonstrate SDL to the University of Arkansas Game Development Club, a group I helped co-found around the same time.
Follow the advice of this GameDev.net tutorial, “How do I make games?” which recommended to start small by creating a polished version of Tetris to get the basics down and have something to show.
Put my music into a game!
Recently I took an interest in revamping some old code, and ended up rewriting much of this. The effort is complete so I’m releasing it. A Windows version is included in the .zip below, as well as the source code in C. Recompiling on *nix should be easy:
cc `sdl-config --libs --config` -lSDL_Mixer -o modest main.c
should be reasonably close, assuming SDL and SDL_Mixer development libraries installed.
Probably the most interesting thing about this game is that after writing, I pushed it to the SDL webpage, which (at the time) had a gallery for people to post their games Made With SDL. From there it caught the attention of a Dreamcast homebrew developer Ian Micheal, who was porting SDL games to the DC. He altered the graphics and added more sounds and cool effects to create “Ghouls ‘N TriX” – a Tetris game for the Dreamcast! It was really cool to know my code was running on a video games console, and I made sure alllll my friends knew about it 🙂
@FPAdventuresBot is a Twitter account that regularly posts screenshots from first-person, point-and-click adventure games. Images are randomly selected from a pool, pre-extracted from original game data files. The bot source code is available on GitHub:
It uses Twitter::API to manage file uploads and posting to Twitter. For some games, I have written custom tools to extract images. Source code for these is in the tools/ subdirectory. There are also some audit scripts in the main folder to find duplicate images or solid-color images. These use Image::PNG::Libpng for working with PNG images.
The account currently posts images from the following games:
Secret of Evermore is a game for the Super Nintendo released in 1995. It continues to be a somewhat controversial title in the otherwise spotless Squaresoft SNES library… but I like it, and my wife plays it as a “comfort game” whenever she is feeling sick.
IPS is an antiquated binary patch file format, used to provide a “diff” of raw bytes that should be applied over an existing file. IPS patches for SNES games are widespread, and often do things like enable cheats, alter graphics, translate text, etc. In some cases, people have found bugs or glitches in the original code, and release an IPS patch to fix it. Often these are found from the work of speedrunners, who spot a glitch and exploit it to break the game in some way. The SNES hackers then identify the code problem behind the bug, and patch the raw binary code to close the hole. There’s a whole black art to crafting binary bugfixes – the space for a fix is severely limited, and if the new code is too big you have to find additional unused code area elsewhere to jump into (or optimize a different routine to make some free space!)
For some games, more than one bugfix patch is available. Managing these with the ubiquitous LunarIPS tool is a pain – you have to generate a bunch of intermediate ROMs, and the patches may conflict / overwrite one another without indication of the problem. There are better IPS patchers around, but I didn’t want to go on a research quest to find one. Besides, IPS is a pretty simple format – why not just write my own patcher?
I wanted a way to take a binary file, apply a complete “patch set” to it, and return the resulting bin. I wanted it to check for conflicts in patches, and give a descriptive message of which exact patches were colliding. And then I didn’t want to just serve up a cooked file, for copyright and maintainability reasons. “XYZ (Bugfixed)” hacks are too frequently outdated, as new patches are released. So I put a simple PHP frontend before it and a folder full of patches server-side.