Home
Posted on 12/24/2024
Tags: Programming, Games
Introducing my latest game, playable right in your web browser: Space Trader

In Space Trader, you can trade goods, hunt bounties, amass a fortune, buy a moon and retire.

Space Trader can be saved to your home screen as a PWA (Progressive Web App).


Space Trader started as a game written by Pieter Spronck for Palm OS, released in 2002. Wikipedia page. Official website (mirror).

You can play the original on archive.org.

As one of my favorites, this game holds a special place in my heart. I played a ton in middle school and high school. This is the second port of the game I've made.

Like SFCave (recreated as CaveRibbon), I decided to recreate Space Trader as a web app to feed my nostalgia and give the game new life. I hope this version of Space Trader can survive long into the future thanks to the universal availability of web browsers and their devotion to compatibility.


Some technical details:

- As usual, I used PCEImage Editor to create many graphics. I created the PCEImage format and tools so I could simply store and edit graphics as ASCII art. See them here.

- To aid debugging and unit testing, I use a deterministic random number generator called GameRand. In debug mode, I can capture the random seed and log of every action taken in the game. Then I can replay that to reproduce a bug or create a test.
  - I've written many unit / integration tests for Space Trader. See them here.
  - Learn more about GameRand in the post for CaveRibbon.
  - A major downside to this technique for testing is that tests become invalid if a bug fix (or a new feature) changes the amount of random numbers consumed. I ended up remaking many tests one or two times. This added a few days of extra work to the project.
  - You can play the game with cheats and access the replay log on a special version of the game: cheats.html.

- I translated an existing implementation of this game to vanilla JavaScript using ChatGPT. I could translate ~300 lines at a time. I audited every line produced. This worked pretty well and saved me a huge amount of time compared to manually translating the code. This was a somewhat zen activity for me because it was mechanical; tedious but rewarding to see how quickly I could progress through the whole codebase. This was the kind of programming I could do after an exhausting day at work. Major differences/difficulties:
  - The original code relies on integer math, but JavaScript uses float math. I needed to ensure all uses of numbers yielded an expected result. I ended up adding exhaustive runtime asserts and writing automated stress tests to catch problems.
  - ChatGPT would sometimes produce inconsistent translations, especially for enum names. These could lurk, waiting to cause a crash at runtime. I hunted these with stress tests, manual tests, nearly exhaustive code coverage, and replayable game logs (which I turned into tests).
  - Similarly, ChatGPT would inconsistently translate properties and their setters/getters. I left many awkward translations in place to save myself time, even though it makes the code worse.
  - The UI needed to be tailored to the web. I ended up writing almost all new code for the UI.
  - The original code had no tests. I wrote all new tests and a quick-and-dirty system for measuring code coverage. I even discovered several longstanding bugs in the original code.

- Before translating the whole codebase, I investigated using emscripten to reuse as much of the original C code as possible. I decided I wouldn't be satisfied with the result. There wasn't separation of UI and business logic that would have let me easily build new UI tailored to web. There were a lot of Palm OS platform-specific functions that would need to be replaced. I didn't want to struggle to change the existing code where it became necessary.