blaubart.com

The decompilation of LEGO Island

Dec 30, 2024
/assets/images/blog/blog-post-9.jpg
Infomaniac minifigure released with some versions of LEGO Island and a Duplo brick handed out at E3 1996

LEGO Island is a Lego-themed action-adventure game developed and published by Mindscape. It was released for Microsoft Windows on September 26, 1997, and playing it is one of my fondest childhood memories. During the past 18 months, I’ve spent over 1500 hours attempting to decompile LEGO Island in order to preserve it for future generations.

Growing up, video games have had a remarkable impact on my life; I imagine they had for many in our generation. My first experience writing software was motivated by wanting to create a video game on a handheld Texas Instruments calculator, followed by writing scripts for a Grand Theft Auto multiplayer mod, ultimately culminating in creating my own multiplayer mod for Fallout 3 (the latter having been only mildly successful).

During this time (2005 - 2010), I’ve had a vision that for the longest time seemed fated to remain little more than a pipe dream: bringing the video game LEGO Island into the web browser to make it accessible to all and everyone.

What is LEGO Island? On first glance, not much more than a crude 3D video game released before the turn of the century. I remember it being one of the first video games I’ve played as a child, together with my brother, huddled together next to a Windows 95 PC of that era. The game’s charm and creativity was so exceptional it remains a vivid memory to this day. If you care to learn more about LEGO Island, look no further than the Internet and you’ll find a small but passionate community of likeminded people enthusiastic about the game.

Why decompile LEGO Island?

Around 2009, I’ve acquired the domain brickster.net with the intention that I would, some day, be able to type that address into my browser bar and hop back into LEGO Island. Since I wanted to share LEGO Island with as many people as possible, the web seemed like a natural fit - most importantly, it would (ideally) not require the user to install any additional software on their system. This is even more relevant today, a time in which the only computer many people own anymore is a smartphone, a time where the browser and its ecosystem have truly become ubiquitous.

/assets/images/blog/blog-post-9-brickster.jpg

Unfortunately, more than a few obstacles made the realization of that project outright impossible. Back in the day, Java applets and Flash were the only technologies one could use to bring any sort of visual entertainment to a website. And, notwithstanding that, LEGO Island was a closed source piece of software and before I had any chance of making the game available online, I needed some version of its source code.

Fast forward to today, and the landscape has changed significantly. WebAssembly, WebGL and more recently WebGPU have become widely available, and most people have a device in their pockets that readily supports these technologies. Video games on the web are a very real thing now, the concerns of the past are no more.

…other than the fact I still needed the source code of LEGO Island to even be able to get started. For a while I briefly contemplated running the game within an emulator, but that would have come with too much overhead. Running Windows in your browser just to play LEGO Island, I figured, is a bridge I wouldn’t want to (attempt to) cross.

The only viable option appeared to be reverse engineering - or decompiling - the entire video game, to eventually have a version of its source code that could be used to port the game to other platforms, such as the web. However, having reverse engineered software before, I knew that such a decompilation would take significant time and effort, something I couldn’t imagine pulling off all by myself.

So MattKC started decompiling LEGO Island…

And then, on June 7, 2023, everything changed when popular YouTuber MattKC announced that he started decompiling LEGO Island. I remember it was a hot summer day, I was casually browsing stuff on my phone when I received an email addressed to his Patreons (of which I was one) with a link to his newest video.

/assets/images/blog/blog-post-9-mattkc.jpg

In an instant I knew that this was it - the one, real, tangible chance and opportunity to realize my long held dream, or at least to take the first steps toward it. I thought to myself that it must be now or never. With the reach and capabilities of someone like MattKC, embarking on a project like decompiling an entire video game suddenly seemed feasible. I got up, turned on my PC and dropped a comment on his video inquiring about possible ways I could support him. I could hardly contain my excitement.

It wasn’t long after that he published his initial decompilation of ISLE.EXE on GitHub, the frontend application of LEGO Island. I vividly recall setting up MSVC 4.20, the compiler originally used to build the game, Ghidra, and other tooling. I submitted my first significant pull request, adding the implementation of MxCriticalSection.

Many years had passed since I had last reverse engineered any kind of software, but getting back into the practice proved easier than I thought, and soon I became a regular contributor to the project.

Attaining byte accuracy, creating reccmp

A major tenet of the decompilation project was the aim to be as accurate as possible, to match the recompiled instructions to the original machine code as much as possible. This was a decision that I personally considered pivotal and quite instrumental.

The alternative would have been to create source code that only aims to be functionally equivalent to the original. That however immediately poses the major concern of how one would possibly be able to know, or prove, that whatever code they wrote is indeed yielding the same results as the original - the short answer is that you wouldn’t have any assurance, other than through potentially a lot of playtesting. In contrast, a byte matching, or instruction matching, decompilation allows you to formally verify correct functionality simply by comparison.

Writing source code that replicates functionality is one thing - writing source code that produces exactly the same assembly as found in the original binaries, quite another. It took a lot of practice, trial and error, to eventually get a solid feeling of how the compiler - in this case MSVC 4.20 - works and makes decisions. The details of this process are too complex and intricate to present here, and are certainly worthy of their own blog post.

/assets/images/blog/blog-post-9-reccmp.jpg

We figured early on that we needed extensive tooling and advanced processes to facilitate effective decompilation. Together, we have devised a set of annotations, to be embedded in the source code, which allowed us to automatically verify the accuracy of re-compiled functions’ assembly, virtual tables, variable offsets and more.

This effort ultimately resulted in what is, today, an entire suite of decompilation tools that can be used not only in the context of the LEGO Island decompilation project, but for other similar projects as well. It is a tremendous achievement that outgrew the original project and will hopefully be useful for many other projects to come.

December 30, 2023: the Infomaniac returns

It took approximately 6 months before our decompiled version of LEGO Island was sufficiently fleshed out to render something on the screen. Until to this point, the application would not launch; all we had in terms of experience was the matching of our recompiled source code to the original.

/assets/images/blog/blog-post-9-info.jpg

LEGO Island was built around a base game engine called Omni, which mainly implemented streaming of .SI asset files, 2D video including support for Smacker and FLIC, as well as audio (Wave and MIDI formats). In order for the game to launch, most of Omni needed to be fully implemented. We have reached this milestone around the end of 2023, and one of the most iconic scenes of LEGO Island came to life. While some functionality was still missing and a number of bugs needed to be ironed out (for instance, sound played with a delay, Smacker video didn’t scale to full screen) this represented one of the first major achievements in the course of the project.

On top of Omni, LEGO Island implemented extensions to the base engine such as 3D video using Direct3D and Direct3D Retained Mode, 3D sound using DirectSound, and of course all of the game’s core logic. The vast majority of this logic was hardcoded into dedicated classes as opposed to residing in the .SI files. We’ve begun decompiling most of these components from 2024 onward.

Origin of the “are you ready to le” bug

One interesting discovery I’ve made this year (among many) was the source of the infamous “are you ready to le” bug.

It turned out that the developers had an uninitialized variable on the stack, located in the event handler WndProc of ISLE.EXE. This variable was meant to contain a notification ID that when passed to the game’s QueueEvent function, would trigger certain functionality. In almost all branches of the function, the notification ID was set; however, in the event branch of WM_SETCURSOR, which is received as a consequence of trying to exit the game through the Infocenter door, the notification ID remains unset.

/assets/images/blog/blog-post-9-readytole.jpg

At this point the original intention was probably not to send an event, but instead return early from the function. However, this has not been implemented and the code will proceed to pass the uninitialized notification ID to QueueEvent.

In case the notification ID happens to assume the exact value of 0, it will trigger this function which in turn proceeds to relaunch the exit animation (the green/red bricks). This cycle keeps repeating and ultimately results in the glitch that causes the game to crash.

If the notification ID happens to be any value other than 0, the glitch would not occur. Since the variable is uninitialized, it results in undefined behavior and depending on the pseudo-random value of the variable, the game will either work as expected or result in the glitch.

Brick by Brick

Over the course of 2024, the decompilation of LEGO Island continued and much progress has been achieved in a remarkable amount of time. Many smaller and bigger milestones along the way, such as reaching the Infocenter, rendering the island or the Infomaniac, correctly working NPC animations, all the way to the missions and the main storyline of the game have been reached and celebrated - “brick by brick”.

Here are a few impressions I’ve recorded.

December 23, 2024: 100% implemented

Finally, on December 23, 2024, we have reached the biggest milestone of all (to this date): LEGO Island has been fully decompiled in terms of functionality. This would not have been possible without all the countless hours we have invested together as a team to see this project through.

However, work is still ongoing to improve the accuracy, naming, documentation, and structure of the source code. While there may still be unresolved bugs that are not present in retail, the game should be fully playable with the binaries derived from the source code.

ISLE.EXE at 100% LEGO1.DLL at 100%

Final thoughts and beyond

A major step towards my vision of bringing LEGO Island to the browser has been taken, and I couldn’t be happier and more grateful to all the contributors that have supported the project until now.

At this point I want to take a moment to thank my wife for her unwavering support throughout this journey. Over the past 18 months, I’ve poured nearly all of my free time into this project - while balancing a full-time job as a software engineer, relocating to a new country, getting married, welcoming a newborn, buying a house, and starting a new job. It’s been a whirlwind of change and challenges, and none of it would have been possible without her sacrifices, encouragement, and belief in me.

Lastly, thanks to everyone involved in the development of LEGO Island back in the day. You have truly created something marvelous of lasting value. The dedication displayed by all of the contributors of this project is testament to that.

Of course, this journey isn’t over quite yet: now that we have fully functional source code for LEGO Island, it is time to make it platform independent, and eventually port it to the web. A follow-up project has already been launched and is in full steam. Stay excited for the next chapter!