Creating a Lisp Game in 2022

In 2018, I wrote a post surveying the Common Lisp games landscape and sharing some of the tools we were using to create Spycursion. Parts of that post were dedicated to explaining why we chose Lisp in the first place; those parts have not changed (much), so I won’t rehash them here. Instead, I’ll update you on our own contribution to Lisp game development and how we got here.

If you’ve been following Spycursion for a while, you know that our first gameplay trailers were built on top of CEPL and QTools. After revealing those trailers, the most common criticisms were about graphics/aesthetics*. For that reason, among others, we knew that we wanted to redesign the client and move away from CEPL and QTools. The big question — the question on which we expended copious team discussions — was what to move to. I won’t get into the options that we looked at and ruled out. In the end, we were most excited by Raylib.

(* Fun fact: I screen recorded those videos on a machine that couldn’t handle the load, and had to reduce quality to prevent stuttering. Mea culpa.)

Raylib is a set of lightweight, open-source game libraries. It is well-documented (with examples!), actively developed with stable releases, runs on at least five operating systems plus HTML5, and has nine years of bug fixes under its belt. For us, there was only one glaring problem: Raylib is written in C. (I apologize for making you throw up in your mouth a little bit just now.) We surveyed the existing Lisp bindings for Raylib, concluded none were where we needed them to be, and decided to wrap our own. Hence, Claylib was born!

Claylib is designed to be a Lispy, beginner-friendly game toolkit. Let’s unpack those two bolded terms, because they’re both important:

Lispy means that Claylib tries to smooth over Raylib’s C semantics as much as is feasible. It is not simply a wrapper around Raylib (though you can use it for that if you prefer). Personally, I like to write Lisp, not “C in Lisp syntax.” That’s why Claylib abstracts C structs into CLOS objects and can manage memory for you using scenes (which do not exist in Raylib).

Beginner-friendly means that Claylib aims to be a fun way to learn Common Lisp, or game development, or both! Raylib itself has a similar stated goal — minus the Lisp, for some silly reason. Arguably, we didn’t have to make Claylib beginner-friendly, but understand that one of our long-term goals is to help boost the community of developers using Lisp and other “esoteric” (but powerful) languages. What better way to do that than by showing off how easy it can be to use Lisp for games, which are some of the most complex software in existence?

At the moment, Claylib is still beta quality and doesn’t have a stable release. It does have a number of examples and some high-level documentation to help you get the gist of it. If you don’t mind “writing C in Lisp syntax,” the wrapper layer that I alluded to above should have feature parity with Raylib. That includes the core, math, and GUI libraries; audio will be coming next.

Finally, for completion, a quick list of non-Claylib CL game engines:

Trial is probably best known for being the game engine behind Kandria. Clearly suitable for a 2D game, though I don’t have any information about its 3D support. The more your game resembles Kandria (or one of the other example games they list), the better an option Trial is likely to be.
Virality Engine has some impressive 3D demos. Its GitHub page showed no activity for awhile, but does have a few recent commits, so I hope that trend continues.
alien-works is a framework of a number of libraries, some in CL, some with C/C++ wrappers. It focuses on performance but appears to be in an earlier stage of development than the other two.

If you decide to give Claylib a whirl, let us know how it goes! We’re excited to see what Lispers and non-Lispers alike can do with it.



How should a game look?

Recently I was reminiscing about some games that seemed not so good looking, but that would not have worked as well with “better graphics”, notice how I quoted that, because we tend to think about game graphics as good when they tend towards photorealism, or are very polished 2D pieces of art (like Cuphead). Suddenly you run into a game like “Thomas was alone”, and you think, I would not change a thing, even though all the characters are colored rectangles.

There are games where the way it looks is somehow independent of the way it plays, think of Nethack, there are people playing that in a terminal, and the graphics are just characters forming the walls, items, and enemies,

there are also people developing 2D tile sets, so a wolf looks like a wolf and not like a lowercase “d”.

And then there are people that have created a 3D interface.

The thing is, the gameplay does not change, because of the type of game it is, in this case a turn-based rogue. There are people that swear that the ascii version is better, there are some which prefer 2d graphical tile sets, and very few prefer the 3D version although it does arguably it looks more modern. Why am I talking about those things in this blog post? Well, because ultimately we will have to choose a look for our game. When you look at games like Fortnite, an ascii version most likely would not have worked. Games like Cuphead were all about achieving a certain look, in this case old time cartoons.

So, How do we decide?
A lot of you saw old versions of Spycursion here and in other places, the look was praised by some people, and criticized by others, the thing is, beauty is in the eye of the beholder.
So what are the right graphics for a game like Spycursion? For one thing we have said it is an RPG, so based on genre there are some expectations, because the more popular MMORPGs are 3D games with character customization, but in reality they range from almost photorealistic like Bless

To cute anime style like Nostale

Or maybe pixel art, like Blossom and Decay

And if we are willing to accept MUDs (Multi User Dungeons) as MMORPGs even text-based.

So, I would say that even more important than the type of graphics is the ambiance that we want to maintain, a dystopian future with some cyberpunk feel, which means the design of the environments and characters should not break the immersion by feeling out of place. You can see that this does not necessarily narrow the art style, the game could work in 2D or 3D. I would stay away from a text-based for Spycursion, due to the dynamicity of graphics compared to text, which will be important in our world, but you can make cyberpunk anime , or pixel art . We want to create a polished cohesive product, with an indie budget, so have to take decisions that will shape the look and feel of the game, without sacrificing quality. Ultimately we have to decide what polished means for Spycursion based on what we can achieve with our budget and resources based on our personal taste, with artistic sensibility the constraints often stimulate creativity, and help to unify the look of the game. We have said several times that we will open-source the front end, and that will allow other people to create different variants of it, but we have to create one that will represent our vision of the world we are creating, and which will hopefully artistically appeal to Hackers and Gamers, we believe that making the right decisions will give us a nice looking, performant and fun game.

 



How Many Lisps Do We Need?

Lisp logo
Lisp logo by Conrad Barski

What? We’ve had blog posts about the fact that we’re writing Spycursion in Lisp. Some call it secret alien technology.  Okay, full disclosure: Lisp as a computing language was created on Earth by a human (his name was John McCarthy) back in the late 1950s. I can’t say whether or not he was inspired by beings from another world. I don’t know for sure, and even if I did, it would be a secret. I would never say. What I do know is that there is a great deal of power packed into the elegant and surprisingly simple programming language known as Lisp. Every few years, we see more modern languages (say, C++, Java, or Python) bringing in “novel” programming constructs into newer releases of the language. Yet, these exciting new constructs are frequently taken from Lisp and often have been part of Lisp since darn near the beginning.

So, it’s a great language if you’re a programmer willing to venture outside the proverbial box. But why did I start off talking about Lisps, plural, as if there were more than one? Simple: there is more than one. In fact there are many. Lisp is actually a family of programming languages. A Lisp can be quite different from other Lisps in much the same way that C++, Java, and Python are different from each other. (If you’re curious, those languages all belong to what could be called the Algol family.) What we have been generally referring to as Lisp is actually a language called Common Lisp, which is the result of an effort to consolidate features from many of the earlier Lisps into one standardized language. Common Lisp is a powerful choice, which allows our tiny team of developers to deliver you a great big gaming experience full of secrets, intrigue, and espionage in a dystopian world just waiting for you to leave your own unique mark on it.

But Spycursion is an MMO. For the three of you who don’t already know it, that means “massively multiplayer online” game. We would like you to know that we are taking that first M very seriously. No doubt you have heard about some online service that fell to its knees at some point because a mass of people all tried to connect to it at the same time. I remember, as a keen example, an evening in recent history when newscasters were reporting the increasingly certain result for a presidential election in the United States. So many people in the country were frightened by the outcome that the Canadian immigration website eventually went down that night. Some people thought this funny. Others thought it worrisome. I thought, Canada did not program its immigration website in Erlang.

So, what’s an Erlang? It’s not a Lisp (though that would certainly have been a sharp guess). It is, however, a programming language and an extremely powerful one at that, just not in the same way that Lisp is known to be powerful. Erlang was not designed to be a general purpose language with Lispy features that lets a tiny development team like ours mould the language itself into the perfect tool to build Spycursion for all of you. Erlang was designed specifically so that when hundreds of thousands (or dare we imagine, millions) of you all decide to play Spycursion at the same time, our servers don’t fall flat as if they had nothing more important to do than to provide information about immigration to Canada to panicking voters.

Erlang is a programming language whose central purpose is to do a massive number of tasks at the same time and also to create systems that never go down, ever. The downside of a language that strives to achieve what no other programming language can is that it is not general-purpose like Common Lisp. Erlang is primarily a server-side language, and so we aren’t really aiming to keep your own personal computer running. Rather, we want to make sure the computers responsible for providing you access to the world of Spycursion are able to keep that world available to you, even if you all decide to enter the game at the same time, even when we have to update our systems, even if we have hardware issues, and even if one of us has somehow missed a bug in our code. (There’s less chance of that in Erlang, but it still happens to the best of us.)

Yet, as we said, Erlang is not a Lisp. We are (defun games ()), which has Lisp right there in the name. (And we’ll give one month of free game play to the first 8 people who figure out how that makes any sense.) Sure the Spycursion client you enjoy on your computer is powered by Common Lisp, but we also want that Lispy goodness on the server side so we can fine-tune our programming language and bring you the best game possible. Unfortunately, there is almost always a trade-off when making design decisions about programming languages. If only Erlang were a Lisp so that we could harness the superpowers of both languages at the same time.

Now I am guessing that perhaps at most three of you have heard of LFE. It may be more of that secret alien technology, but it too was created on Earth by a human (his name is Robert Virding) back in the mid 2000s. LFE stands for Lisp Flavoured Erlang.  As the name implies, we have Lisp and Erlang in a single programming language. We at (defun games ()) feel that it truly represents the best of both worlds. We can use the power of a Lisp to extend the language so that it is not only a gaming language, but a language oriented specifically for Spycursion. At the same time we can build the world of Spycursion on the solidly reliable and massively parallel foundation that comes with an Erlang-based application.

LFE logo
LFE logo by Duncan McGreggor

So, how many Lisps do we need?   To provide you the best massively multiplayer online gaming experience we possibly can, we need two: Lisp Flavoured Erlang to serve you en masse and Common Lisp so we can delight you individually.



Introducing Myself (den)

Den's Picture
The peril-sensitive sunglasses need an adjustment!

Hello, Spycursion fans.  My name is Den Drown.  I have heard at various points that there are eight or three or a handful of you.  I had better introduce myself now, before you number in the hundreds or thousands.  (Dare I say millions?)  However many of you there are, know that I am thrilled to be part of the team bringing you Spycursion.  I know you’re simply going to love this game.

How can I know this when I’m just meeting you now, virtually, on a blog post for this odd company (defun games ())?  Essentially, I believe you’ll love the game for the same reason that I do.  The people bringing it to you are thinking of you at every step.  This is more of a challenge than you might imagine.  Some of you are interested in learning some programming.  Some just want to have fun.  Generally, you think a dystopian world, rife with espionage and subterfuge, sounds intriguing.  You are, of course, right about this, but your intrigue takes shape in various ways.  Some of you feel a deep desire to make this tragic world a better place.  Others feel they can understand the chaos, allowing them to manipulate it, bending it subtly to their will for fun and for profit.  Finally, our greatest challenge will surely come from those among you who seek some winding path between the noble goal and the devious one.  What are you looking for when you step into Spycursion?

No doubt, you’re already aware that (defun games ()) is coding Spycursion in Lisp.  Believe it or not (likely a good number of game developers will not), this is a very good thing.  My first experience with Lisp  was way back in 1989 when I took a course in Common Lisp as an elective in the computer engineering program at North Carolina State.  That was the semester I truly discovered the magic in programming.  My career in software development has largely revolved around the languages of the industry (C/C++, Java and several others of their persuasion), but over the last several years I have been fortunate enough to find (or create) opportunities to design and develop systems using a number of languages that allow the coder to ultimately go beyond what is readily doable using a “mainstream” programming language.  Most of these marvelous languages are members of the Lisp family.

Lisp is a key reason that I am joining Scott and Mauricio as we dedicate our blood, sweat, and tears to bring you Spycursion.  Lisp does more than make it possible for a tiny team like ours to create a professional game that will thrill you, delight you, and even allow you to learn something in the process.  John Foderaro called Lisp a “programmable programming language,” and it is exactly that.  We are molding the very language used to create Spycursion into the perfect language to express in code the world that the game represents.  To me, this beats the approach of plugging the game context into a mainstream gaming engine.  It beats it by a mile.

I may be biased.  Lisp has historically been considered the language of artificial intelligence, and here I am joining (defun games ()) just as I am working to finish up a PhD in cognitive computing.  However, if you are already a fan of Spycursion, well before even a beta release, then I bet you can guess how AI-oriented design and Lisp are a natural foundation for a game that challenges you to survive and even thrive in a world where technology is perhaps the only thing holding everything together.  In addition to AI, I will be drawing from a background in computer-telephony integration and information security.  I look forward to putting these skills to use so that you may lose yourself in the dangerous and captivating, technological world that is Spycursion.

–den Drown

 



Procedural Generation

As a team of (currently) just two developers, people often ask us how we can possibly create a game as expansive as Spycursion. If you ask someone who doesn’t make games for a living about their idea of what an MMO is, the first game to pop into their head is likely to be World of Warcraft — a 16-year-old behemoth created by a company with over 4,000 employees and billions of dollars in revenue.

Fortunately for us, Spycursion is not World of Warcraft, nor is World of Warcraft synonymous with the MMO genre!

In order to “catch up” with the big players, indie studios making big games need to be creative about where to focus their efforts and where they can “cheat.” This is where procedural generation comes in. To illustrate procedural generation, I’d like you to walk through a short exercise with me: Grab a pencil and paper and draw a house. Your house should have four walls, at least one door, at least one window, and a roof. The other details are up to you.

Go ahead and draw that house now. I’ll wait.

… You don’t seem convinced that this has anything to do with procedural generation. That’s okay, do it anyway. 😉 When you’re done, send this blog post to a friend and have them draw a house as well, with the same specs. (Yes, it’s relevant, I promise.)

Now compare the two houses you and your friend have drawn. Unless you and your friend are part of the same hive mind, your two houses should look at least somewhat different. And it’s easy to understand why; the key lies in that phrase, “the other details are up to you.” Your house could be in 2D, or if you’re good, maybe it’s 3D. Maybe your house has a chimney, maybe it has landscaping. Maybe the front door has a door handle, or maybe you forgot that rather important feature. Maybe you went on an interior decorating binge and drew stuff inside the house. Maybe your house has a balcony, or an attached garage, or a rooftop garden. Maybe your house looks like it was drawn by a chimpanzee. Maybe you are a chimpanzee.

Point is, if you were to assign this task to 100 chimpanzees, you would get 100 different houses. Add in some roads, and you have a neighborhood. Have the chimps draw 100 different neighborhoods (with different specifications like density, age, residential vs. commercial zoning, etc.) and you have a city. Now replace the chimps with a computer, and there you have it — procedural generation!

With the right algorithms, a small studio can use procedural generation to create game worlds that look like this…

Attribution: By Source, Fair use, https://en.wikipedia.org/w/index.php?curid=39980945
.kkrieger (2004)

Or this…

Attribution: https://www.flickr.com/photos/playstationblog/14052569021
Spelunky (2008)

Or even this…

Attribution: By Source (WP:NFCC#4), Fair use, https://en.wikipedia.org/w/index.php?curid=47438165
No Man’s Sky (2016)

Spycursion uses procedural generation, in various places, to help generate its “real” world as well as its virtual one. In the last trailer, by contrast, neither the demonstrated city nor the internet were procedural. The city in our Kickstarter trailer was a big hand-crafted grid, and there was only one of it. The “internet” was just a couple of devices. Nowadays, our test version of the in-game internet is a graph of 10,000 devices, and that will be expanded later (and expanded by players, of course). The world can contain up to 300 cities spread across every continent, with the ability to quickly add more, should the need arise.

With the help of chimpanzees algorithms, the two of us are working hard to bring Spycursion’s immersive twin worlds to life. Eat that, World of Warcraft.



What’s the deal with this server side and client side stuff?

I was looking at our previous posts and I noticed that Scott had written a bit of an overview of what the server does, but I never made any attempts to make any explanations about the client, I guess that somehow I tend to think that everybody knows, but some times is better to talk about what you think everybody knows. The client, is, after all, the most visible part of the game.

If you write a single player game, normally you can get away with having everything in a single place (the executing machine). The natural question when you have an online multiplayer game is, What can you have in your client and what must be on the server?

Let’s imagine a simple game which can be played online, “Air Hockey”, and of course, keeping it simple, just two players. Each client could have a map (the table), the assets (the paddles and puck graphics), the sound effects and music. Since each player is using a different computer to render the table, paddles, puck etc,  we could quickly come up with two versions of the world, the one you see and the one your opponent sees, and that can greatly affect game-play. If you try to block the puck but it is not where you thought it should be, then you could unfairly loose a point.

Right away we understand why we need a system to make our worlds as similar as possible. So both clients must communicate with the server, and tell it where the paddle is, what is its speed, and perhaps some other information, the server in this case will communicate to both clients where the puck is, what is its speed and direction, where is your opponent’s paddle, and how it is moving, state that tells you if the puck collided and what it collided with, etc.

Now, in order to render things as synchronized as possible both clients must communicate with the server as frequently as possible, because the server is the source of truth, but at the same time there may be limitations that can cause you to not  be able to receive/transmit in each frame, however the game must maintain its fluidity, so your client must be able to decide what to do when it does not receive information from the server, and then communicate to the sever what happened so it can re-sync stuff.

What happens if you get disconnected? the client should be able to determine if it lost it’s connection with the server, and have some way to get you out of the game in a way that won’t make your game crash. You might get substituted by a bot, so the other player can finish, but that is up to the server.

Now let’s complicate things a bit, imagine that somebody invented a extreme version of air hockey combined with pinball “Pinbockey!”, there might be obstacles that react to the puck when they get hit, furthermore, imagine that the placement of these things can be customized, and some players create special tables.

When this happens we will have another complication, you won’t have all possible maps in your game, the server must transmit those maps before the match starts, and your game should be able to read that information and render the map as envisioned by the level designer in reasonable time. Asides from just rendering the table, it must be able to understand what events could happen, and how do those events look and sound, all of that  “protocol” should be established and the client must understand how the server will communicate the state to it, so it can render things correctly, play the appropriate sounds, etc. The main job of the client’s program is to display the world as consistently as it can to all the players, so all of them are playing the same game, and at the same time respect the physics and rules of the game in between the moments when it gets updates.

So far we have talked about a game with two players, but MMOs by definition have many players, and they could be doing things like jumping, running, engaging in conversation, interacting with the world, etc. Some of those things should be visible, and/or audible to you, each running client should create a representation of that reality which immerses each player in a single cohesive world.

Spycursion is a game with some particularities, you can hack, which means you will have devices that will connect to other devices, and that means that you will have GUIs that should react to devices, some nearby and some remote, which may at the same time be visible to other players,the client in many cases will just be a dumb terminal, or GUI and all of the things happening in this interface actually are communicated to and from the server. All of that must happen while keeping the physical world around you going, because Spycursion is also an espionage game, and people around you will be watching and hearing you and in some cases trying to gain access to your devices.

By this point you might be able to get some idea of what happens in the server and what happens in the client, the only thing I have not mentioned is that any program that is capable of showing a representation of the world that is understandable by the player could be a client for that game, so potentially several clients could be developed for a single game, and the visual appeal and performance of the client has a great deal of influence on the success of it.

I hope this was interesting to you, I tried to keep it non technical so all interested parties can get something from this post, we might revisit some of these ideas in future posts.

I hope you have fun and learn something everyday,  and keep an eye on this project, which will give you an opportunity to do both,



Viruses, Errors, and You

Not that I would ever wish this upon anyone, but let’s pretend that you just became one of the unlucky 1.5 million people (at the time of this writing) to be infected with COVID-19.  Since this post is primarily about error handling — don’t worry, I’ll get there — let’s think about the errors that may have occurred up to the point when you became sick. In other words, what went wrong, what mistakes were made, to cause this undesirable end result.

    • Maybe Patient Zero was a jerk who coughed on dozens of other people, accelerating the initial spread.
    • Maybe China’s government bungled the initial response, allowing the virus to leave its borders and/or misleadingly downplaying the threat.
    • Maybe your own government didn’t act quickly enough to enact social distancing and ramp up testing.
    • Maybe testing was ramped up, but there weren’t enough supplies or staff members to process those tests.
    • Maybe one of your coworkers or family members ignored social distancing rules and got you infected.
    • Or maybe none of the above happened, and you just screwed it up for yourself by trying to break the doorknob licking world record.

Naturally, at the top of that list, we could put “COVID-19 came into existence.” And with the exception of that mutation “error,” what all of the above problems have in common is that they are preventable. If the right people take the right actions, at the right times, the number of cases of COVID-19 — perhaps including yours — can be reduced.

By this point, however, containment isn’t practical, and with the long incubation period, it may never have been. (You could argue that, if China had acted aggressively and early enough, COVID-19 could’ve been completely contained. My analogy kind of breaks down on that issue, so I won’t get into it.) In any system that is large or complex enough, you will inevitably have failures — people make mistakes, governments dawdle, our scientific understanding proves insufficient. Members of society at large will get sick, with or without showing any symptoms, and everyone else has to figure out how to deal with that.

What does all of this have to do with Spycursion? One of my (many) quarantine projects has been improving the game’s error handling. Just like with a pandemic, any large software project has a massive number of moving parts, any number of which can and will fail. Preventing failures entirely is a lost cause, just like relying on 7.2 billion humans to follow hygiene guidelines flawlessly is a lost cause.

To hammer this point home, consider a few possible sources of errors we, as the game developers, might have to deal with:

    • Server-side infrastructure problems, such as a database becoming unavailable
    • A game client making invalid API calls
    • A game client making valid API calls that violate game rules — in other words, a player trying to cheat
    • Some poorly-written Slang software making an incorrect function call
    • A player running a piece of Slang software incorrectly, like putting “1 / 0” into a calculator program

You might notice that some of these error sources are entirely out of our control! We cannot control what players will do, but we can make sure that Spycursion still does The Right Thing™ when faced with an unexpected situation. This is the essence of error handling.

But what exactly is The Right Thing™ when it comes to, say, a database failure? What happens when the game server calls login_player and the result is error: database unreachable? We don’t just immediately show this message to the player verbatim, partly because it’s meaningless to them, but also because the problem may still be fixable. Ideally, this database will have a backup copy ready to go, so the code can try the same call to a different database server and everything is hunky dory. If the backup is down too, then the player can’t log in, and we have no choice but to tell them something. So that message error: database unreachable bubbles up through a series of constructs, which I won’t get into details about but often looks something like try { stuff } catch(errors) { other-stuff }. (Common Lisp has its own powerful tools for handling errors, but that’s another post for another time.) In the end, the player receives a less confusing message, like: “Oh crap, something went wrong with Spycursion, but don’t worry, we’re gonna fix it ASAP, promise, please don’t talk smack about us on Twitter, kthxbai.”

The Slang calculator program is an interesting scenario, and somewhat unique to Spycursion, because it deals with player-written code. We do provide (simple) features in Slang to deal with errors and warnings, so a well-written calculator program would throw a “divide by zero” error on its own. But there’s always the possibility of a poorly-written calculator that forces us to deal with that division by zero. In that scenario, we still handle the error, but not necessarily without a penalty to the player who wrote the faulty Slang code. (Don’t say I didn’t warn you…)

In all cases, a lower-level error bubbles up to higher levels until it is either handled or we give up and send a pleading message to the player. Going back to our unfortunate COVID-19 scenario, perhaps you can see a similar process playing out:

Error: Virus created

Error: Containment failure

Error: Not enough tests

Error: Unable to process tests

Error: Social distancing breach detected

Error: Too many doorknobs licked

Just like a well-designed software system, a well-designed public health system will reduce illness by handling these “errors.” Well, except that last one. There’s still no cure for stupidity.



Realistic Hacking

We have talked about realistic hacking in Spycursion a lot of times, but what exactly is hacking and what do we mean by realistic? Let’s answer those questions one at a time.

Hacking

Frequently when people hear about hackers they imagine a shady figure with a hood trying to steal your bank account information or get into your e-mail, but it is more about applied knowledge and outsmarting systems to get what you want, some times maliciously (black hat hacking) and some times legally (white hat hacking). In general when people think about hackers they are thinking of coders that can cast magical “spells” which allow them to do almost anything, changing traffic lights, changing their college grades, moving money around, or even get heart attacks to people using connected pacemakers.

In modern days a lot of these things can be realistic, if the systems can be controlled remotely chances are somebody can design an attack that will allow them govern the system, and make it do things, some of which are unexpected even to those who designed the system. But hacking is not limited to that, however in a game we need to limit things to what can be achieved inside our simulation of the world.

Realistic Hacking in Spycursion

To disrupt or infiltrate a system we need to know how things work, how do clients access the system, what happens when a system receives a request (or a lot of them), how do systems protect against over-lookers, and how can you overlook the information coming and going from the parts involved in a conversation.

Once we know how things work, we have to be ingenious to know how we can make them do what we want or stop doing what they are supposed to do. So in order to have realistic hacking in our game, we need to have systems that are accessed in a similar way than real systems do, with existing protocols, and with limitations similar to those of real systems.

Where do systems, break?, the answer could be in the physical layer, in the low level communications, in the protocols, in the limitations of the server (an its underlying OS), and a lot of times in the people using the system. So a player in our game should be able to create attacks to any of those layers. This means that:

There must be servers, clients and peers interconnected trough an internet, with messages going to a from servers, some times through wires, and sometimes wirelessly, IR, Wi-Fi, bluetooth, sound, lasers, etc. Operated by real people and/or NPCs.

The Players/NPCs should have an environment which they live, and where they have personal possessions, garbage, social interactions, etc. In the world of hacking information is crucial, and it is not always obtained electronically. Some times you have to spy, eavesdrop, invade private property and look for clues, go trough somebody’s garbage to gain information, go to social media to gain insights about a person, impersonate trusted entities in real life or electronically, etc.

So, the Spycursion world should allow you to do physical hacking, tap lines, connect usb devices to servers or computers, set up wireless hot spots, intercept radio frequency, infra red, or other types of transmission media. It should also allow you to use public connections and code to intercept communications not intended for you and be able to use that information.

Each server should have speed limitations, and be limited in the number of connections it can keep alive, and should obey some rules on what to do with incomplete communications, disconnected clients, and other disruptions.

Finally, our citizens (some of them NPCs) should have the same type of vulnerabilities as real persons, use obvious password, leave unprotected ports opened, be vulnerable to phishing and social engineering. and make silly mistakes as leaving the computer unlocked and unattended, or send passwords in chats or phone conversations, etc.

An example, Man in the middle attack.

Real Life

There are several ways this can happen in real life, we will talk about one. When you connect to a hotspot on an airport or restaurant. You normally open turn on your Wi-Fi and start looking for hot spots and look for something that looks right, “theBurger-guests’ for example, what you are in effect doing is connecting to the Wi-Fi router which in turn connects to the internet. Now, most phones can be turned into a hotspot to allow you to use your phone carrier’s internet to connect to the internet from other devices (normally your laptop), it also allows you to change the predefined name so you could name it “spacecowboy” or whatever you want, and you can set up the security for it. So if I were to go to theBurger and rename my hotspot “theBurger-guests’ and make it insecure, anyone could connect to it. and in fact many people would, because they trust it is a Wi-Fi for the customers. Now you have all the internet traffic from the people who connected going through your phone, and if you have the right apps you could redirect them to wherever you want, or sniff their packets (since all the traffic is going through your phone you can see what is being sent and received for all the users, that is what we call sniffing). You can imagine you could do all sorts of malicious stuff then, like serving a custom page of your own when somebody asks for amazon.com, and try to trick them into giving you personal information under false pretenses, or try to add your own items into their shopping cart and change the delivery address, etc.

Spycursion

Now, in game if you have a device that can serve as a Wi-Fi hotspot, that could be simulated by a process that has a certain number of channels that can receive and send information, the game will know if a player or NPC is sufficiently close to it to discover it and/or connect to it. Imagine you want to spy on employees of a data center, and they normally go to the same coffee shop ‘AstroDollars’, then you could set up your device somewhere in the shop and have all packets dumped into a file that you can later analyze with your computer. You could write the “sniffer” and “analysis software” yourself, or get it in an in game store, either way is going to be “Slang”. Now since Spycursion is as much about defending as it is about attacking, then, knowing what you know, you would not be connecting to any random hotspot you find, but you also have a need to connect to the internet on the go, so you have to figure some countermeasures, you could for example use your laptop to send and received encrypted messages to your home computer, and have your computer be the one connected to the web site you want to reach, effectively acting as a tunnel, then anyone looking at those packets should be able to un-encrypt the traffic in order to see any info in it. Again, in game your computers are processes that can receive and send messages, in this case with a program that allows them to receive and send encrypted messages between them, these programs could have different types of encryption with different strengths, and demand on resources.



Designing a Video Game API

We’ve talked a bit about Spycursion and its open source model, but we haven’t really delved into how that will work from a practical standpoint. In this post I’ll talk about application programming interfaces, or API‘s, with the goal of helping you understand some of the decisions that go into designing an API for a multiplayer game like Spycursion. Please note, this information is intended for a more general audience, so many of the details have been simplified. This post is an introduction, not a reference manual!

What is an API?

An API is a set of rules and agreements, through which developers of various software components agree how those components will communicate. You can search the internet for API documents of all sorts to get a feel for what typically goes into those documents, but if you’ve never tried writing code for an API before (or writing code at all), you may get lost in the jargon.

Instead, let’s look at a simple real-world example…

Server: Hello, and welcome to Foodz R Us! Can I get you anything to drink?
You: Purple cow.
Server: Excuse me?
You: Purple cow.
Server: Err, I’m… sorry, we don’t have that on the menu. Would you like-
You: PURPLE COW!

When a server at a restaurant asks if you’d like anything to drink, they are usually expecting you to name something on the drink menu, or perhaps to ask a question. Here, though, you violated their expectations and the server’s “API” returned an “error.” (I personally have never seen “purple cow” on any drink menu, but if you do, let me know!) In computer-speak, this example could be converted to something like…

Server:

{ "request": "drink_choice" }

You:

{ "drink_choice": "purple_cow" }

Server:

{
  "error": "purple_cow not found",
  "drinks": [ "water", "tea", "milk", "juice", "beer" ]
}

{ "request": "drink_choice" }

You:

{ "drink_choice": "purple_cow" }

Server:

{
  "error": "purple_cow not found",
  "drinks": [ "water", "tea", "milk", "juice", "beer" ]
}

{ "request": "drink_choice" }

You:

{ "drink_choice": "purple_cow" }

Seasoned programmers will recognize that the messages above are in the popular JSON format. Certainly not all API’s use JSON (Spycursion’s does), but I will be using it throughout this post, for its simplicity and readability.

Movement

Just about every multiplayer video game will, at some point, involve you moving one or more characters from point A to point B on a game map. To keep things simple, let’s say our game map is a 2D grid made up of integer coordinates. (You know, the grids your high school Geometry teacher made you draw.) When you first start the game, you don’t necessarily know your character’s starting point, but the server should have that information, and so it lets your game client know:

{ "player_position": [ "x": 5, "y": -2 ] }

Now that the client and server are synced, you can move your character around the map. In a flat, boring world with no obstacles whatsoever, your client could just do something like this:

{ "move": [ "x": 3, "y": 1 ] }

But where’s the fun in that? In Spycursion, as in most other games, pathfinding may be required. Walking directly from A to B in a straight line might have you plowing through buildings or getting run over by a car! So the client, or the server, or both, will need to be able to navigate your character around obstacles. In practice, you would likely rely on the client for pathfinding, then convert that into API requests. If you as a player click the point (3,1), but there is an object in the way, the actual API requests might look like this:

{ "move": [ "x": 6, "y": -2 ] }
{ "move": [ "x": 6, "y": 1 ] }
{ "move": [ "x": 3, "y": 1 ] }

But what happens if a player hacks their client to just ignore those obstacles? What does the server do with a request that seems to defy the laws of physics? This is where collision detection comes into play, and any well-designed game server will include it. Basically, upon a player trying to run through a tree, the server sends a message to said player’s client…

{ "player_position": [ "x": 5, "y": -2 ] }

… as if to say, “Sorry, that thing is impermeable. You’re still at (5,-2).”

REST

No.

… Sorry, I should explain. REST stands for representational state transfer and is very often used in a sentence with “API.” Without getting into too many details, REST is an architectural style that is common among web API’s, and one of its more notable features is that the server does not store any client context between requests. In other words, every client request has all of the information that the server needs in order to process it. In a RESTful API, movement requests would look something like this:

{
  "from": [ "x": 5, "y": -2 ],
  "to": [ "x": 6, "y": -2 ]
}
{
  "from": [ "x": 6, "y": -2 ],
  "to": [ "x": 6, "y": 1 ]
}
{
  "from": [ "x": 6, "y": 1 ],
  "to": [ "x": 3, "y": 1 ]
}

A little verbose, but not terrible, right? Well, think about that little cheater with the hacked game client:

{
  "from": [ "x": 5, "y": -2 ],
  "to": [ "x": 3, "y": 1 ]
}
{
  "from": [ "x": 6, "y": -2 ],
  "to": [ "x": 4, "y": 7 ]
}
{
  "from": [ "x": 666, "y": 666 ],
  "to": [ "x": 666, "y": 666 ]
}

A stateless API would give the kid free reign to teleport around the game map! Naturally, this makes no sense for Spycursion, and you should treat any multiplayer game advertising a “REST API” with extreme skepticism.

Vision

I don’t believe we’ve talked about this, but here’s a new Spycursion tidbit for you — every player and NPC in the game has a vision cone. You can only see characters about 135 degrees in front of you (buildings and other stationary objects are always visible), so it matters which direction you’re facing. If you sneak up behind another player, they can’t see you without turning around. The API request to change where you’re facing is straightforward:

{ "look": 1.570795 }

You might recognize that number — yes, here are those Geometry nightmares again — as half of pi, telling the server that your character is now looking at pi/2 radians, or 180 degrees, which in this case just means “due south.” When you turn around, you might discover another player trying to sneak up on you, about which the server now sends a warning:

{
  "player_id": 66666,
  "player_position": [ "x": 5, "y": -3" ],
  "player_looking": 0
}

In reality, you wouldn’t be sent the opposing player’s actual ID (see below), but instead a lot of information about their appearance, and perhaps an indication that you’d encountered them before. Again, we’re keeping things simple here.

Interaction

Another MMO trope: Interacting with other characters. (I know, it’s awful.) In most games, if you wanted to converse with and/or hit on another character, your client might send a request like this:

{
  "action": "talk",
  "player_id": 66666,
  "message": "Hey, stop sneaking up on me."
}

And that’s all well and good, if your client has the player’s ID, which it probably does, as it was probably already sent by the server. Spycursion, though, is a bit different. We can’t tell you a given player’s actual ID or username, because of the possibility of disguises. (This is a spy game, after all!) If you knew that little Johnny’s player ID was 66666, and this fact was always shared by the server, then little Johnny could never truly fool you. Instead, we have to assign a temporary ID for every character who enters your vision cone. This is shared between client and server, until enough time has passed, or you leave the map, at which point you “forget what they looked like.”

If another player starts a conversation with you, your client gets a message like this:

{
  "player_id": 1234,
  "says": "I heard there was a new Spycursion blog post today!"
}

Other spy-like requests look similar, except of course the server doesn’t notify your client that someone has just planted a bug on you. 😉

Hacking

This post wouldn’t be complete without me talking about the API details behind what happens on your character’s computer screen. That said… there actually isn’t much to talk about! Spycursion’s in-game internet will offer many services which can essentially be divided into two types — “hackable” and “unhackable.” The “unhackable” services will have their own API specifications, while the “hackable” services will consist of in-game programs written in Slang. All of the Slang programs follow one simple API request:

{
  "command": "rm",
  "args": [ "-rf", "/" ],
  "target": "0123:4567:89ab:cdef:0123:4567:89ab:cdef",
  "session_key": "0123456789abcdef"
}

The target and session key are just for verification that you are logged into a remote host, and for allowing you to have multiple terminals running at once. That request includes every (non-client-specific) command you’ll run from the terminal, including network tools, the Slang compiler, and your programs themselves.

We haven’t fully decided which services will fall under which categories. Transparently, we would love every service to fall under the “hackable” category, but it’s just a question of feasibility and what we actually want players mucking around with.

 

Spycursion’s API documents aren’t yet ready for public release (and even if they were, the server isn’t ready for public release, so you wouldn’t be able to do much with them). In the meantime, hopefully this post has taught you a few things about video game API’s, and maybe even motivated you to design your own!



Anomaly Report #73 (CASSI 001)

From: Burdinjaun
To:                    

Subject: [TS//SCI] United States Armed Forces, Cyber Directorate — Possible Security Breach
Status: Investigation in Progress
Interviewer:                         , Military Investigator

Verifying… [100%]

Deciphering… [100%]

 


 

Interviewer: Please verbally express your consent to record this interview.

Tomás Lednura, PhD: I consent.

Interviewer: Can you summarize the facts of what happened on Oct. 24th, in the Annex B Conference Room 109, at 13:34?

Lednura: OK, as I recall it… Hmm, 17 people were summoned to the room due to an urgent security breach. 13 were there when the meeting started and the doors were closed. Four were high ranking officers, six were cybersecurity experts. The rest were CASSI developers.

Interviewer: For the record, CASSI is the Computer-Assisted Security Surveillance Intelligence. Do you recall all the names?

Lednura: You should have them in the written report I sent… (trails off) Jack from cyber security, my boss, called the meeting. I made the discovery of the information leak, and he restated what I had told him. At 13:01, one of the servers hosting CASSI started extracting data from the other servers and sending it to external sources. There were no known intrusions at the time, as verified by extensive malware checks. The data transfer processes were not spawned from a cron job or any other server configurations, and resisted all attempts to kill them. After getting everybody up to date on the situation, an engineer from the AI development team gave an assessment… (pause) Lisa, I think. Anyhow, she said that CASSI was only capable of monitoring communications and looking for possible national security threats. Any alarms would be relayed to a GUI in a room where some analyst would continue the work, and the system had no volition or any I/O capable of moving files or sending messages to the outside. I guess she could give you a better summary.

Interviewer: Sadly, we can’t ask her, nor anyone else. After the events of that day, one by one everyone in that room has died or disappeared. Except you, Dr. Lednura.

Lednura: What? How is that possible? I talked to Glenn a week ago!

Interviewer: Please stay on topic. We’ll talk about Mr. Lewis’ disappearance later. We need all the facts first.

Lednura: (sighs) I think those are all the facts any of us had prior to the meeting. During the meeting, we found that large amounts of data were being transferred. There was no rhyme or reason as far as security classification, but most of it was generated by CASSI processes. Like I said, every time we killed one of those processes a new one replaced it, and no other countermeasures worked, either. Gen. Miller asked for a summary; we told him what we knew and showed some evidence illustrating what was happening. That’s when I suggested taking the server offline, but there was a lot of debate about that. The CASSI guys were adamant that there was no way it could be responsible for the situation.

Interviewer: Was it?

Lednura: The evidence was inconclusive, but it was strong enough to suggest that turning off the server could stop the leak. I explained that, and Gen. Miller gave the OK to shut it down, even with the devs protesting about its state being corrupted, losing generations and all of that. As soon as he gave that order, the alarm went off, and the monitors showed the activation of something called Protocol Z14. I didn’t even know what Protocol Z14 was, I still don’t. But I distinctly remember hearing the big doors locking.

Interviewer: The big doors?

Lednura: That’s internal jargon for a complete lockdown, basically. Gen. Miller gave us this confused look and said that Protocol Z14 could not be activated without his OK. But we were all locked out of our systems.

Interviewer: Aside from that, did he reveal anything about the nature of the Z14 protocol?

Lednura: No, we’re all trained to avoid asking too many questions. But a voice recording sounding with the alarm said we had five minutes before the whole floor was incinerated, so we were frantically trying to override the security systems preventing us from getting out, or at least the ignition systems about to burn us alive. (sigh) But it was useless. After a few minutes we gave up and accepted our fate.

Interviewer: Just like that?

Lednura: What else could we do? We were in a concrete basement, with two-meter reinforced walls, a single exit sealed by a solid steel door, no working overrides, and a (expletive) incendiary bomb about to go off!

Interviewer: OK, and-

Lednura: Gen. Miller was starting to say something when the alarms ceased, and a green notification on the monitors signaled that Protocol Z14 had been suspended. Everybody was cheering, but the general just had that same confused or worried look on his face.

Interviewer: I can tell you this much: Protocol Z14 was designed to not be stopped, paused or suspended in any way. Once initiated, there is no way to stop it, by design.

Lednura: I guess that’s why he asked right afterward who had stopped it. We were all as puzzled as he was. Then a bunch of code appeared on my screen-

Interviewer: That’s enough, thank you. Now let’s talk about Mr. Lewis’ disappearance.

 

(click sound; end of recording)