My Fitzgerald’s Story

I’m going to share a brief history of my experience with Fitzgerald’s (the live music club in Houston). Partly as an exercise in capturing some memories, but also to show how seemingly minor things can have effects over a lifetime.

It starts Friday, Feb 16, 1990. A high school friend of ours, Chris King, was playing bass for the band Panjandrum. That night they were playing with the Dallas/Denton band Ten Hands at Fitz. This was the first ever live, local band club I had ever been to. At Zelda’s that night was the first time the Austin rap/rock band Retarted Elf played in Houston (at least at Fitz)… and that was a crazy show as well. But upstairs, I was transfixed. Ten Hands, to this day, is one of my favorite bands. And BOTH bands demonstrated how you can have top-notch musical ability, catchy songs, and just have FUN.

This might be apocryphal, but I seem to remember picking up a Fitzherald paper that night, and seeing it mention “Breakin’ Out” nights at Zelda’s. Then talking about starting a band with my friend Dave. We were part of our high school jazz band (which was how we knew Chris King), and recruited others in the band to join us. At that point, we didn’t have any songs, but came up with the name “Ancient Phyz-ics”. I don’t recall the specifics about how that name came about, but I think there was discussion about having weird spelling and punctuation to make it stand out. At that point, one of us called Fitz to see about getting in on a Breakin’ Out night… and found out we needed to pay $50, and would get $1 back for each person we brought in who used a ticket they gave us, up to $50. Dave and I went up to the Fitz office (at that time it was a separate building at the back), paid the $50, got scheduled for Monday April 9, and got a stack of labels and tickets. It’s quite possible we still didn’t have any songs at this point, or maybe we had a couple of ideas but nothing finalized.

Luckily, April 9 was during spring break, so we were able to get a bunch of friends out to the show, and made back the $50. We also got scheduled for another Breakin’ Out night the next month, but WITHOUT having to pay the $50 upfront, and we could still get $1 per ticket up to $50. We played 4 shows in total, all at Zelda’s, and I know we added a bass player at some point, but he wasn’t from our school and I don’t recall how all that happened.

Ray at Zelda's

Back to Ten Hands

I probably went to every Fitz show they played up until I went to college. Plus, at the time, I was considering going to college as a music major. After reading about the members of Ten Hands having come out of the University of North Texas music school, I decided THAT was where I wanted to go. And when I actually spent my year at UNT, I saw Ten Hands many times in Denton and Dallas. I ended up hating UNT for myriad reasons, and came back to Houston to go to UofH.

After a couple more years as a music major, I realized that I enjoyed PLAYING music too much, and having to STUDY it zapped all the joy. Then I discovered Houston Community College’s Audio Recording Technology program, and enrolled for the Spring of 1995. I really enjoyed that program. At some point, my friend Clare had started working at Fitz and mentioned they were looking for someone to do sound at Zelda’s during week days. We met up in Austin at SXSW, coincidentally videoed by the Fitz soundman at the time, Keith, and on YouTube. That night, Clare introduced me to Chris Chaney, who was managing Fitz, and she told me to come in and start training in a couple of weeks.

My first few weeks were training with the guy who was doing sound at Zelda’s (I forget his name). The idea was that I would run weekdays at Zelda’s and he would run weekends, and fill in for Keith at Fitz on occasion. I also trained with Keith to act as a second backup.

Another tangent about how small things can have lasting effects: One evening while helping Keith before doors opened, he started playing a CD over the PA. I was instantly curious about who it was… and Keith said it was Nick Heyward and the CD, From Monday to Sunday. I ended up buying that CD, and have been a dedicated Heyward/Haircut 100 fan since. Heyward, and that particular album, have probably been in my Spotify Top 10 since Spotify started showing that.

The Zelda’s sound guy ended up going to work full-time sound at Emo’s (Houston) in the fall of ’95 and I took over doing weekends, as well as occasional weekdays at Fitz and filling in for Keith on weekends when needed. I’ve always been super introverted, so I doubt I made much of an impression on anyone, but I probably ran at least one show of the more popular bands during the few years I was there. One I particularly remember was getting scheduled for a 30 Foot Fall show, and already being a fan, I was scared of screwing things up and those random feedback frequencies that sometimes happened, and everyone getting pissed off at me. But it ended up being one of the most chill shows I did, and everyone was super nice. I think Bickley may have been on the bill? But even if not, I remember the lead singer of Bickley being super cool as well.

Let me share some thoughts on the various bands I remember. Understand that I get how the shows can be stressful and having things sound good for the audience is one of the most important things, and people handle that differently:

  • Stroke 9: They ended up having a modest hit a few years later, but this weekday night, there were literally 5 non-staff people upstairs. But they were already super polished, and I enjoyed them. They even offered to end early so I could go home, and I told them I was there until close anyway, so happy for them to finish their set. Very cool guys, and even though Fitz always sounded better when more bodies were there, I think I got them sounding decent.
  • Pushmonkey: Austin band. The singer was a jerk to me while setting up, then constantly complained about the monitors (I did my best). I didn’t enjoy that night.
  • The Xenos: Prog, Zappa-esque band that should have been WAY more popular.
  • Demise of Folly: Another small band that I personally enjoyed, and nice guys.
  • King Friday: Austin band that I did sound for twice during weekday shows. The first time I was blown away, and they gave me a free CD (I always enjoyed free CDs). Super tight, with a super modern sound (in the mid 90s), and nice people. It was another sparsely populated show, but I think there were a couple of opening bands that stuck around, so it wasn’t totally empty. I was excited the second time I was on the schedule when they played, and think I got some of the cleanest sound with those guys. I thought they should’ve been more popular.
  • Ska nights: I did a handful of these. It seemed for a couple years, every suburban high school marching band kid was in a ska band. These usually started around 6pm and there would be 6 or 7 bands (or more) playing, trying to wrap up before the midnight under-18 curfew. Most of the kids were fine, but the parents in the balcony, telling me how THEIR kid needed to be turned up… well. Then, those opening bands usually had 30 minutes, and most of the time I would give a “5 minutes / one more song” prompt and everything was fine… other times they were a bit more difficult. And I remember one band, where the drummer had his own mics, for every drum, that he wanted to use. I had to tell him there was literally no way to use them all and still be able to mic a horn line and multiple vocals and other instruments. I remember going home after these nights, trying to fall asleep, and hearing that “ska rhythm” in my head all night.

Let me do another tangent about local band CDs/recordings:

At one point in time, I had SO many CDs and cassettes from local bands. Some I listened to quite a bit. Sadly, over the years, they either degraded beyond repair, got lost, and many got destroyed after tropical storm Allison flooded my parents’ house. Today, trying to find them on the internet is basically impossible, and that saddens me. One particular CD was “Swill” from a band named “Wishbone Bush”, a funk/rap/rock band. There is basically zero reference that it even existed on the internet… nothing on Spotify/BandCamp/etc. I listened to this CD quite a bit, and now it’s basically vanished from existence. Then going back to Panjandrum, I had their tape/EP “Chuck” and listened to that so much… and also, there’s nothing about it online. With that in mind, I started https://houstonmusicarchive.com/ , with the goal of finding local Houston bands’ music and collecting it into a single place, admittedly focusing on 90s bands in the broader “rock” genre. I’ve been sourcing the material from various places: if the band has put their music online, I make sure to link to it… I’ve found random YouTube “videos” that are rips of CDs, and I’ll download the audio and save it… there are random websites that posted mp3s that I downloaded… and some are rips of music I still have, or happened to rip before. My ultimate idea is to have all the music downloaded and stored… somewhere (offline AND online)… so even if Bandcamp/Spotify shuts down, there will be an archive of it. Kind of like Rice’s Houston Folk Music archive but for rock music. So if you were in a band in the 80s/90s/00s that released an album, and would like it archived, let me know. Also, do you have a copy of Wishbone Bush’s Swill, or Panjandrum’s Chuck?

Going back to Fitzgerald’s:

One of the nights, I did sound for Taste of Garlic, and I guess they liked what I did, and they asked me to be their soundguy for other, non-Fitz shows. This would’ve been late 1995. I remember I even got them to be my Audio Recording class project for that Fall semester, and they came out and I recorded a few songs… once again, I fear those recordings have vanished. Also, nothing from their first full CD, other than a couple of tracks on their ReverbNation account. But that was a fun time getting to hang with those guys, watching them rehearse at Francisco Studio, and even doing sound at this huge rock club when they opened for Dread Zeppelin.

I think it was around late 95 that Jeremy started doing more sound shifts. When the other guy went to Emo’s, he took over weekdays at Zelda’s and we would swap between weekend shows and filling in for Keith upstairs. He also seemed to do just about everything at Fitz at some point, from the door to sound to bartending. I will say I didn’t really befriend many people during my time at Fitz – my introversion, among a bunch of extroverts, didn’t translate well. Jeremy was one of the few that I would’ve considered a “friend”. He even got me a few sound gigs at Emo’s, where he also worked. Also, there was a guy named Justin who ran the door and was a general helper, and he played in this band “Juxta”… he was super friendly, and I liked talking to him. I even recorded his band at HCC, and again, sadly, have lost those recordings.

Then there was Keith.

I found him very intimidating. He was cool and confident and wore a long trench coat and hat, and was not afraid to tell bands to get the hell off the stage. But the intimidation was all on me… he was always patient and pleasant to train with. This leads to another branch in my story: I was always interested in technology, starting with learning how to code BASIC on a Commodore Vic-20 in the 80s… and buying a 14.4 modem to connect to the internet in the early 90s. I don’t remember why, but I was over at Keith’s house and he had just started this web server company named Trinicom. At this point, the “web” was only a few years old, and I was amazed by the whole idea… and he explained how it all worked. Soon after that, I taught myself HTML and very basic web server tech. At that point, I still had dreams of either being a musician or recording engineer, but it laid a foundation that resulted in my last 25 years working in software engineering.

There are a few key Fitzgerald’s memories that have stuck with me:

  • Charlie Sexton – I remember getting called to help with load-in for the show. He had his own PA and lights, and tons of gear… and a bunch of us were there early to haul this heavy stuff upstairs. After all that, I think there were maybe 100 people at the show, and he didn’t even do the one song that made him semi-famous.
  • The Tragically Hip played one night, and I was scheduled to be general help. I had never heard of the band, and I thought I was fairly hip with cool, underground music. And the place was PACKED. Lines out to the parking lot. Apparently there was a contingent of Canadian ex-pats living in Houston, and ALL of them showed up.
  • Fugazi – This was booked by Fitz, but they actually played at this hall in south Houston. A bunch of us were conscripted to be “security” for the show. I remember Jeremy handed me a Maglight and I just roamed the back of the hall and out to the parking lot. There was also something about it being Ian MacKaye’s birthday and having a hard time finding a vegan birthday cake.

I don’t remember all the dates, but at some point Chris Chaney left Fitzgerald’s and Robbie (a singer in one of the Houston bands) took over booking. Maybe there was someone else in between? Anyway, I had the feeling that Robbie didn’t like me for some reason. I don’t recall any specific incidents, but I would see him be friendly with other people and was NOT that way with me. I admit I’ve never had the most astute “emotional radar”, so it’s likely I misread that. But anyway, this would’ve been late 1997 and I noticed my schedule became VERY infrequent. In fact, I had started running the light board (a lesser-paying shift) more and more, and even THAT became infrequent. There would be two weeks of no shifts, then three, and by the end of 97, I just stopped getting scheduled for anything.

At that point, I had a part-time position at a radio station. Part of the HCC program was interning at a studio, but when I applied at various studios they had no space… so my advisor said I should try a radio station. I ended up being production intern at The Buzz, and then got a paid gig at KKBQ, eventually moving to full-time there. Later, I was working at Clear Channel and saw an internal job opening for an “Online Training Developer” and was able to get that job, which was the first programming gig I ever had… while I’ve had many jobs since, I’m still doing programming to this day.

It’s all connected.

My final Fitzgerald’s experience was in 2000, when the band I was in played Zelda’s (it had been converted to a bigger stage, and better sound, and called Fitz Downstairs at the time). My (eventual) wife took some pictures. And I think that was the last time I had been there. After that, I got married and we lived far south and didn’t do a whole lot in town. And I think the bands we were into at the time were all at Rudyard’s. We moved to Austin, and I remember seeing BC from ToG/Simpleton at Kerbey Lane Cafe… and he actually recognized me first. I was older and had gained weight, so at least I was somewhat still recognizable!

Currently, outside the Houston Music Archive, just for fun I started creating a Fitzgerald’s show archive: https://houstonmusicarchive.com/fitzgeralds/ … Most of the show info is from Houston Post and Chronicle newspaper listings. Some is from various concert flyers that have been posted. Rice has some Public News archives from 1982 and 83 that I was able to parse. Feel free to contact me if there’s anything wrong or missing. It’s still a work in progress, and I do regularly look up newspaper archives and flyers.

CREATING a GameBoy game with PHP

Previously on, I’ve been decompiling the DuckTale GameBoy ROM using only PHP. That got me curious if one could MAKE a GameBoy ROM with PHP.

Assembly

My first stop was to better understand how the games were originally created, which led me to the RGBDS site with tons of info about GB game creation. It was actually one of the sites I used to find out what headers the Nintendo ROMS used, and how to access them. But for actually making games, it has everything. My main focus was looking at the Assembly code, and seeing how I could re-construct that from PHP.

Helpfully, there are a lot of boilerplate examples out there, so I pulled in some and created a very basic “main.asm” file. It handles all the setup, game loop, and arrow key presses. Then I did another very basic “game.asm” file.

You have to manually set values to specific memory addresses, like for the player’s x and y locations:

DEF player_x EQU $C000
DEF player_y EQU $C001

On the GameBoy, those are the start of the “Work RAM” locations. There are ~8k of those, if you wanted to store 8,000 integers between 0 and 254. It gets more complicated when you want to store larger numbers or other objects. I’m keeping it simple for now.

Then we set the initial state of the game…

    ld a, 76           
    ld [player_x], a
    ld a, 68            
    ld [player_y], a
    ld b, 76
    ld c, 68

This gets interesting, because “a” is the specific memory register any calculations are done. So here, we put (load) the number 76 into “a”… then load the value of “a” into the player_x memory location ($C000). Then do the same thing with the Y location, and then finally put them into the “b” and “c” registers. Honestly, I’m not exactly sure what the “b” and “c” are for at this point… but they’re used in the main.asm file. Looking at GameBoy code, it’s so much “load {value} into ‘a’, then load ‘a’ into {memory}”

Next is the game loop.

GameLoop:
    call WaitVblank
    call UpdateInputs

    ; -- Right --
    call KeyRight
    jr z, .noRight
    ld a, [player_x]
    cp 152              
    jr nc, .noRight
    inc a
    ld [player_x], a

WaitVblank keeps the system and screen synced up, and UpdateInputs is checking if any buttons are pressed. For this first pass, we’re only checking for up/down/left/right, but this also handles start/select/a/b/bumpers. For checking if the “right” arrow is pressed, it calls KeyRight and then checks if the z bit is set. If it IS, that means the button was NOT pressed, so you jump the .noRight symbol.

The next couple of lines are boundary checks, which I didn’t include in the PHP compiler. But from what I understand cp 152 is comparing ‘a’ with 152 (the right side of the screen). If ‘a’ is less than 152, it sets a “carry” flag, which means it’s fine to keep moving. The jr nc, .noRight line is “there is NOT a carry flag, so stop moving and go to the .noRight section”. Next increments ‘a’ and then updates the player’s X value with ‘a’. So the whole thing is checking “is right pressed? is left pressed? is up pressed? is down pressed?”, in order, every 1/60th of a second.

Then the one sprite:

SpriteTileData:
    db $18, $18         ; ...XX...  binary for 0001 1000
    db $3C, $3C         ; ..XXXX..  binary for 0011 1100, etc
    db $7E, $7E         ; .XXXXXX.
    db $FF, $FF         ; XXXXXXXX
    db $FF, $FF         ; XXXXXXXX
    db $7E, $7E         ; .XXXXXX.
    db $3C, $3C         ; ..XXXX..
    db $18, $18         ; ...XX...
SpriteTileDataEnd:

I know the sprites are set as 2 bits, a high and low bit. For this, it’s the same value for both to keep it simple. The main.asm files loads all these in the correct place so they display on screen.

At this point, I was able to run the needed commands, and got a .gb file that ran.

The PHP game file

My next step was to see how I wanted the PHP game file to look. I stubbed out a super basic idea. Setup fairly similar to how the assembly file is organized.

wait_vblank();
update_inputs();

Then I have function calls, that I plan on PascalCasing when calling the “main.asm” files. Other than that, not a whole lot going on. To compile it, I decided to just read each line of the file, do some preg_match … and build up an assembly file.

The PHP compiler

So this is currently a bit of a mess (but it works on my machine).

I changed a couple of things, like instead of defining variables with memory locations, I’m just using the locations directly. And I’m not doing boundary checks. And I renamed the “noRight/Left/etc” symbols to be a bit more flexible later on.

And when I ran my game code through it, it worked!

I even made a build script to do the whole process.

I have ideas for next steps. Like splitting up the compiler code to be more object-oriented, and less spaghetti. And hopefully will be easier to add new functionality. Part of the process is getting more indepth on the actual assembly code side of things… which I’m not sure I have much time to do. We’ll see.

Decompiling DuckTales for Game Boy… with PHP

I’ve been pulling apart the DuckTales Game Boy ROM byte by byte using PHP. Just PHP with file_get_contents() and a bunch of bitwise operators. Just out of pure curiosity, and whether it was possible. It’s been… interesting, so I figured I’d log what I’m doing.

It began when I got more into making games, and made a very simple platformer that ended being 50MB in size… but I remember playing DuckTales on GameBoy, and I know those cartridges couldn’t hold that size.

Loading a ROM

A Game Boy ROM is a flat binary file. No compression wrapper, no file system, nothing fancy. It’s just raw bytes . Loading it into PHP is simple:

$this->data = file_get_contents('ducktales.gb');
$this->size = strlen($this->data);  // 65,536 bytes

With DuckTales, it’s a full featured platformer, and all in a 64k file. With file_get_contents the whole game is a string in memory. Every byte accessible by index. Want byte number 500? ord($this->data[500]). PHP strings are byte arrays under the hood, which helps makes all this possible.

The Header

Every Game Boy cartridge has a header at fixed memory addresses. Nintendo standardized this so the boot ROM could validate cartridges. We just read the right offsets:

// Game title lives at bytes 0x134 through 0x143
$title = substr($this->data, 0x134, 16);
$title = rtrim($title, "\x00");  // strip null padding
// Returns: "DUCKTALES"

// Cartridge type at 0x147
$cartType = ord($this->data[0x147]);
// 0x01 = MBC1 (Memory Bank Controller 1)

// ROM size at 0x148
$sizeCode = ord($this->data[0x148]);
$actualSize = pow(2, 15 + $sizeCode);  // 32KB * 2^n

No magic here. The Game Boy hardware expected the title at 0x134. Most of these locations are documented by many other people, in other languages, but I didn’t write down all the url… so just google ’em if you want.

Finding Text in the ROM

Some text in ROMs is just plain ASCII. You can find it by scanning for runs of printable characters:

for ($i = 0; $i < $this->size; $i++) {
    $byte = ord($this->data[$i]);

    if ($byte >= 32 && $byte <= 126) {
        $current .= chr($byte);
    } else {
        if (strlen($current) >= 4) {
            echo "Found text at $i: $current\n";
        }
        $current = '';
    }
}

This catches copyright strings, debug text, anything stored as standard ASCII.

Most Game Boy games don’t use ASCII for their actual ingame text though. They use a custom encoding where each byte maps to a tile in the font. DuckTales maps it like this:

  • 0x01 through 0x1A = A through Z
  • 0x1B through 0x34 = a through z
  • 0x80 through 0x89 = 0 through 9
  • 0xFF = line break

So the letter “A” isn’t 0x41 (ASCII), it’s 0x01. tile #1 in their font tileset is the letter A. Once you figure out the mapping, decoding is just a big if/elseif:

if ($byte >= 0x01 && $byte <= 0x1A) {
    $result .= chr(ord('A') + $byte - 1);
} elseif ($byte >= 0x1B && $byte <= 0x34) {
    $result .= chr(ord('a') + $byte - 0x1B);
} elseif ($byte >= 0x80 && $byte <= 0x89) {
    $result .= chr(ord('0') + $byte - 0x80);
}

it works.

The Graphics

Game Boy tiles are 8×8 pixels with 4 shades of green (well, gray on the actual hardware… the green was just the screen). Each pixel needs 2 bits to store its shade (0-3), packed in a format called 2bpp (2 bits per pixel).

Here’s how one row of 8 pixels is stored in 2 bytes:

Byte 1 (low bits):  01011010
Byte 2 (high bits): 00110110
                     ^^^^^^^^
                     Pixel: 01001310  (combine bit from each byte)

For each pixel, grab one bit from byte 1 and one from byte 2, combine them, and you get a value 0-3. In PHP:

for ($row = 0; $row < 8; $row++) {
    $byte1 = ord($this->data[$address + ($row * 2)]);      // low bits
    $byte2 = ord($this->data[$address + ($row * 2) + 1]);  // high bits

    for ($bit = 7; $bit >= 0; $bit--) {
        $pixel = (($byte1 >> $bit) & 1) | ((($byte2 >> $bit) & 1) << 1);
        // $pixel is now 0, 1, 2, or 3
    }
}

Each tile is 16 bytes (8 rows × 2 bytes per row). So every 16-byte chunk in the graphics region is potentially a tile.

ASCII Art in the Terminal

Before even bothering with images, you can preview tiles right in the terminal:

$shades = [' ', '░', '▒', '█'];
echo $shades[$pixel];

That one line turns pixel values into a quick visual.

Actual PNG Output

Once you know the pixel values, GD handles the rest:

$image = imagecreate(64, 64);

// Classic Game Boy green palette
$colors = [
    imagecolorallocate($image, 155, 188, 15),  // lightest
    imagecolorallocate($image, 139, 172, 15),
    imagecolorallocate($image, 48, 98, 48),
    imagecolorallocate($image, 15, 56, 15),    // darkest
];

imagefilledrectangle($image, $x, $y, $x + $scale - 1, $y + $scale - 1, $colors[$pixel]);

imagepng($image, 'tile.png');

Actual Game Boy sprites rendered as PNGs from raw ROM data. Using PHP’s GD library.

Assembling Multi-Tile Sprites

Individual tiles are only 8×8 pixels. Scrooge McDuck is bigger than that. Characters are usually made up of 4 tiles (2×2 = 16×16 pixels) or 6 tiles (2×3 = 16×24 pixels).

The tricky part is figuring out HOW the tiles are arranged in memory. Left-to-right? Top-to-bottom? Interleaved? Some weird order specific to Capcom? We don’t know, so… trial and error:

$patterns = [
    'sequential'  => [0, 16, 32, 48],
    'interleaved' => [0, 32, 16, 48],
    'column_pairs' => [0, 16, 256, 272],
    'reverse'     => [48, 32, 16, 0],
];

Each array is 4 byte offsets from a base address, placed into a 2×2 grid. Generate a PNG for each pattern, look at the results, and one of them will look like an actual character. It’s not elegant, but it gets the job done. For example, below is one of the extracted spritesheets… and you can sort of seen Scrooge elements in the center:

Here’s a screenshot from the actual game, and while some coloring is different, you can see elements…

Decompressing Hidden Graphics

Not all graphics are stored raw. Capcom used LZSS compression to fit more data into the ROM. It’s a fairly simple scheme with two operations: literal runs (“copy the next N bytes as-is”) and back-references (“copy N bytes from earlier output, starting M bytes back”).

The token format is one byte:

  • Bit 7 clear → literal run (lower 7 bits = count)
  • Bit 7 set → back-reference (lower 7 bits = length, next byte = offset)
  • 0x00 → end of data
while ($pos < $this->size) {
    $token = ord($this->data[$pos++]);

    if ($token === 0x00) break;

    if (($token & 0x80) === 0) {
        // Literal: copy next N bytes directly
        $count = $token & 0x7F;
        for ($i = 0; $i < $count; $i++) {
            $output .= chr(ord($this->data[$pos++]));
        }
    } else {
        // Back-reference: repeat from earlier output
        $length = $token & 0x7F;
        $offset = ord($this->data[$pos++]);
        $srcPos = strlen($output) - (256 - $offset);

        for ($i = 0; $i < $length; $i++) {
            $output .= $output[$srcPos + $i];
        }
    }
}

The interesting part is finding compressed blocks. We scan the entire ROM, try to decompress at every offset, and check if the result looks legit (decompressed size is bigger than compressed, output is a multiple of 16 bytes so it contains complete tiles). It’s bruteforce, but it turns up graphics you’d never find otherwise.

Finding Level Maps

Level layouts are stored as tile maps… grids of numbers where each number says “put tile #X here.” The game’s rendering engine reads these grids and draws the level by looking up each tile.

We scan for regions that look like tile map data using a pretty basic heuristic: if a block of bytes mostly contains values between 0x00 and 0x7F (valid tile indices), it’s probably a tile map.

for ($i = 0; $i < 32; $i++) {
    $byte = ord($this->data[$addr + $i]);
    if ($byte > 0x00 && $byte < 0x80) $score++;
    if ($byte == 0x00) $score += 0.5;
}
if ($score > 20) {
    // Probably a tile map
}

Once you have a map address and know where the tileset is, you can render an entire level preview by looking up each tile index and drawing it:

$tileId = ord($this->data[$mapAddr + ($y * $width + $x)]);
$tileAddr = $tilesetAddr + ($tileId * 16);  // 16 bytes per tile
// Decode and draw that tile at position (x, y) in the output image

Right now this handles all the data in the ROM: graphics, text, maps, compressed blocks. I think the next step is a full CPU disassembler for the Sharp SM83 (the Game Boy’s processor). So turning every byte in the code regions into readable assembly instructions, which I’m not sure if even possible?

Anyway… there’s literally no reason to do this, and I have no idea what I’m trying to accomplish.


How THIS long-time dev uses AI

There’s a lot of talk about “vibe coding”, the idea of just throwing prompts at an AI and hoping it spits out something useful. A fairly new term coined by Andrej Karpathy. But “forgetting that the code even exists” might work for a weekend hack project, but it’s not what seasoned developers are doing as far as I can tell.

Experienced coders aren’t handing over the reins. They’re still designing systems, checking code. And treating AI as a helper. A recent article in The Register noted that many senior devs now rely on AI for more than half their work. I’d sat that isn’t “vibes”. That’s experience. Or as Simon Willison says, it’s “using an LLM as a typing assistant”.

Prompts with a Plan

The real difference is in the way they prompt. A non-developer might prompt, “Build me a CRM for patio furniture business”, and leave everything else up to the AI. A veteran knows enough to write out the full plan: stack, database, models, security, tests, APIs, integrations, whatever. The AI is just filling in the details.

That’s where experience shows. Knowing what to ask for, recognizing when the AI stumbles, and steering it toward code that will actually hold up.

Faster in a Different Way

Studies show senior developers get more value out of AI even though they spend extra time fixing what it produces. That’s because they’re looking at the whole project, not just one function. What used to take weeks of boilerplate work can now be sketched out in hours. Then they can focus on design, security, and scale.

AI handles the repetitive stuff: models, services, tests. The human brain is free to solve the harder questions. Where do we draw system boundaries? How do we keep data safe? Can it handle real traffic?

Always Double-Checking

Of course, AI still makes mistakes. It doesn’t understand projects the way humans do. It might try to fix a bug by piling on extra code instead of solving the root problem. In one instance, Claude Code was trying to fix some failing tests and ended up creating various debug files and “test” code in the service class. I stopped the agent, and realized that the parent class of the test wasn’t setting a mock object correctly. A simple one-line fix, but Claude didn’t find it. Experienced developers are able to understand when the agent goes off the rails, and know where to look.

My Process with Claude Code

The PLANNING.md “Trick”

One of the easiest ways to keep Claude on track is to give your project a “second brain.” Start with a PLANNING.md file in the repo, and have Claude break down the project. This doc becomes the single source of truth for the project – goals, architecture, and next steps.

Here’s how it works:

  • Plan first: Outline the stack, features, database, APIs, and deployment.
  • Break it down: Claude splits the plan into small tasks, like setting up auth or writing migration scripts.
  • Stay focused: For each task, start a fresh session with Claude and only prompt it the relevant slice of the plan.
  • Update as you go: When a task is done, have Claude mark it complete and add notes back into PLANNING.md.

This loop keeps both you and the AI synced, so the project grows in an organized way. And also gives you specific points where you can stop and debug.

Plan Mode as a Sanity Check

Another great move is to force Claude to “think before coding”. You can start in “Plan mode” and ask it to outline what it wants to do before writing any code. Approve the plan, or re-prompt if something seems off, then let it generate.

Catching mistakes in plain English is way cheaper than debugging 200 lines of nonsense later. Juniors might miss issues here, but experienced devs can spot when the Claude’s plan doesn’t fit the bigger picture.

Not Vibing, Conducting

So no, senior devs aren’t “vibe coding”. They’re conducting. The AI is the orchestra. It’s powerful and fast, but ultimately… directionless. The developer is the conductor, setting the score and keeping the rhythm.

That’s where coding is heading. Human vision plus machine speed. Less typing every line, more designing systems and guiding AI to build them right.

3 Years Between Posts – Game Development

It’s been a while. My latest non-work obsession is trying out various game ideas. I’ve always had an interest, and a few ideas, but getting proficient with a game engine like Unity or Unreal seemed a daunting task.

I did start a few years ago with Videordle, a Wordle ripoff where you try and guess the “video of the day” with a super zoomed-in clip. Each wrong guess zooms the clip out a bit. One of the goals was to have it all self-contained, and only vanilla javascript. So you could technically download it and run it all locally.

Last year, I had the idea for an Android “word game”, and I created Word Stars using React Native. I utilized my Laravel skills to create an API auth and backend for the game. That went very well, so I kept going with React Native and ported Videordle to an Android app/game, also using an API to deliver the data. I haven’t touched them since release… but also, no one is playing them. Also, also, I’m horrible at marketing, so I doubt anyone knows they exist.

I also got interested in bigger games, so I started learning more about Godot, a free game engine I’ve toyed with, on and off, for a few years. That led to My First Game. After that, I started working on another platformer type game in Godot… one that I would eventually like to release on Steam at some point. That’s going to take longer, because it’s bigger in scope, and I don’t have a lot of dedicated time.

In the meantime, I want to actually “complete” something, so I’ve entered a few itch.io game jams. The first one I did was an RPG Maker game named Anxiety. I bit off more than I could, with an ambitious idea and a game engine I never used before… so it’s only about 1/3 of what I envisioned. But it’s submitted. So that’s a win.

I have a few more of just me playing around with things, and experimenting with quick ideas. The next jam I’m signed up for is Bullet Hell Jam 6, which could be fun. I’ve been playing around with the logic in Godot, so once it starts, I can hit the ground running. The next jam after that is for GDevelop, another engine I only just downloaded last week. I’m tempted to use THAT for the Bullet Hell jam, so I can learn. We’ll see.

The most recent thing I’ve completed, and fairly happy with, is Idle Hands. It’s an “idle clicker” game where the goal is to collect demons and traverse the circles of Hell. Visually, I’m happy with it… up next, I need to add some music and sound effects. This is also a game that’s vanilla javascript. It’s literally just index.html, index.js, and styles.css … plus assets. I added a package.json just for minification, and I think I’m going to release it on mobile using Capacitor.

The future: I remember having a Palm Pilot in the early 2000s, and there was a game called “drug wars” or something, where you bought goods in one place and sold them in another to try and make money… and random events would happen that could either help or hurt your profits. It was fun. I have the idea of doing a similar concept, but for music – like you’re trying to put a band together and you have to change it up as musical tastes change, so you buy and sell things like a “fiddle player” when country music becomes popular or something. I still have to work it out.

Updating a 10 year old Laravel post

In November of 2012, I had a short blog post about using Laravel (at the time v3) with the Redactor javascript code for wysiwyg textareas. It’s not bad, but could use an update.

First, I see “classic” Redactor is deprecated in favor of Redactor X, and they want you to pay for it. Since I don’t plan on actually using, I’m going to assume the docs work as expected. Second, Laravel is now on version 9, which is a long way from version 3. Though interestingly, the syntax is not that wildly different.

Begin by updating initial route, now located in “/routes/web.php”. Instead of the View facade, we can do this:

Route::get('redactor', function() {
    return view('redactor');
});

Easy! We could’ve left it as is, since View::make() still works (!!!) but this is a bit nicer.

Next, we can update the HTML for that view. In the original, it was using a non-Blade view which is a bit silly in 2022. Also, the Form facade was removed from Laravel in version 5, so you either use plain-old HTML form tags, or the HTML package from Laravel Collective, which is what I did.

<!DOCTYPE html>
<html>
   <head>     
         <title>Laravel 9 and Redactor</title>
         <meta charset="utf-8">
         <link rel="stylesheet" href="css/redactorx.min.css" />
   </head>
   <body>
         {!! Form::open() !!}
         {!! Form::label('mytext', 'My Text') }
         <br>
         {!! Form::textarea('mytext', '', ['id' => 'mytext']) !!}
         <br>
         {!! Form::submit('Send it!') !!}
         {!! Form::close() !!}
         <script src="js/redactorx.min.js"></script>
         <script type="text/javascript">
                RedactorX('#mytext', {
                    image: {
                        upload: '/redactorupload/'
                    }
                });
         </script>
   </body>
</html>

No more jQuery and fancy Blade code!

Then we update the route that will accept the upload, and again, it’s still pretty close to the original:

Route::post('redactorupload', function(Request $request) {
    $validation = Validator::make($request->all(), [
        'file' => 'image|max:10000'
    ]);

    if ($validation->fails()) {
        return false;
    }

    $filePath = $request->file('file')->store('public/images');
    if (empty($filePath)) {
        return false;
    }

    return response()->json(['filelink' => Storage::url($path)]);
});

The biggest difference is the Input facade was removed in favor of using the Request object in the closure. I also removed an unneeded else statement.

The final bit of code was simply echoing out the form input if you submitted it. Instead of doing a dd() (which still works), we can update it like so:

Route::post('redactor', function(Request $request) {
    return $request->all();
});

That’s it. Now we have updated some 10 year old code!

Laracon: Saturday. 1st Laravel Conference in (others’) Pictures.

Morning in Washington DC

 

 



 

Aaron Kuzemchak : Simple API Development

Demo

 

 

 



 

Dayle Rees : Laravel: An Unexpected Journey

 

 

 



 

Zack Kitzmiller : Procrastinating Code

 

 

 



 

Jonathan Barronville : Vagrant, Puppet, Laravel & You

 

 

 



 

Eric Barnes : The Care and Feeding of a Robot

 

 

 



 

Shawn McCool : Running a Small Business on Laravel

 

 

 



 

Taylor Otwell : Eloquence Evolving

 

http://instagram.com/p/WF1YHVNzR2

Links to Unemployment signup page for each state

At SXSW, I spent a couple of the days at the sessions dealing with government topics.  One of the things that was brought up quite a bit was that State websites are almost universally horrible.  They’re poorly designed and finding information easily is near impossible.  Utah is one exception to this rule, but really, it’s just about the ONLY exception.

I decided to try and find the Unemployment signup pages for a couple of states, just to see how easy or difficult it was.  It was NOT easy.  I remember a couple of years ago, when I was laid off, getting to the Texas unemployment online signup was full of twists and turns, and pages of descriptions and explanation. I just wanted to go to the signup page.  So I decided to create a simple page with links to the unemployment signup pages for each state… hopefully skipping all the explanations and description pages.

As I was searching for each state, I was surprised at how outdated the sites were. So many required Internet Explorer, and a couple prevented me from even accessing the pages using Chrome.  And Pennsylvania… Netscape Navigator? Really? Well, it IS using classic ASP… so I guess it is to be expected.

I think I may do this for other commonly needed pages, too.  In one of the sessions, someone mentioned how difficult it was to find info about building permits… but since that gets into county and city pages, it may be beyond the scope of this project. I just need to figure out what pages are most commonly needed.

Terry’s Happy Place songs

There are songs that just seem to always make you feel better when you hear them.  I’ve kept my own list in my head, and now I want to collect them into one post.  The list is fluid, but most of these have been set for years.  In no particular order, songs that put a smile on my face:

1) Morningwood – Nth Degree

2) Frankie Valli – December, 1963 (Oh, What a Night)

3) Glass Tiger – Don’t Forget Me When I’m Gone

4) Dolly Parton – Here You Come Again

5) Duran Duran – Hold Back The Rain

6) Duran Duran – The Reflex (yes, 2 Duran Duran songs)

7) The Beatles – Good Morning Good Morning (pretty much any Beatles, though)

8) Public Image Ltd – Disappointed

9) Radiohead – Bones

Fun puzzle – Christmas Conundrum

Saw this puzzle on Chris Shiflett’s blog and was able to figure it out. Don’t read further if you want to try yourself…

 

 

 

 

First, I wrote down the numbers, and immediately noticed the first numbers “1024” and “512” were suspiciously binary… though, that seems somewhat coincidental now. However, I plotted all the numbers into a spreadsheet, then did a conversion to binary.  I began thinking that maybe the 1s and 0s were like the beat of a Christmas song, so I tapped them out, and it didn’t seem to be anything.  Though bits seemed to be like “Jingle Bells” or “God Rest Ye Merry Gentlemen”, they never played out for the entire song. I got a bit sidetracked, thinking this was a designer, that maybe the numbers should be converted to HEX values, and use those colors for something.  Again, it didn’t pan out.  Here’s where I was at that point:

Then, as I looked at the column of binary numbers, I noticed there was a pattern… not in the numbers, but in the shape of the groups of numbers. I converted the column to monospace type and started connecting the 1s. It really didn’t make sense at first… but I saw the last group of numbers made a Greek Sigma “Σ” and an “X”. So I thought “Sigma Chi”, a fraternity.  The numbers above it made a “W” and a Sigma, and I thought maybe the “W” was supposed to be a Psi, but I couldn’t find anything relevant for “Psi Sigma”. At that point, I hadn’t connected all the 1s correctly, so I went back and connected all the 1s, even diagonally. The patterns became a lot clearer… but it still didn’t make sense.  At that point, I had my table turned just a bit to the side, and noticed the Sigma could actually be a sideways “M” and the “W” a sideways “E”… so I had “E M M X”.  With that, I saw I already had the “A” and a “Y”. Once I made one more missed connection of 1s, I had the two “R”s and figured the extra bit in the first group was an “!”.  From there, it was a simple matter of re-ordering the letters to make: MERRY XMAS!

Thanks to Chris Shiflett for the fun diversion. Though, it looks like I missed submitting the correct answer by only a few minutes (congrats Cogocogo) … it was still an enjoyable brain exercise.