I wrote a version of the Classic Elite Trading engine in Go, with a terminal UI. Jump to the Get It section to find out how to get it if you want to try it out.
I can't remember the year, I guess it must have been 1985 and I would have been 11. But I remember this like it was yesterday. We were visiting friends of the family and the father of the family, who worked at a private school, had bought home a BBC Micro 8-bit computer. 11 year old me was, as I am now, a complete computer nerd who was lucky enough to grow up during the birth of the home computer in the 80's, the heyday of the glorious menagerie of 8-bit computers. So I knew what a BBC micro was and was drawn to it like a moth to a flame. The computer was excitement enough, but what I saw running on it blew my mind even more.
The thing running on it was Elite. A game where you fly between planets, buy and sell commodities, make a profit, fight pirates, fight aliens and enemy traders. What made it fascinating was the apparent size of the universe it created, the wireframe graphics and the open ended non-linear gameplay. It felt like an entire world living on the computer.
Open navigation screen on Elite and you see the chart of Galaxy. Every dot was a place you could visit. Each place had a unique name and description and market to buy goods from. It looked endless and there were many many galaxies in Elite.
This blew my 11 year old mind. How was this done? At the time I was curious but mostly just wanted to play the game and explore. Elite was a seminal gaming experience.
I have played many versions of Elite on many platforms including the latest incarnation,Elite Dangerous which if played in virtual reality is one of the most immersive VR experiences you can get. Even without VR the immersive and emergent game play available in Elite Dangerous is incredible. But none of the later versions had quite the same impact of that first wireframe marvel on that BBC Micro.
If I were to list my top ten games of all time (there's an idea!), Elite would be pretty close to the top.
Over the years the curiosity about how classic Elite was still there.
Ian Bell - Text Elite
A few years ago Ian Bell, one of the developers of the original Elite released onto the web a C version of the original Elite trading engine. He called it Text Elite on his web site (still with a quirky 90's style!) because it simply implements the trading game in a text only form.
Finally I could understand see how the magic was done!
The C code is simple and clever. A little hard to follow in places, but nothing super crazy if you know even a little C.
All data that needs to persist in the game loop is stored as integers. Strings are mostly generated when they need to be displayed on screen and stored in memory sparingly and only once.
The galaxies are generated using a random seed, which is hard coded so it's the same for every game instance and execution.
Best of all the planet descriptions use an algorithm beautifully named ‘Goat Soup’ for generation. They are generated randomly (using the same seed every time) and only when displayed on screen. The Goat Soup algorithm is only there to generate the planet descriptions, but it takes up quite a chunk of the C code. Its glorious.
I wanted to understand it better and do a side project, just for fun. So I decided to reimplement text elite in Go
My first attempt at reimplementing Text Elite in Go was a success, but a miserable piece of code. I simply took the C code and translated it into Go. A feat that is neither clever or elegant. But at least I got it working…
I wasn't satisfied with this attempt, but I also wasn't that interested in doing it again, so I let it sit round for a bit.
Then summer one day while mowing my lawn, I was listening to excellent Go Time Podcast. It was an episode called Making the command line glamorous. They were speaking to Toby Padilla from Charm. A company that makes a bunch of libraries and frameworks for Go that enable you to create fancy Terminal User Interfaces (TUI). Immediately I thought: “It might be cool to do Text Elite with a TUI just for fun”
Rather than use my shameful Go port of Text Elite I decided to start again and re-write the Elite Engine in a more ‘Go like’ way. I stuck to the original spirit of the C version as much as possible (I just liked having that heritage in there and the frugalness of the design), but made it more idiomatic Go rather than a C program turned line for line into Go. I enjoyed doing this more than I expected I would (it helps if you write tests. Who knew?!).
Once the engine was built, I was ready for the TUI. So I jumped in and took a look at the Charm Bubble Tea framework and the Lip Gloss library. At first glance it looked all too hard and I wasn't so keen and nearly just stopped. Satisfied at having done a decent enough job on the engine.
Bubble Tea describes itself as a “Functional and Stateful way to build terminal apps” and a “Go framework based on the Elm Architecture". The Elm Architecture? I had no idea what that was and I didn't fancy learning a great big thing just for my small silly side project. I mean it looked interesting, but was now the time to learn yet another framework?
I was worried that the Elm Architecture would be this weird thing I'd need to learn before I could do anything with Bubble Tea. However I dug into the examples and read a little bit on the Elm Architecture and it turns out it's pretty easy and very cool.
The Elm Architecture comes from the Elm Language.
I hadn't really come across it before, not having doe much web development at all. But I am all about ‘simplicity and quality’. Turns out, the Elm Architecture uses a paradigm called Model, View, Update, which sounded to me a lot like Model, View, Controller which I do know a bit about. I started to feel more at home.
Even if you don't know much about data driven, declarative UI's and MVC, Bubble Tea is pretty easy to use. The sample apps are great and if you are a Go developer it's pretty straight forward to get something simple up and running.
Of course my Text Elite engine plugs nicely into the model part. All I needed to do was build the update logic and the view logic.
Once you have it wired up, it's pretty neat. Bubble Tea renders really a nice terminal UI that updates as the data changes. It has widgets they call ‘bubbles’ which implement all manner of UI elements (textbooks, progress bars, tables). It's all very clever and addictive once you get into it. Composing elements into a nice UI.
The sister project, Lip Gloss, provides styling similar to CSS. It allows you to add colour to text, render borders, build styled UI elements like status bars and layout the UI. You can use Lip Gloss indecently of Bubble Tea, but they work really nicely together.
I can see myself using the Bubble Tea framework and Lip Gloss a lot for future projects. It's just so much fun creating slick terminal applications.
Anyway… Here we have Text Elite, written in Go, with a terminal UI:
It's a faithful and playable recreation of the Classic Elite trading engine.
If you have a Mac and use Homebrew, you can install it by adding my Tap to your Homebrew install:
brew tap andrewsjg/tap
brew install txtelite
Or you can download the latest binary version or download the source code from my GitHub and build it yourself.
Run it and type ‘help’ to see the available commands.
It works best with a dark background (I need to add code that changes the style based on the terminal style… one day). I have tested it on the Mac terminal and iTerm. It works fine on Ubuntu Linux 22.04.
It will run on Windows, but the terminal UI doesn't render properly in the windows command shell. It may work if you use a 3rd party terminal, but I haven't tried. It can probably be fixed, and I'll try to do it soon(tm).
I am sure there are many UI and engine bugs and I probably haven't got all of the Bubble Tea bits and pieces perfectly right. There are a few things I might get to on the TODO list (I'd love to somehow render the galaxy map). But it's functional and works in a not unreasonably sized terminal window.