The Solar Trail

Drug Wars meets The Expanse

Kris Chain
ILLUMINATION’S MIRROR
7 min readOct 3, 2023

--

I enjoy learning about systems. Systems have inputs and outputs. After enough tinkering with a system, you end up learning what is important and why. After that, everything else is just details.

Building games in Python is a great delivery system to learn about everything you need to create a functioning program. After building Snake and a choose-your-own-adventure text game, I wanted to build something without a tutorial. Out of this desire came The Solar Trail which was the marriage of one of the best science fiction series, The Expanse, and a long-lost TI-83 calculator drug dealing game that taught me about market fundamentals and how to get in trouble in grade school.

If you need some context, continue reading. If you want to see the code, feel free to fork it from github and expand away!

The Expanse

I haven’t found a science fiction book or series that brings together suspense, aliens, and plausibility in quite the same way as The Expanse. Sure, there are outstanding works that come close, but in my opinion, the focus on human nature and the realistic boundaries of our universe makes this series great.

No spoilers here, but the story starts a few hundred years in the future when humanity has expanded throughout the solar system. It starts as almost a retelling of the Peloponnesian War by Thucydides where we have two great powers struggling to control/influence many smaller factions which change based on their needs. It’s a story as old as time which is why it works. In this fictional universe, the dipoles are Earth and Mars but thinking about the US and USSR or Rome and Carthage will set the stage efficiently.

Between the superpowers, there is a rising power called the Belters which are the distributed populations of humans that don’t live on Earth or Mars. Just like European expansion into the Americas, with enough time and distance, it is human nature to develop a unique culture and sense of independence.

Moving supplies throughout this fictional future feels extremely plausible all the way down to mining/transporting materials across vast distances. Oxygen and water need to be sent to outposts on faraway moons or space stations just like the raw materials being mined need to be sent back to Earth and Mars. This ecosystem would be subject to supply and demand just like any other civilization.

Drug Wars — the first viral calculator game

TI-83 calculators are essential to learning math or how to sell drugs in NYC. Photo by Aaron Lefler on Unsplash

The year 2000 was like being at the top of a roller coaster just as it started to lurch forward and go over that first huge drop. The iPhone was years away, Y2K hadn’t destroyed our world, and the internet was a different place. Bo Burnham nailed the time with Welcome to the Internet: it was a carefree time where technology felt like it was only around to help. Flame wars hadn’t begun, bots weren’t a thing, and your AIM profile was the most important part of a young person’s online persona.

The benevolence of technology at that time was complicated by one viral game that taught you how to sell drugs in New York City: Drug Wars. The game was simple: you were an aspiring drug dealer with some cash in your pocket and all you had to do was buy drugs on the cheap, travel to a different borough in NYC, and sell high. The menu of options included pot, heroin, speed, LSD… all the things that D.A.R.E. was telling you to stay away from. Naturally, this game had the perfect recipe to go viral.

For a student of that time, Drug Wars had it all:

  • It only played on a TI-83 calculator which was a required item for just about every math class above algebra.
  • You could play the game in class while looking like you were working on an assignment.
  • No adult even had a concept of games being loaded on a calculator and with one button press returning you to the normal calculator function, it was nearly impossible to get caught.
  • It required a transfer cable to share it from calculator to calculator and every school had that one kid that somehow had a cable.
  • It used inappropriate material in an educational way. In a pinch, it felt like you could reason your way out of trouble because math was involved.
  • It was New York. Remember, this was before YouTube and Grand Theft Auto 3, so this calculator game lets you play around in the New York City of your imagination.

My calculator with the game file on it met a tragic end with some degraded batteries. That game was a lost relic for many years. Some millennials knew about it and most didn’t but it was always an interesting conversation piece about something that was to time.

Drug Wars meets The Expanse

This game was my initial way to learn how the Python class structure works. There was enough meat to build a few interacting classes to pass data between, familiar gameplay mechanics, a rich universe, and a unique problem that had no ready-made solutions (that I knew of) to cheat myself out of learning.

It didn’t take long before everything started to fall into place. As a largely self-taught coder, this was a fun problem to tackle. There is more than enough fertile ground to cover if someone wants to take this idea and expand it, but it served my purpose. Feel free to fork the repository or if you remember this game from being a kid, build your own and compare!

Now onto the code. First, we need items in a class structure that can hold information. In addition to the name of the item, we can include a summary, price, and category:

class Item:
def __init__(self,name,cat,price,info):
self.name = name
self.cat = cat
self.price = price
self.info = info

The category is used to describe where in the solar system this item would be most easily found. This is useful for creating scarcity where it makes sense.

Next, is the City class which includes a name, a short description, and distance from the sun which is used to calculate distances when traveling. The word city is an artifact from Drug Wars where the player would travel from borough to borough. This class should be called Hub or Station, but City works for now:

class City:
def __init__(self,name,info,distance):
self.name = name
self.info = info
self.distance = distance

Next is the Player class. This handles the player’s inventory and wallet:

class Player:
def __init__(self,name):
self.name = name
cash = 5000

_Water = 1000
_Copper = 0
_Helium = 0
_Crew = 4
_Fuel = 200

def check_inv(self):
print (" ")
print ("I N V E N T O R Y :")
print (" ")
print ("Cash: ", self.cash)
print (" ")
print ("Water: ", self._Water)
print ("Copper: ", self._Copper)
print ("Helium: ", self._Helium)
print ("Crew: ", self._Crew)
print ("Fuel: ", self._Fuel)

The Map class contains a few core functions of the game like ‘where am I’ and ‘how far away is another location’.

The first of the major gameplay mechanics is the travel function. This allows a user to choose the destination and sets the randomized market fluctuations when arriving at a new destination:

         def travel(self, city):
self.location = city
print (" ")
print ("You Have arrived at ", self.location.name)
print (" ")
#set new rates
if (self.location.name == 'Mercury' or self.location.name == 'Venus' or self.location.name == 'Earth' or self.location.name == 'Luna'):
self.inner = round(random.uniform(0.1,1.5),3)
self.belter = round(random.uniform(0.1,2.7),3)
self.jovian = round(random.uniform(1.2,3.5),3)
if (self.location.name == 'Eros' or self.location.name == 'Ceres'):
self.inner = round(random.uniform(0.5,2.7),3)
self.belter = round(random.uniform(0.1,1.5),3)
self.jovian = round(random.uniform(0.5,3.0),3)
if (self.location.name == 'Ganymede' or self.location.name == 'Io' or self.location.name == 'Titan' or self.location.name == 'Enceladus' or self.location.name == 'Tycho Station'):
self.inner = round(random.uniform(1.5,3.5),3)
self.belter = round(random.uniform(0.5,2.7),3)
self.jovian = round(random.uniform(0.1,1.0),3)

The demand function in the Map class allows a user to quickly assess the current trading rates of various supplies:

         def check_demand(self):
print (" ")
print ("D E M A N D :")
print ("Current Location market multiplier: ", self.location.name)
print (" ")
print ("Ship items: ",self.inner,"X")
print ("Asteroid Belt Resources: ",self.belter,"X")
print ("Jovian System Resources: ",self.jovian,"X")
print (" ")
print ("Water: $",round(float(Water.price)*float(self.belter),1))
print ("Copper: $",round(float(Copper.price)*float(self.belter),1))
print ("Helium: $",round(float(Helium.price)*float(self.jovian),1))
print ("Crew: $",round(float(Crew.price)*float(self.inner),1))
print ("Fuel: $",round(float(Fuel.price)*float(self.inner),1))

The travel, buy, and sell functions are part of the game loop that allow for different Class attributes to talk to one another. Take the travel function:

def Travel():
currentloc = m1.location.name
currentlocd = m1.location.distance
print("Current location: ", currentloc)
destination = input("Where to?: ")
destination = destination.title()
found = False
for x in range(0,len(m1.cities)):
if (destination == m1.cities[x].name):
print ("Found ",m1.cities[x].name," on the map...")
trip = round(abs(currentlocd-m1.cities[x].distance),3)
tripfuel = round(trip*50,1)
tripwater = round(trip*100,1)
print (m1.cities[x].name, " is ", trip, "AU away from your current location.")
print ("Traveling to ", m1.cities[x].name, " will use ", tripfuel, "fuel pellets and ", tripwater, "L of water.")
if p1._Fuel >= tripfuel and p1._Water >= tripwater:
found = True
p1._Fuel -= tripfuel
p1._Water -= tripwater
city = m1.cities[x]
print ("Working ")
m1.travel(city)
elif p1._Fuel < tripfuel or p1._Water < tripwater:
print ("You don't have the resources to make the journey! Try again later...")
print (" ")
else:
print("I can't find this place.")
print(" ")

This game loop function assesses a user’s current location from the Map Class, calculates the fuel available from the Player Class, determines if a trip is viable, and if so, updates the player’s inventory and location in the appropriate classes.

There is minimal strategy at this point but this was everything it was intended to be: a thought experiment turned into a personal coding exercise to learn the Python Class system. The skills learned in this exercise were put into action on larger projects with a more refined approach.

If you are looking to learn something in a coding language, you don’t always need to find a tutorial — jump in and make it work. You will break everything along the way but you will learn a ton. LLM tools make learning that much easier nowadays, so get to building!

--

--

Kris Chain
ILLUMINATION’S MIRROR

Scientist, teacher, conservationist, and father trying to do what I can to make the world a better place. Founder of seasonreport.com