
Making an RPG in Clojure (2010) - arm
http://briancarper.net/blog/520.html
======
Morgawr
Reading this article is like reading something I might have written myself. I,
too, just like the author, have been toying around the idea of Clojure games
for a long time. I've made small games (Ludum Dare entries mostly) and started
(and subsequently killed) a lot of Clojure game engine projects.

I tried the threading approach using agents (which later evolved into agents
inside atoms or was it atoms inside agents? It's been a long time) and came to
the same conclusion as the author. I tried to move to a more centralized CES
approach, which didn't work out.

It's interesting to see how some people can come down to the same path and
achieve the same results (for the good or for the bad). I think my experience
with Clojure has been overall positive as far as game development goes,
although definitely not empty of woes.

Currently what I'm (very on and off) working on is a Visual Novel/Interactive
storytelling engine on ClojureScript, at
[http://novelette.moe](http://novelette.moe) and Clojure is great for it. Feel
free to trawl through my github profile (link in my profile) if you're curious
about some of my (failed? abandoned?) Clojure gamedev projects (among other
things).

~~~
vanderZwan
Nice, for some reason I have a soft spot for interactive fiction engines! How
does it compare to Twine?

~~~
Morgawr
I had never heard of Twine before, I just had a quick superficial look at it
and wow it looks really nice!

To be honest I don't know how it compares, my engine is closer to something
like Ren'Py but I plan to provide more freedom to the writers thanks to the
power of functional programming and the DSL-like implementation of Lisp. I
haven't formalized on a proper syntax for the scripts yet (although a rough
example can be seen on my demo game:
[https://github.com/Morgawr/ld31/blob/master/src/cljs/game/sc...](https://github.com/Morgawr/ld31/blob/master/src/cljs/game/script.cljs)
), but the idea is to have something like the script of an actual novel. The
author can define acts and chapters and have actors enter the scene, interact,
define the state of the scene (add/remove sprites, backgrounds, music) and
define the transitions from chapter to chapter within the novel.

------
alexkehayias
I've been working on a project to create 2D sprite based game engine in
ClojureScript. My goal was to represent the game completely with data and let
the engine figure out how to interpret and render it (declaratively). In the
end I implemented an entity component system (as other comments have
suggested) and used existing javascript rendering libraries to handle
rendering (not writing a wrapper for webgl...). You can check it out here:
[https://github.com/alexkehayias/chocolatier](https://github.com/alexkehayias/chocolatier)

It's been a ton of fun bringing a functional approach to games using Clojure
and I gave a talk about it at ClojureWest this year.
[https://www.youtube.com/watch?v=TW1ie0pIO_E](https://www.youtube.com/watch?v=TW1ie0pIO_E)
hope this helps others looking to build games!

------
davexunit
For those that are interested in what the current state of Lisp game
development is, check out the latest installment of the Lisp Game Jam. The jam
page includes lots of information about game development tools for many
different Lisps, and the submissions include games written in Common Lisp,
Scheme, Clojure, and Emacs Lisp.

[https://itch.io/jam/spring-2016-lisp-game-
jam](https://itch.io/jam/spring-2016-lisp-game-jam)

------
sbov
> due to multiple threads trying to edit the world ref 50+ times per second.

Of course you get no benefit if you serialize the game through a single ref.
Just because you have a fancy feature like agents doesn't mean you don't have
to think about how your concurrent code is behaving.

I chose Clojure for the server side code of my MUD. It wasn't for the agents
or STM, it was for immutability. Immutability gives me the ability to easily
have a consistent snapshot of the world which I can use to perform some
operation, such as saving, event propagation, or some AI calculations.

~~~
lgas
If you don't serialize the game through a single ref (or the equivalent) how
do you get the consistent snapshot of the world to perform an operation on?

~~~
glhaynes
Event loops are heavily used — basically process input, process physics,
process NPCs, render, repeat. (Likely not in that order — I'm not much of a
game developer.) This is what the author lands on in the "Success" section.

Speaking of event loops, I feel like they weren't discussed very much at all
at my school, despite being at the core of not just most game engines, but
most GUIs. I think if I'd embarked on writing a GUI system when I was fresh
out of school, I'd probably have done it in a massively threaded way like the
developer in the article started their game. An event loop would have somehow
seemed too … primitive.

------
sdegutis
This is great. I've also tried my hand at making video games in Clojure.

For me though, it was a weak attempt at a simple Bomberman clone that would be
playable over the network, so that my kids could play it across our different
family computers. It was even kid friendly, being about planting timed water
balloons, and avoiding getting wet!

It seemed like Clojure would be ideal for this, because the JVM has excellent
networking libs and GUI libs for simple 2d graphics.

But I severely underestimated how much time it would take though, so it never
really even got to a playable single player state.

The main part I got stuck on was trying to settle on a data format, how to
represent tiles and players and items and everything, in a form of immutable
data that was easy to both analyze and transform.

The author's idea of mapping a giant 2d string to actual data is genius,
although I suspect it wouldn't scale well for an RPG, and for my game it
wouldn't have been very helpful since the terrain would be auto-generated
(since needing to be somewhat randomized).

It's surprising to see the author here mention using Agents as the original
primary building block of the game engine. I've never directly used Agents or
found them helpful. To this day I really don't know what they're good for.

------
resatori
A few years ago I created a fully small RPG game in clojure:
[https://github.com/damn/cdq](https://github.com/damn/cdq)

Including procedurally generated maps, items and 3 small levels.

------
Elrac
I love that the author takes us on a tour of all his blunders, so we can learn
from them the way he did.

Far too many "making of" articles present you with a finely polished end
product and pretend that its evolution was child's play. That leaves us
readers disheartened and reluctant to try similar things.

------
PaulHoule
The article also shows up that there is snake oil in the actors, stm and many
other concepts to make concurrency easy and fun. Often you fall back on doing
it all in 1 thread because you get better performance that way but then what
is the poll of multicore?

Lmax disruptor is different from the others because it is based on engineering
(what works on actual hardware) opposed to 'science' (how you imagine it ought
to work)

~~~
wtetzner
Well, based on the original videos Rich did to promote Clojure, I think I
remember him claiming that STM was never meant for cases where you wanted
parallelism for performance reasons.

STM was intended to make it less error prone to use threads in places where
concurrency was the right fit for the problem.

~~~
anamexis
When is parallelism ever needed but for performance reasons? (Honest question,
I'm quite a novice when it comes to concurrency)

~~~
wtetzner
I maybe didn't word my comment very well. What I meant is that STM is meant to
be used in cases where the problem you're solving is most easily expressed in
a concurrent way. It's main use case is concurrency, as opposed to
parallelism.

For example, a web server is naturally concurrent. You definitely can
implement a web server in a single-threaded manner, but you'll end up just
faking concurrency anyway. So there are times where you'll want to use
concurrency because the problem you're solving is naturally concurrent. In
these cases, having an STM is valuable, because it makes it hard to get state
changes wrong in a concurrent environment. It is not necessarily a way to make
your program faster.

------
andrewclunn
Article is from 2010. Was there ever a follow up?

~~~
arm
Unfortunately not, it seems like many factors in his life led to him burning
out. He does have a new blog¹ now though.

――――――

¹ — [http://carper.ca/](http://carper.ca/)

------
xiaoma
This reminds me of Realm of Racket.

