What We’re Building (That Isn’t a Game)

Here at (defun games ()) HQ, we write a lot of posts about game development. This time, I’d like to take a step back and discuss (defun games ()) itself — the company we’re building, how we’re building it, and why.

If you pay much attention to the gaming industry, it’s hard to miss the complaints about “pay-to-win” microtransactions, rushed releases, and game developer burnout. These anti-features hurt the industry in the long term, and can only lead to disappointment for everyone involved. We believe there’s a better way to build a game studio:

We believe in big, hairy, audacious games. Plenty of well-meaning folks have advised indie studios like us to start off with simple platformers or clones of popular mobile games. AAA studios, meanwhile, are infamous for rehashing the same franchises ad nauseum. While those games might be easier and/or safer to make than a cyberespionage MMO, in my humble opinion, they’re a lot less satisfying — not only to make, but also to play! That’s why we’ve dedicated ourselves to what we call Big Hairy Audacious Games. Because at the end of the day, that’s what gives us, and our games, meaning. Speaking of which….

We believe that games can be more than just entertainment. For those who choose to use it as such, Spycursion will be as much an educational tool as a game. This is not an accident! So-called “serious games” are not new, but we believe that game developers (not to mention humanity) would benefit from helping to make them more common and more popular. This topic is worthy of its own post later on. For now, you’re probably wondering how we hope to accomplish all of this…

We believe in working smarter, not harder. By taking advantage of procedural generation and other secret alien technology, we can of course save time. But we don’t do that just so we can produce more games more quickly — we do it to preserve the sanity and work-life balance of everyone who works on Spycursion and other to-be-determined games. It would be all too easy to follow the broader societal trend of “do more with less,” but we believe the end results of that are flawed products and burnout. That’s another reason why…

We believe in releasing games when they’re ready. Most AAA studios announce their games’ release dates weeks or months in advance, usually timed for the late autumn or another similarly heavy game-buying season. This is a standard “best practice” for marketing throughout the industry, which would be all well and good, if not for the inevitable technical hurdles that are also prevalent all over the industry. So what happens when marketing and development disagree? Too often, the answer is: Crunch time! We believe, as above, that forced crunch time can only lead to flawed products and burnout. Our goal is to make games that are well worth the wait (Spycursion included!), and for our fans to know that they will be, in part because…

We believe that “winning” is a skill, not a price. Remember back in the days of video game arcades, putting quarters into machines in exchange for play time fragging/dunking on your friends? And do you remember how, if you put in more quarters than your friends, your characters would become faster and stronger and have better abilities? No, I don’t remember that either, because being able to pay for a gameplay advantage would suck all the fun out of any game. We believe in fair monetization schemes that reward strategic gameplay, not wallet size.

 

If you’ve read this far, hopefully this paints a picture of a game studio you’d like to support… or work with. If you happen to be in the market for a startup gig and would like to help us grow (defun games ()) into the studio it’s meant to become, take a peek at the Join Our Team page for more information.



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.



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.



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!



Spycursion and the News

I’d originally planned to pick a relevant news story and tie it to Spycursion somehow — “Hey look, you can steal Bitcoin too, here’s how you might do that,” etc., etc. But it turns out there were so many news stories that I couldn’t just choose one; that’s also why this month’s post is late. (That’s my excuse, and I’m stickin’ to it.) The plethora of cyberespionage-related news stories inspired another idea, which I’ll get to in a minute. As for the Spycursion update… I decided to go meta.

If you live in the United States, you’re probably aware of the allegations by the intelligence community against Russia for attempting to interfere in our 2016 (and 2018) elections. To the best of our knowledge, Russia didn’t do this by hacking voting machines — instead, they hacked our minds. They spread disinformation targeting both ends of the political spectrum in an attempt to divide Americans and sow chaos.

Consider where you get your news. If you’re like most people, you probably get a significant chunk of your news online, and a significant chunk of that from social media; the other largest news source, especially for older people, is TV.

Now, if you’re a disinformation specialist and you want to spread some salacious-but-obviously-false rumor, where do you go? The New York Times has over 130 million monthly readers, but that would be difficult to get into… pesky fact-checkers and all that. No, if your story is actually fake, no reputable news source would publish it (we hope) — you have to get in through a backdoor. One of those backdoors is social media. So you, being the sleazy fake news artist that you are, make a troll post on 4chan. Some legit-sounding but conveniently anonymous users “verify” it, and then some Twitter bots pick it up. From there, it spreads, with trolls fanning the flames and useful idiots spreading it around, and you’re off to the races.

There’s another backdoor, though, one that’s arguably even more insidious. This backdoor is mostly effective with stories that are half-true, or true, but with a particular spin on them… but it doesn’t have to be limited to those stories. The NYT alone has about 1300 employees. Let’s say you identify a shy young election reporter who made the rookie mistake of saving sexytime videos on her old, unpatched iPhone. Insta-blackmail! Now, her editors might catch anything too egregious you try to publish, but go up a couple of steps in the chain of command, and you could virtually guarantee the publishing of any semi-legitimate story that you want. And that’s not all! News organizations don’t just stick with their own stories, of course; they source from others. What gets published in the NYT also goes to Reuters, CNN, the gossipy lady down the street, etc. Congratulations! You’ve effectively blackmailed the entire media industry.

I don’t believe we’ve discussed it much, but we’ve designed a media system into Spycursion. It will be basic at first, like publishing stories about major hacks that players do, and other random events. The ability to blackmail journalists may come later. In order for that to be useful, you’d first need a good reason to do it — elections, stock market, laws, etc. All more advanced and ambitious features… but all incredibly awesome. 😉 You may even have the ability to play as a journalist, working for a news organization, deciding what stories to publish or not to publish… and being targeted by disinformation specialists.

Spycursion News Network

Now, for that other inspired idea: The Spycursion News Network! We will be sharing out real-world news stories about cybersecurity, espionage, and related topics, through this Twitter account. (The way things are going… we’ll probably post multiple times every day.) And yes, as the game and the media system progress, we’ll share some fake stories from within the world of Spycursion, too. For now, it’s all real, though. If you’re interested in these topics, give that account a follow!



Spycursion Update (May 1, 2019)

It’s been about a month since our Kickstarter campaign ended and we launched our Patreon page. As people who have watched exciting projects rise and fall — often without even saying goodbye — the last thing we want is to leave Spycursion dormant for months while our fans wonder what happened to it and if we will ever return. (If Spycursion ever does fall into the bit bucket of history, it won’t be because we ghosted you — it will be because we went out in a blaze of glory.) To that end, our goal is to share a progress update roughly once every month, even in months where not a whole lot has happened…

… like this one! As I hinted in the last post, both Mauricio and I have had to “take some time off” to focus on useless trivialities like, say, paying the electric bill. Aside from that, we’ve been zooming out a bit to discuss the Spycursion architecture and how to tackle a development roadmap in our new post-Kickstarter world.

Ooh, Shiny!

Can I be honest? You know all those parts of the game that you’ve probably seen from our trailer? Those are my least favorite parts. The parts of Spycursion that I enjoy talking about and sharing the most are, well… the parts you can’t see. There are good reasons for that. Spycursion was never meant to be a graphics-first game, and in fact, I hadn’t even planned on making it 3D! My original vision of Spycursion was as a 2D isometric world. It evolved into 3D throughout the process of development and commissioning assets, as we decided that 3D would allow for greater flexibility in terms of feature additions and look-and-feel modifications.

But really, we should go back even further. In July 2018, we published this post containing the very first public Spycursion screenshots (with the exception of this very, very early device UI screenshot, in Nov. 2017). At that point, the game had been in development for nearly a year. We hadn’t shared screenshots because we weren’t focused on anything that could be screenshotted. Then, we read pieces from some wise(?) internet denizens who told us that, in order to have a successful Kickstarter campaign, we would have to make shiny things and show them off and generally become glued to social media. (Anyone who’s ever worked on an indie game knows where this is going.)

Hence, our focus shifted from server to client, and more or less remained there until the Kickstarter launch. I don’t know whether this was ultimately the right decision, but I do know that not focusing on the client certainly wouldn’t have helped that campaign. In any event, I personally feel that the visuals in Spycursion’s trailer turned out well, but not as well as they could have. There was a degree of crunch in the weeks and months leading up to February, and as a result I didn’t feel we were able to give the client the polish it deserves. That’s why one of our first post-Kickstarter discussions was about…

(Shiny) Client Architecture

If you’ve followed our blog, you know that the Spycursion client relies heavily on a couple of Common Lisp frameworks — CEPL and QTools. What you might not realize is that, within our code base, these two frameworks never even touch each other. It’s almost as if we have two separate clients that just happen to have the same name. That makes some sense, of course, because they have very different purposes. But let’s say that we want to display a device UI (a Qt QMDIArea, if you’re fancy) partially overlaid on top of that 3D world, rather than in a completely separate window. I’m not sure there’s a good solution to that. (QtOpenGL comes the closest, but we dismissed that because it would be difficult to use with CEPL or other GL frameworks, plus it had some problems on OS X.) Qt also adds some bloat that we’d rather not have.

Though we’ve discussed it before, without the time pressure of Kickstarter, we’ve decided to begin replacing QTools now. And that replacement will be… Nuklear! Why Nuklear? Well, for starters, look at these two screenshots and tell me which one fits better in a game about cyberespionage. (Yeah, I thought so.) In seriousness, what’s attractive about Nuklear is that it’s simple and embeddable, and doesn’t try to take over your entire application.

Now, the astute and tech-savvy reader may be thinking, “Wait, Nuklear is written in C, not Lisp… does it have any Lisp bindings?” Well, yes, yes it does! We’ve decided to give cl-bodge a shot, specifically the UI module, and see if we can make a workable device UI out of it. Another potential benefit here is that we could get away from traditional desktop UI paradigms of the sort enforced by Qt, and design something more unique. It’s too early to know what that might look like, but I’m excited about the possibility.

If cl-bodge works well for us on the UI, we may also use other modules of it for other purposes. It is possible that we will eventually replace CEPL, but I think the more likely outcome is that we blend the two, taking advantage of cl-bodge where it makes sense and working with CEPL as a friendlier alternative to raw OpenGL (cl-opengl).

More Shiny?

Between paying the bills and replacing QTools (not to mention me having a strong desire to hide back in my server code), it may be awhile before we can share more screenshots of any quality. It will definitely be awhile before we share more videos. When we do, we’ll try to include some upgrades to the 3D world, as well. We picked up a fair amount of technical debt during pre-Kickstarter crunch time, so performance improvements are definitely in order. With performance improvements, we can add more “bling bling” (to use the words of an influencer who didn’t want to share Spycursion because it didn’t have enough of that). And if we get enough funds through Patreon, we could add new 3D art as well.

What Kind of Shiny Would You Like to See?

As always, we invite our Patrons and followers to help shape not only Spycursion itself, but how we share it with you. What do you think about the technical changes outlined above? What do you want to read about in future updates? What would you like to see on our Patreon page?

Let us know!



Out With the Old, In With the New

The Launch

On Feb. 26, we launched our Kickstarter campaign in the hopes of funding the rest of Spycursion’s development. Our spirits were high (even if our energy levels weren’t), we hit 2% funding within a few hours, but most of all, we were just excited for our studio to move into a new phase of its life. We had lined up PR contacts and were running a really clever — perhaps too clever — marketing campaign. At that point, all we had to do is wait for the inevitable surge in backers.

Early Bird

Admittedly, we should have seen the signs. By Day 3 I was beginning to, but to be completely honest, I spent most of the first three days of our campaign so exhausted from the preparation of it that I could do little else but refresh social media feeds and ask Mauricio why more backers weren’t coming in. The press weren’t responding to us in nearly enough volume, our ad campaign was a total flop, and our mailing list on its own wasn’t large enough to drive the early traffic we needed. We had focused all of our energy on that 72-hour period, and it netted us a whopping 4% funding. I was about to call a pow-wow with Mauricio and Dan to figure out how we could save this floundering campaign. Until…

CRACK!

Did you hear that? That was the sound of my wife breaking her wrist (in a very complicated and interesting fashion, she says). So, yes, I spent much of the next week focusing on her rather than our Kickstarter campaign.

The Doldrums

By the time I got back into things, our campaign hadn’t advanced much further and we all agreed that it was more or less doomed. That’s when we made the decision to move to Patreon and shared this update on the Kickstarter page. Since that update, Mauricio and I have been working on said Patreon page, discussing our new development plans… and looking for jobs. C’est la vie.

The Future!

As you may have already gathered, development on Spycursion will continue! It will be at a slower pace, no doubt. We almost certainly won’t be able to hit the Q4 2020 goal that were aiming for with the Kickstarter campaign. On the upside, if we can get our sustainable funding situation worked out, then you’ll have happier, less stressed-out devs working on the game — which means greater productivity and fewer bugs!

For now, we’ve launched a Patreon page to serve as both a funding boost and a barometer of how our fans are feeling about the game. Right now, our membership tiers are very simple: For every month that you back us, for an amount of your choice (more on that in a minute), you get one month of Spycursion gameplay after it’s released. We will certainly add more tiers, and possibly raise the minimum price tier, as time goes on. For now, we’d just like to know what our supporters want in terms of rewards. Let us know if you have reward ideas or other thoughts on our Patreon page!

In diagnosing the non-success of our Kickstarter campaign, one of the conclusions we reached is that the pricing and value we offered didn’t line up. Our pricing was based on a fuller, more polished version of Spycursion that we had in our heads — rather than reflecting the presentation that we were able to showcase at this stage of development. People don’t see what’s in our heads, they only see what we can show them, and what we could show them didn’t justify the price points. (And yet, it clearly did, for those who backed us. A friend pointed out that some backers were willing to pledge over $200 for a game that’s 18+ months away! That’s certainly not nothing!)

This is why the “pay what you want” model we’ve adopted on Patreon is key. We’d like our supporters to think carefully about what they see, what we’ve shared, and our own capabilities, to decide what a month of Spycursion is worth to them… and then tell us! At this point, we’re expecting a lot of $1/month backers, and that’s perfectly fine. Over time, we hope to earn more supporters and more trust. The nice thing about Patreon is that we don’t have to get everything right at the beginning; our fans can help us over a longer time period in molding Spycursion into what they’d like it to be. We hope you will join us on this journey!



The Spirit of Kickstarter

Kickstarter has changed a lot over the years. Observe this video game project from 2012… and then observe this one from 2018.

Go on. I’ll wait.

In 2012, a tiny independent game studio could launch a campaign without so much as a video trailer and net $150,000 in funding. Meanwhile, in 2018, established studios learned they could repackage their old releases, toss them onto Kickstarter with some collectors’ items, and fund a successful campaign literally overnight.

Don’t get me wrong, I loved the Myst games. But I can’t help but feel that’s not really what Kickstarter is for, ya know?

Some people have told me that we shouldn’t be launching a Kickstarter campaign. “You aren’t a big studio with an established audience.” “Your graphics aren’t very good yet.” “You don’t have gobs of marketing dollars.” All of those things are true. I certainly wish inspiration had struck back in 2012, when those weren’t necessities — we might have surged past our funding goal a long time ago.

But instead of looking at the cards we weren’t dealt, let’s look at the ones we were:

  • An innovative concept in an underserved niche. I truly believe that enough people exist who would be excited enough about Spycursion to back it, as long as we are able to find that audience. (Not always an easy task!) When and where we have found that audience, we’ve received a lot of praise. (And a handful of naysayers, usually related to one of the “cards we weren’t dealt” above.)
  • Secret alien technology. We haven’t played up Lisp too much as an advantage, partly because it’s still largely uncharted territory for game development. But both Mauricio and I have often been surprised by how easy it makes certain things. If When Spycursion happens, I won’t say it was only because of our choice of programming language… but I will say that that choice probably helped.
  • A small, but enthusiastic, fan base. That’s you! And, it turns out, you may be the most important part of this whole equation…

It’s important to realize that indie studios like us are no longer competing against the likes of Starlight Inception for visibility on Kickstarter. We’re competing against Myst, and if we try to compete on traditional grounds, we’ll get creamed every time. We’ve done our best so far to put those first two advantages above to good use, but the third one is mostly out of our hands. That’s where you come in.

And yes, this is the part of the blog post where we shamelessly ask you to share Spycursion with all of your family, friends, enemies, acquaintances, ex-lovers, and every random person with whom you make eye contact but don’t click the Back button yet because there are good reasons why you should do so!

If you’ve spent any amount of time browsing Kickstarter, you’ve probably seen those projects from very non-startup companies with high-budget videos and suspiciously low funding goals. You know, the ones using spammy crowdfunding agencies, the ones that make you think to yourself: “This entire campaign is solely for publicity, isn’t it?”

Well, we’re the antithesis of that. We’re just a couple of people with some ideas and skills who came together to bring a game to life. As a brand new, zero-budget studio, we’re using Kickstarter for its original intended purpose — to “kickstart” a creative project! Kickstarter is, and always has been, our Plan A. (There are contingency plans — all of which have significant downsides — but those are better off in another post.) Sadly, that also means we’re facing some headwinds that we arguably shouldn’t have to face. That’s why your support (financial and/or social) is crucial to our success.

Do you love the concept of Spycursion and the long-term vision we have for it? Splendid! Share. This. Game.

Do you love the concept of Spycursion but hate how the graphics look right now? Excellent! Share. This. Game. With the support of you and all your family/friends/enemies/etc., we can afford some better art and all of the graphical bling-bling you can handle.

Do you love the concept of Spycursion but are skeptical that we can actually pull it off? Glad to hear it! Share. This. Game. With the enough support, we will pull it off, and if for some reason we don’t, we’ll be open-sourcing the whole shebang for you to try pulling it off yourself. (See the “Risks and Challenges” section of our Kickstarter page.)

Do you hate the concept of Spycursion altogether? Cool beans! Share. This. Game. You never know who else might enjoy it in your stead.

Did you come from /r/lisp or Hacker News and you just want a Lisp game to point to when people trash your favorite language? Superb! Share. This. Game.

Share our Kickstarter page. Share our trailer. Share this blog post. Share it on Facebook. Share it on Twitter. Share it on Reddit, or Mastodon, or Pinterest, or whatever your favorite social networks are. Share it on 4chan just kidding please don’t do that. Share it on your blog. Share it on a postcard. Share it at parties. Share it especially with people you know who happen to be in media and/or very rich. Share. This. Game.

With enough sharing (and broken records), we can bring Spycursion to life. That, in my opinion, is what the spirit of Kickstarter is all about. Thank you for your support!





Creating a (Non-Trivial) Lisp Game in 2018

Lisp programmers are a small group. According to the TIOBE index, Lisp currently sits at #32 on their ranking of programming language popularity. (Common Lisp specifically is somewhere between 51 and 100.) You can certainly imagine that Lisp game programmers are an even smaller group. And then when you consider non-trivial games, the games made by teams, the ones that are significant enough in scope to potentially fund the studio building them… well, I don’t think it’s much of a leap to say that you can probably count the number of those games on one hand.

Suffice it to say that not a whole lot has been written on the art of developing games in Lisp, relative to other languages. As a leader of one of the aforementioned five-or-fewer teams building a sizeable Lisp game (Common Lisp, in our case), I want to contribute to that collective knowledge base. But first, a caveat: It would be premature to consider either (defun games ()), as a studio, or myself, personally, as any kind of “authoritative voice” in the Lisp game community. Spycursion is the first game that we as a studio are producing, and it hasn’t even been funded yet. (Hint hint, Kickstarter, Feb. 26, hint hint!) And although I was a hobbyist Common Lisp developer for about seven years before starting work on Spycursion last year, there’s still a lot about this language I don’t know, and there are certainly people who could write better/faster Lisp game code than me… I’m just the only one who was insane enough to start this project. 😉 We also recently picked up another developer (he hasn’t introduced himself yet, but he will) whose opinions may differ from mine. Taken altogether, what I’m trying to say is: I’m not a guru. I’m just one guy trying to find his way on this bizarre-yet-beautiful landscape, just like everyone else!

Aaaanyway, Lisp games. The first thing you should know, before you go tell all your friends “Hey, they wrote Spycursion in Lisp, let’s create our Overwatch/Pokemon/Dark Souls cross-over in Lisp, too!” is that Spycursion is weird. The game itself is weird, its architecture is weird, its developers are weird… Point is, we’re working with some parameters that make Lisp not only suitable for Spycursion, but perhaps even the ideal language for it. Your Overwatch/Pokemon/Dark Souls cross-over may not fit the bill. (Or it may. I’ll let you know after we release Game #2.) It’s also important to remember that Spycursion has a client and a server component, both of which are written in CL. This was not always the case for the client; I’ll share that story in a minute. But let’s talk about the server first.

As we’ve mentioned before, Spycursion has its own programming language. You may have read about how domain-specific languages (DSL’s) in Lisp are grand, how they’ll make your coffee for you, blah blah blah. In my experience, a lot of the conversation about this can get pretty academic, but here’s a summary of what happens when you compile and run a Slang program in the world of Spycursion:

1. Compilation: The server parses your program (assuming it is syntactically correct) and creates a tree of Lisp forms from it.
2. Runtime: Some contextualization happens with that tree of Lisp forms, and then it is evaluated within the context of an in-game device.
3. (Optional): If the program needs to communicate with another program on another in-game device, via in-game network, then some magic happens to determine where that program is, and runs it, too.

This is of course a lot more complicated than I’m making it sound, but it’s still far less complicated than in probably most, if not all, other mainstream languages. Lisp allows you, as a player, to run your own code within someone else’s online game. (And yes, we do run security checks on your code before we parse it. We’re not n00bs, thankyouverymuch.) This is not merely simulated. There are plenty of places within Spycursion where we “cheat” to make things easier on ourselves — hey, we’re an indie, cut us some slack — but Slang is not one of those places. Just thinking about trying to do all of this in C++ gives me an icky feeling. (I eagerly await the e-mail from someone telling me how you can do it in C++, if you just jump through these 27 hoops…)

So, yes, Lisp is awesome as a game server, but I have a feeling that’s not what most of you are here for. You want to know why we’re using Lisp for the Spycursion client, and how you can write your own amazing thing in Lisp too, and clearly the answers are because I’m insane and you should stop listening to me because it’s fun, dadgum it, and by being a masochist early adopter and maybe having a fairly simple game, graphically. Sarcasm aside, these questions deserve longer answers:

Why Lisp (for the client)? Okay, story time. Long, long ago, when the Spycursion server was just Slang and a WebSocket interface and not much else, I set about creating a text-only testing client. I did this in Python, figuring it would be relatively quick and easy, which it was. At this point I’d not completely decided on how the client would be implemented, but I reasoned that, despite Python not being my best language, it would be easy to find developers for — so I could handle doing all the server-side Lisp as long as I had someone else dedicated to the client.

But there was a problem: Writing in Python just wasn’t fun. Some of you may not understand this, but it’s a phenomenon I’ve heard about before — once you get “spoiled” by Lisp, you have trouble getting motivated to code in any other “lesser” language. This was before we existed as a studio, when I was doing this project entirely by myself, so I didn’t have anyone else to shove the Python work off to, but I knew it was important to get something visual produced so that I could begin to show people (not simply tell them) what Spycursion was about.

So I chucked the Python client, rewrote the thing in CL, and around that time, started getting ideas of what I felt this fledgling studio could be. In my opinion, the reasons “nobody programs in Lisp” mostly boil down to, well… because “nobody programs in Lisp.” The community is small, so there are few tools available, so the community doesn’t grow because people don’t use Lisp for major projects due to a lack of tools. This is even more true for Lisp games specifically, but I believe that this chicken-and-egg problem can be helped by creating a well-known game in Lisp, if only to point to it as a success and prove that it can be done. Additionally, by open-sourcing the client code (which we’ve not done yet, mostly due to legal questions that need answering), we show new and aspiring Lispers how it can be done. Again, to avoid getting ahead of ourselves — this thing could still fail, perhaps in spectacular fashion. But at least if it does, you’ll get a front-row seat. 😉 And I guarantee you that it won’t be because of the programming language we chose.

Why do you think it will work? As I mentioned before, Spycursion is weird. There are very experienced people within the Lisp community who think that Lisp, in its current state, is not ready for serious game programming. I have no basis on which to disagree with them, but I do think it depends on the type of game you’re creating. Spycursion has several things going for it that make it different from what you might imagine as a “typical game,” especially a AAA game:

  • There’s no twitch action. An ill-timed garbage collection isn’t going to be the difference between life and death. As of yet, we’ve made no attempt to customize GC or really push for low-level performance in ways that might be challenging to do in Lisp. We might, at some point, but I’m guessing we won’t even need to.
  • Much of the tricky stuff is offloaded to the server. Don’t underestimate the advantage of having a server (read: one single platform, of your choice) running parts of your game. That means fewer shared library headaches and fewer client performance woes — assuming you do everything asynchronously — for starters. (Oh, but please don’t be that developer who forces a network connection for your single-player game. That’s just rude.)
  • We don’t need to build for consoles. Ever tried to run Lisp on the Switch? I haven’t… and I don’t want to.
  • Physics? We don’t need no stinkin’ physics. Or at least no physics that can’t be calculated based solely on what I remember from 9th grade Geometry.
  • We keep graphics simple. I don’t really know how to quantify that, but the game is meant to be played 3rd-person, from a distanced zoom level. (We let you zoom in, but I wouldn’t necessarily recommend it.) The assets will be relatively low-poly and there will be relatively few of them. Note that “simple” does not mean ugly. We’re aiming to make it all look good while still putting most of our effort into gameplay — graphics are one of the places we “cheat.” You’ll be able to judge how we’re doing once we finish the Kickstarter trailer.

Put all of the above together, and you get a picture of a fairly minimalistic game client that really gets out of the way and lets you enjoy playing. (Or at least that’s the picture I hope you get!) And to be clear, I am not saying that fancier, AAA-level games can’t be made with Lisp. I’m saying I really don’t know, but this is our attempt to get as close as we can with the resources we have.

How are you doing it? I would say “pain, sweat, and toil,” but that kind of describes all game development, so…

  • The engine. Oh, just kidding, we aren’t using one. In 2018, I know of at least three Common Lisp 3D game engines in varying stages of development: First Light, Trial, and cl-bodge. In 2017, when I was researching these engines, they were all either too early in development or otherwise just didn’t fit our needs. They might now, but I haven’t followed their progress enough to know for sure. This brings me to what is maybe the most important thing to know if you’re looking to write a non-trivial Lisp game in 2018: You have to be okay with writing a lot of things yourself. Lisp makes this fun to do, and might still even save you time overall depending on just how much you need to write. But it’s a very different mindset from being, say, a plug-and-play JavaScript developer.
  • CEPL. CEPL is an abstraction layer around OpenGL which has been a joy to work with, once I figured out how. (Tip: See the author’s video stream, it’s great.) Its goal seems to be to make OpenGL lispy and fun to work with, and I really think it has achieved that. Spycursion uses CEPL extensively, and while I’m sure we’re doing some things suboptimally, performance has been fine so far. We’re also using cepl.sdl2 which brings in cl-sdl2.
  • QTools. QTools is a lispy wrapper around Qt 4. Most games probably won’t want the heft of Qt, but our device UI actually needs something a bit more featureful, so it’s worth mentioning. We have run into some build problems with QTools, particularly on Linux. Add in that there doesn’t seem to be a Qt5 update on the horizon, and we may well end up switching away from it (to what, I can’t say yet). But it’s currently working well, for what we need it for.
  • Other libraries

And that’s it! Lisp game development isn’t for everyone, but I stand by my assertion that it can be done, and done well, given the right game — and perhaps the right amount of patience.

TL;DR:

  • Use CEPL. Or one of the engines, if they fit. Or maybe both.
  • Yes, you should do it, even if you fail. That’s how the community grows.
  • Be prepared to write a lot of stuff yourself. This is not necessarily a bad thing. It’s fun!
    • Except skeletal animation. Don’t write that yourself.
  • Support our Kickstarter starting on February 26th!