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 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

 



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!



Some things we’ve learned developing a 3D game for Lisp.

Hi, Mauricio Here,

This blog post is kind of a developers blog, as I said in my only previous post I’ve been dealing with the MS Windows side of things, I also made some 3D models using Blender, and use the abstractions Scott had created to create a a new scene for the game (a bedroom), but of course my job has not been limited to that. We’ve learned some stuff that we would like to share, so that is what I am doing.

Classimp on Windows.

One of the earlier lessons we learned was related to Assimp, for one thing downloading the binaries and moving the dll to your project directory does not work, in recent Assimp versions the name of the dll isn’t even one of the names searched by Classimp, and renaming or making the code match the dll name does not do the trick. In order to make classimp work we had to compile with gcc instead of visual c, using mingw,, this produces a libassimp.dll which is what classimp looks for and that DLL works fine. The latest Assimp library supported by Classimp is 3.3.1, so if you want to compile it yourself download that version and then follow the instructions here.

When you compile with MingGW using the instructions in the link the DLL will be in the “assimp-3.3.1\build\tools\assimp_cmd” directory, and asides from that you get an assimp.exe executable that is very useful for asset conversion. Currently we are consuming fbx files, so when I created models in Blender I exported them as fbx files, and that caused problems in some cases, so we adopted a different  workflow which so far guarantees a model that loads correctly in CEPL, we use assimp.exe in the command line to convert the .blend to .dae which is the extension for Collada, an open exchange format, and then use Autodesk FBX Converter to convert the .dae to .fbx. This workflow gives you better control over the way that the files are converted.

Why not reading the .blend files directly?, Well for one thing we had some pre-made assets and those were fbx, and we want to be uniform., another reason is that sometimes the file would not be read correctly by classimp, but assimp.exe tries several stuff and is able to export it, as long as you remove any lamps form the scene (I also remove the cameras for good measure). And a third reason, is that sometimes we want to pre-transform the vertices  specially with several objects in the same file, and doing this during the export simplifies the code to read the file. So we do use this:

assimp export file.blend  file.dae -ptv

In the command line, where -ptv stands for pre-transform vertices, and assimp guesses the output file format from the extension of the second file. Assimp does not export fbx , that is why we export to ,dae and then convert. Classimp can read .dae files correctly, but fbx files are smaller, and the difference in load time is negligible for our purposes, and as I said we want to keep uniformity.

Another good tip is to use the assimp viewer to open an asset, and then look at the log file, this will warn you of possible problems when importing with classimp.

Multiple Textures in one Mesh.

We ran into a problem with a model of an avatar we were using in the game, the textures were not imported correctly, the head texture was applied to the body, so the model looked like it had no pants, and it had some weird things in the skin (actually stretched head features). The problem is that when you run (classimp:import-into-lisp) each mesh object contains only one texture. however the model had a mesh with two textures.

Luckily Blender allows you to select the portion of the mesh that is assigned to a particular texture and separate it. So we separated the head from the body, re exported, re-sorted the textures and voila, problem solved.

How do you know the order of the meshes? Well, the first thing is to name things right in Blender, then the structure you get when you import into lisp has a tree and that gives you the clue.

SPYCURSION-CLIENT> (ai:import-into-lisp (car *char8-data*))
#<CLASSIMP:SCENE {100A0E4AE3}>
SPYCURSION-CLIENT> (ai:root-node *)
#<CLASSIMP:NODE {1004FA9443}>
SPYCURSION-CLIENT> (ai:children *)
#(#<CLASSIMP:NODE {1004FA8663}> #<CLASSIMP:NODE {1004FA8903}>
  #<CLASSIMP:NODE {1004FA8B93}> #<CLASSIMP:NODE {1004FA8E33}>
  #<CLASSIMP:NODE {1004FA90D3}> #<CLASSIMP:NODE {1004FA9373}>)
SPYCURSION-CLIENT> (loop for x across * collect (ai:name x))
("Head" "Gadget" "Bag" "Body" "Jacket" "Hair")
SPYCURSION-CLIENT>

So the first mesh is the head, the second the Gadget, and so on. The pre existing textures worked well because I just separated and saved again so the UV coordinates remain intact,  now each mesh reads from the right image, and maps the right coordinates.

Blender

One of the models I was making was a full room, to do it I used Archimesh, the room was simple, a rectangular room with a window and a door,  and some cabinets, this worked out perfectly in Blender, but not so much when I imported the models in CEPL. The thing is that boolean operators produce weird geometry, and the holes in the walls for the door and window are produced by boolean subtraction. In other models the sub surface modifiers looked like crap when imported,

So I decided to re-make the room the old fashioned way, loop-cuts and face deletion, replace the old room, and apply all of the modifiers to other objects before exporting, that way the look was predictable.

The other thing I learned is that you need to either use the a processing flag in classimp or export the model with pre-transformed vertices, otherwise the objects in the scene were not placed in the right position. I used Blender to lay out the room furniture, and then exported each element separately, that made it easier to place and remove things, and handle the textures.

I also spend some time baking textures, and exporting the UVs, the UVs exported from Blender are immediately usable, and you can use DIRT to import the texture, so asides from the tedious process of UV wrapping the objects, assigning the image, and baking the textures into it, the process is very painless.

Final Thoughts

After ironing out the exporting problems saving models so they can be used with CEPL turns out to be a straight away process, there are some things in our code we are optimizing to make the process of maintaining the software and adding stuff more straight forward, but we have a working skeleton,  we can create rooms and cities, place avatars, animate them,  etc.

Of course there is still work to do, and Spycursion is curious in that it has two environments, the OS and the 3D world, but even when we some times hit ourselves against a wall, there is always a door a couple of steps away, as we learn more is like turning the lights on, we now where the walls doors, windows and other stuff is, and that allows us to move freely.



Our Kickstarter Launches February 26th!

We’re excited to remind you that our Kickstarter launches February 26th!

We’ll share the pre-launch page with you when we’re ready, but we’re looking for $100,000 to help us get Spycursion off the ground.

We’ve got some exciting backer rewards planned, so we hope you’re hyped!

For more information on our plans for Kickstarter, see here.

Check out our trailer if you haven’t already for an idea of what Spycursion is all about.

Don’t forget to follow our Twitter to keep up with what we’re up to!

What is Spycursion?

We’re glad you asked! Spycursion is our “edutainment” hacking MMO that aims to teach players how to hack and code. We want to get people more invested in the world of programming.

Spycursion may be educational in nature, but it’s as much a game as a learning tool. Expect more details on the MMORPG aspect of the game in the future!



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!