Cl-bodge: a cross-platform Common Lisp game and application framework
borodust.orgThere’s a small, somewhat quiet, but very welcoming and very vibrant community of Common Lisp games developers. #lispgames on Libera is where many of them hang out.
There are a few people who are trying their darndest to build and support libraries for graphics and other game-necessary things. It’s a tall order, since computers and operating systems have become so wildly complex and incompatible. (It’s no wonder people go straight for the browser to do little graphics things now.) Often it means finding a way to robustly interop with C++, graphics cards, etc.
Borodust, Baggers, dto, mfiano, and Shinmera are but a few Internet pseudonyms of people working hard along these lines. Shinmera in particular just released a demo of his team’s game Kandria [1]. It’s a cool and modern game with neat mechanics and effects. It’s powered in part by a ton of open source Common Lisp tools he’s developed.
I feel like this is a good time to shoutout to Baggers for the excellent "Little Bits of Lisp" Youtube series: https://www.youtube.com/watch?v=m0TsdytmGhc&list=PL2VAYZE_4w...
On a somewhat related aside, the book Land of Lisp [1] is an interesting introduction to both Common Lisp and game programming. If anyone, like me, was interested in learning Common Lisp through a casual and fun mode, I highly recommend the book.
I generally recommend people avoid Land of Lisp as an introduction to CL book. It's simultainisouly too easy and too hard for most people approaching the language in that it goes way too briefly over core concepts then all of a sudden shifts gears into much more involved programming.
That being said, it's probably the best second book on CL ever. It showcases a variety of lisp techniques on some very real and fun example projects working itself all the way up to a web base game rendered via SVG which is quite fun.
Fair enough! I haven’t gone through it entirely. What do you recommend as primary texts? I have a few in mind (Practical Common Lisp, for example) but haven’t actually touched them yet.
Practical Common Lisp lives up to its name as the most practical of introduction texts, covering all the core topics and including many small example projects.
Touretzky's Gentle Introduction is popular, but targeted more at people entirely new to programming. The nice thing about this book is it is more like a college textbook in that it has many homework questions with answers in the back, so its great for structured practice.
Paul Graham's ANSI Common Lisp is still my favorite introductory text assuming the reader has knowledge of an existing functional language (using Javascript functionally for example). The books is a firehose of information, is short yet somehow manages to cover even more material than the other books, includes a full reference to CL, has a section on performance tuning I haven't seen in other intro texts, and still fits in meaty examples like a raytracer and a prolog-lite DSL. It's a real shame this book does not get a reprint, you'll need to buy a used version to get it at a decent price, however I'm finding myself using it as a reference so much I'm considering buying a new copy.
What I've found with learning CL as opposed to other langauges is that I get a lot of value out of reading multiple beginner texts. Rather than having a small number of core concepts like an OO language, CL just has a massive number of functions. This makes it nicer to work with IMO but just takes more repetition to learn.
An alternative approach I would love to see somebody try is to learn straight from Norvig's Paradigms of AI Programming. The book has a brief introduction to the langauge at the start, then goes into writing actual very interesting code, then ends with a section covering some of the more detailed topics. If you're the kind of person who learns most by example of real-world code, it could work.
I liked Practical Common Lisp. Also Paul Graham's "On Lisp" (Chapter 4 is a good example of the flavor of it).
Both of these are still perfectly serviceable texts for common lisp purely in terms of "can I run this code from 20+ years ago unchanged on sbcl I just installed via a package manager?". Practical Common Lisp is simply a phenomenal textbook in terms of pedagogy.
But for simply and phone based game, would concentrate on JS better than on CL due to the support, and easy of doing both desktop and phone. Wonder?
Even kandria itself is open-source (I believe) here[0].
I think Lisp is wonderful, and I would love to develop games using Lisp. However, I was under the impression that, by all accounts, developing games in Lisp is completely unrealistic due to the garbage collector.
I'm not familiar with Common Lisp, but in Racket, “GC pauses [...] typically run from 50ms to 100ms” [0]. On a 16ms maximum frame budget, that doesn't really work. Am I missing something?
[0]: https://docs.racket-lang.org/portaudio/index.html#%28part._....
EDIT: I'm aware of GOAL at Naughty Dog — Andy Gavin who wrote it described the GC as being a problem in a HN comment. [1]
You can write Lisp in a way that you manage your own allocations, including avoiding the heap. It defeats part of the point of Lisp, but sometimes you can use that coding style for a subset of your program that shouldn’t be leaning on the GC too much.
I don’t do game development, but in scientific computing, I rely on the GC a lot for workload preparation and other administrivia, then adopt a GC-famished Lisp style for the hardcore numerical computing part.
To be sure though, GC-less Lisp programming takes a great deal of effort and knowledge. It’s not exactly an a la carte option. But the fact it’s possible means latency-sensitive applications are possible. Fortunately, Lisp’s primary benefit isn’t the GC.
And with DISASSEMBLE[1] you can easily check to be 100% sure.
Anyone know if there have been attempts at concurrent garbage collection in any of the major lisp implementations (whether CL or Scheme). Maybe Clojure?
Clojure uses the underlying host's GC (e.g., JVM, CLR or JS engine). It also typically generates rather more garbage than other languages may due to immutability by default. As with all things, you can avoid the garbage if you are willing to abandon the usual idioms.
I heard Allegro's GC is concurrent and that "a new GC seems to be brewing in SBCL".
Also Clasp's GC (via Boehm GC and MPS).
Last but not least, quoting: "when one runs ABCL on a suitable JVM with ZGC or Shenandoah, then it has parallel GC".
https://twitter.com/stylewarning/status/1387809546287022082?...
https://lisp-journey.gitlab.io/blog/pro-mailing-list-on-comm...
Naughty Dog historically disagreed with this [0], plenty of games these days are developed in languages with GC but it is a performance trade off. For maximum performance any Lisp is probably not the way to go but I don't think it's unfeasable.
I want to say in general e.g. SBCL (a popular common lisp implementation) will perform a lot better than Racket. Racket is a great language but performance is not it's strong suit.
[0]: https://en.m.wikipedia.org/wiki/Game_Oriented_Assembly_Lisp
Currently, but hopefully no longer in the near future, SBCL’s garbage collector is extremely meh. It’s hard to tune, it stops the world, etc.
Otherwise SBCL is a wonderful implementation.
I used Clozure CL (and I'm now a LispWorks customer) for this reason.
Is there some recent work going on in SBCL on its GC?
yes!
> A new garbage collector seems to be brewing in SBCL git...
https://twitter.com/stylewarning/status/1387809546287022082?...
There’s a lisp-like language without a GC called Carp [1]. I believe the goal was enabling real time applications and specifically games. I’ve only toyed with it a tiny bit, but it has an ownership memory model inspired by Rust. Pretty neat project!
The `portaudio` is a few years old, so I have a hunch that the comment refers to the old backend "Racket BC". The new backend "Racket CS" has a new garbage collection mode "incremental", which I understand is better for this usage scenario. I don't have any numbers though.
I got some more information from Flatt.
The new incremental mode means the 16ms deadline is within reach. In fact if the screen is not involved, then 1-2ms is reachable.
On macOS a screen-refresh can cause a 16ms pause.
Didn't incremental GC exist before CS work even began? I certainly remember seeing it although it was not default. Or is this a different implementation?
Yes, incremental GC exists in both the CS and BC variants. It works quite differently in each one, though, because the general GC architecture in each is different.
Kandria is written in Common Lisp and manages to deal with this.
I can't speak to the exact numbers, but in comparison to Scheme based lisps, CL has a much wider variety of optional hints you can give to the run time to drastically speed up performance thanks to its more pragmatic industrial heritage.
This is correct. You can declare the types of objects (DECLARE TYPE) which has repercussions on size and allocation, you can declare the type of optimizations you want to do (DECLARE OPTIMIZE) be them speed space or safety, and you can declare things to be stack allocated (DECLARE DYNAMIC-EXTENT), avoiding GC of a particular object altogether.
This is what makes CL feel so good to use. I can declare optimizations and types and verify it with DISASSEMBLE to see the resulting assembly. (If your CL implementation compiles to assembly, such as SBCL) It's possible to make things go really fast this way, too.
It's worth mentioning that in general, racket is just a lot slower than SBCL. I would never write performance critical software in racket
Andy derides the GC of a particular common lisp implementation (Allegro) and praises the GC of an implementation of a language with broadly similar semantics and data model (Ruby). The conclusion to take from that is that one CL implementation had a crappy GC, not that CL is not amenable to fast garbage collection.
Author on the line. Thanks for the shoutout!
:cl-bodge itself is still an experimental tech that has barely any documentation - I won't recommend using it directly, unless you are happy tinkerer that ain't afraid of guts from hell.
:trivial-gamekit though is a stable framework that have much better documentation and strives to be as simple as possible. Nothing experimental about it. It's dangerous to go alone into jams with CL-based games, take gamekit with you. The fact that it is based on :cl-bodge at the moment is an implementation detail.
:alien-works is an attempt to reuse everything C/C++ gamedev world has and drive it from CL without too much blood bolting from eyes. It's not very experimental - just some conventional stuff piled together, but still is in early stages of development (although it has passed proof-of-concept phase).
We are, as in #lispgames community, indeed very welcome you to join us on irc.libera.chat:6697 in #lispgames channel. Some of us can also be found on Lisp Discord server[0] in #lisp-gamedev channel.
We also have community twitter account[1] which is not super active, but still alive. Just smells funny.
Also check out alien-works[0] by same author (borodust). This guy just works non-stop. I find it inspiring in a way.
Playing with their 'trivial-gamekit' based on cl-bodge now, very nice I think!
https://borodust.org/projects/trivial-gamekit/
alien-works also looks cool and under active development