Project Overview: perfectstorm

| | Comments (29)

with-health-bars.png

perfectstorm is a real time strategy game study written in common lisp using OpenGL for graphics display and cairo for texture generation. It is in active development with many of the basic features still unimplemented, but i decided the effort put into it justifies some public documentation.

Why

I started perfectstorm because i was annoyed with the Artificial Intelligence offered in most commercial RTS games. Although significant academic research is going on, it seldom finds its way into released games due to publishers’ wishes for absolute stability of the “gameplay experience” and the notion of AI as just being responsible for pathfinding plus something. Naturally, AI development can only begin late in the development cycle when the deadline is nearing. The most pressing feature the single “AI guy” most teams employ has to do is implementing pathfinding, which is not even part of AI if you want to see it that way. After that, only a poor makeshift enemy AI can be implemented before the product is shipped. Aside from that, writing good AI is hard. Or so i heard.

Most of the academic AI research going on seems to be tested on ORTS , which seems to be decent and alive. Since i wanted to learn about general game coding and graphics development i decided not to use ORTS and write my own. And of course, i wanted to use lisp since i had not done a serious project with lisp and wanted to test its capability (and mine) to cope with heavy library interaction and larger real-world projects. The name “perfect storm” is a metaphor used to denote the interaction of several different parts to maximum overall effect, something i want both my RTS units and my code to perform :)

Details

For graphics, i first tested SDL, the 2D part of which turned out not to be hardware-acceleratable under X11. OpenGL was the only alternative and — thanks to the excellent cl-opengl bindings — is very easy and fun to use. Now i needed textures and decided i wanted a defcon-like slick minimalist-but-pleasing look. No complex models or realism was needed, so i figured drawing nice antialiased primitives and gradients would be enough and settled for cairo. While cairo is certainly not fast enough for drawing life animations, it produces very nice output and is reasonably easy to use, although the cl-cairo bindings are a pain (i hear that with cl-cairo2 and cl-cairo-cffi two alternatives have emerged). After spending quite some time setting everything up and finally successfully extracting pixel data from cairo i started defining first units and implementing dummy game mechanics and graphics.

Status

Since then, the game has grown and, with the developer count rapidly soaring up to two, includes the following features:

  • User-definable units and weapons that can be plugged together
  • Object-oriented very open design
  • Some 20 different textures, with the possibility to add more very easily
  • Fragment shaders for nice glows and flickering laser beams
  • Pathfinding
  • In-game developer console (aka REPL)

Future Plans

In the near future, i’d like to see the following things:

  • Steering behaviours for units (currently work in progress)
  • A first easily replaceable resource scheme
  • Buildings
  • More verbose GUI
  • Dummy ai for first playtesting

You are welcome to try it and play around if you like, or even contribute something.

Currently, the svn version is not guaranteed to be in any usable state or even to compile. Since we are more or less concentrating on one feature at the time, it is likely you will see some debug output concering the current development focus when just starting it. Dependencies are listed in the README file. You can check it out from svn://erleuchtet.org/perfectstorm. You will need both the cairo and OpenGL bindings from the same svn repo since i added some features that are needed by perfectstorm.

But beware! the current state is not that presentable: you’ll just see pathfinding debug output at the moment. When a first dummy is playable and the code is cleaned up a bit we’ll make a project page.

Screenshots

pathfinding.png

land_vs_air.png

shader-on.png

shader-off.png

29 Comments

This looks great! I can't wait to try it.

What you are basing your impression of the current state of AI in the games industry on? There seems to be a lot of very interesting talks on AI every year at the GDC, and they are rarely about pathfinding. Why do you think there is only one AI programmer per studio, and they can only begin late in development?

I wrote cl-cairo2, and still maintain it as I use it on a daily basis. You might want to take a look, it is pretty stable and has a tutorial to get you started. There is no explicit code for xlib image surfaces/contexts, the current one is embedded in a small scale interface with a threaded event loop that allows you to draw into an X11 window, but it is just a few lines to write (contact me if you need it).

It looks cool, but unfortunately I'm not able to get cl-opengl-thomas to compile on my Mac OS X w/ sbcl 1.0.15.

It seems to have some troubles with the ensure-integer type:
; caught STYLE-WARNING:
; can't find type for specializer ENSURE-INTEGER in
; SB-PCL::PARAMETER-SPECIALIZER-DECLARATION-IN-DEFMETHOD.


and finally blows up at

(defctype int ensure-integer)

any ideas?

Greg:
You might have to use cffi-newtypes instead of cffi.
After this you might be running into more problems with OpenGL on OSX. In this case look at http://www.esden.net/blog/ for a solution.

Austin:
You will have to wait a little longer or get your hands dirty yourself if you want to try a playable version :)

I'm basing my impression on several articles i read on gamedev and similar sites. While the number of only "one AI guy" might have been slightly exaggerated, the overall impression of AI being neglected seemed to be agreed on by several authors (I can't find the actual articles right now). I have no first-hand experience in the business, though.

I can't seem to get the toolbox repo, it gives me a 404. Perhaps there is a typo in the README?

Hi!

After downloading and setting up all the packages (i.e. making *.asd files symlinks) I started sbcl and tried to load the game: (asdf:oos 'asdf:load-op :perfectstorm).

Here is what I've got:

The path
#P"/var/cache/common-lisp-controller/1000....../cl-cairo/Drawing/cairo_t.fasl"
does not exist.

Some *.asd files missing?
Any other ideas?

Regards,

Yuri

Yes you do require cffi-newtypes. The game starts fine but is slow due to my video card (on-board piece of junk). I tried to package it up and make it an executable and it's 30M which is pretty good. Unfortunately I get the following error when trying to use it:

omouse-perfectstorm> ./perfectstorm.image
freeglut  ERROR:  Function  called without first calling 'glutInit'.

I created the image using

(sb-ext:save-lisp-and-die "perfectstorm.image" :toplevel #'storm:storm :executable t)

I get a lot of errors like this when I do the asdf-loadop:

There is no class named ENSURE-INTEGER.

What am I missing?

Wow, that is great. Simplicity is really beautiful. I can't wait until this is usable enough to play.

Sweet, I like the look. I'll pull from svn and see what I can get working as soon as I get home. I hope you don't mind my peeking though to see how you've got things working so far, I'm working on a simple turn based game right now that focuses heavily on AI.

@Rudolf: it seems you need to create an extra init function to be called on the image's startup. What's happening is that the gl bindings do a proper gl(ut) initialisation on load, but apparently not when you invoke an image, as then SBCL skips some steps. I'm not sure if there's a generic solution to this, or if you just need to poke each library that has dependencies on outside state being initialised (like glut) separately.

Maciej, Rudolf:

I tried Rudolf's naive approach, too, and of course got the same results. If you manage to package a cl-opengl application, i will be most interested.

So...

Where's the el version?

M-x awesome-game

Okay, I got it to work under Mac OS X. It is pretty raw, but groovy anyway.

I made a source directory ~/Source.

After reading http://www.esden.net/blog/ , I downloaded the cl-opengl-thomas from http://www.esden.net/content/lisp/cl-mac-native-opengl-thomas-0.1.tar.bz2 .

I hand applied this patch: http://www.mail-archive.com/cl-opengl-devel@common-lisp.net/msg00147.html to the cl-mac-native-opengl-thomas sources.

Now, IMPORTANT: I used darcs by just grabbing the prelinked binary from http://wiki.darcs.net/DarcsWiki/CategoryBinaries , and in my Source directory I did:

/path/to/darcs/binary/darcs-1.0.9-i386-darwin get http://www.common-lisp.net/project/cffi/darcs/cffi/

I then changed directories to ~/.sbcl/systems and did "ln -s /Users/me/Source/cffi/*.asd ."

Then, cd ~/Source and do:

svn checkout svn://erleuchtet.org/cl-cairo
svn checkout svn://erleuchtet.org/infpre
svn checkout svn://erleuchtet.org/toolbox

Back to ~/.sbcl/systems, "ln -s /Users/me/Source/cl-cairo/*.asd ." (and of course I did this for infpre and toolbox too).

Start up sbcl and do (require 'asdf), then (require 'asdf-install), then (asdf-install:install 'metabang-bind).

Quit sbcl.

Use MacPorts to do "sudo port install cairo" and "sudo port install freetype".

Go to ~/Source/cl-cairo and edit "cl-cairo.lisp". Comment out everything in "NON-PORTABLE CODE". Add the line:

(cffi:load-foreign-library "/opt/local/lib/libcairo.dylib")

(Or wherever libcairo.dylib ended up going.)

cd ~/Source/cl-cairo/Drawing

Edit cairo_t.lisp, and make sure that the "cairo_get_miter_limit" function and "cairo_get_miter_limit" function both end with *limit*, not *limet*. (Limit ends with IT, not ET).

cd ~/Source/perfectstorm

sbcl

(require 'asdf)
(asdf:oos 'asdf:load-op :perfectstorm)

And finally:

(storm:storm)


That'll do it!

It died pretty fast after I started clicking on stuff, but at least it showed up! :)


Great work! Keep it up! The prospect of games written in Lisp excited me when I first heard about GOAL:

http://en.wikipedia.org/wiki/Game_Oriented_Assembly_Lisp

I didn't know this was possible in CL! I may have to join you in a couple months (once I graduate).

Adam:
Everything is possible with every Language :)
But i concur: i was at first skeptical myself about lisp's adequacy for games. Although there were some difficulties to overcome, lisp has proven itself and now provides a working and productive environment.
More help will always be welcome, although graduation is not required ;)

Hi Johann,

that looks really nice. The graphical style reminds me of Geometry Wars, one of my favourites.
I recently learned some Common Lisp. I really like it. Especially the REPL and the way it integrates into Emacs with SLIME make it easy to get started with. Hopefully it gets more attention in the future.

Great work Johann!

Could you tell me where can I get "cffi-newtypes"?
The link http://common-lisp.net/~loliveira/darcs/cffi-newtypes is broken ( I've tried with darcs ).
And from SBCL I recieve "Server responded 404 for GET http://www.cliki.net/CFFI-NEWTYPES?download" bug message. Googling gives not so much results :(.

Any suggestion would be great appreciated.

Hi nagi

current cffi from darcs will do. sorry about the confusion.

I am trying to install this on Kubuntu 8.04 KDE4 beta. I had to bootstrap the SBCL 1.0.16 from source. I also had to correct a missing stubs-32.h from libc6-dev-i386 to get everything to compile. I am using cffi+lotsastuff from http://common-lisp.net/~loliveira/darcs/ which I compiled by running make test-sbcl (not sure if that is correct. It made the .fasl files but failed some test).

I get this error during load-op:

There is no class named ENSURE-INTEGER

This is while loading CL-GLUT... I know other people have reported this issue. Hopefully I provided enough info for someone to narrow down the problem. Google barely has mention of "ensure-integer" and installing krmcl alone did not help..

Hi all
I'm trying to install at least cl-opengl on my sbcl 1.0.12 system and I'm experiencing the same error mentioned above:
There is no class named ENSURE-INTEGER
I've installed current cffi with darcs.
Any solutions are deeply appretiated

The svn is currently not up. Will the source be reposted or is it closed? I'm learning lisp and have been looking for a good example of how stuff like this implemented. Regardless -- thanks so much for sharing what's been shared already -- It's so inspiring!

Hi Dustin, hi all of you who wondered about perfectstorm's current state.

The project is more or less frozen since i got addicted to graphics programming. Also, i don't consider it the best example to learn lisp (especially because it is in semi-working state). But if you still want to look at it, you can drop me a mail at my-nick @ this-domain and i will send it to you.

greets
cupe

Hey, we are having a Lisp Game Design Challenge... see http://dto.github.com/notebook/lgdc.html

Your project looks great, we would love for you to participate!

You will have to wait a little longer or get your hands dirty yourself if you want to try a playable version :)

Hey, perfectstorm looks fantastic, want to join our month-long Expo? Running until the end of july. If you don't have a lot of time to work on the project itself, perhaps you could write up a brief paper about your software and experiences for our conference. More info at http://dto.github.com/notebook/2010expo.html

Where is admin?!
By the way, anybody home?!

@Yuri: that looks like a debian version of SBCL, with Common-lisp-controller built in. It's not clear that anyone involved will be able to help you with this because of the non-standard use of C-L-C. I'd recommend building your own copy of SBCL from source (it's not too hard), or grabbing a binary tarball.

Try again after that....

Cheers,
r