Is clojurescript game development actually a viable thing? For a game like a sidescroller that requires constant animation? I've been looking at play-cljs
and chocolatier
both which seem to be significant efforts. but their own demos for these types of games are unplayably slow and buggy out of the box. I'm trying to decide if it's worth it to try to track down what's causing this in these libraries but I'm starting to suspect it might be the performance overhead of clojurescript itself and that it's not really easily fixable?
I'm not sure which rabbit hole I want to go down: attempt fix existing cljs frameworks, go without a framework, or abandon cljs altogether for something else
The majority of game code won't be all that performance intensive, and for that there should be no problem using CLJS.
Depending on the style of game, if you're doing a lot of work per-frame, you might end up wanting to write parts of it in JS. But you'd probably want to build it in CLJS first to figure out what you want your game to be, and then when you notice slowness, measure what is causing the slowness and apply targeted fixes for that stuff.
CLJS also offers some nice half-step measures to eke out additional perf where you really need it — like using mutable JS arrays and objects from CLJS. That way you have the benefit of staying in Clojure-land, but you don't end up beating on the garbage collector.
When doing games and such in the browser, you usually end up spending more of your time per frame rendering rather than running scripts, so whenever that's the case your choice of language really doesn't matter — rather, what matters is how your structure your scene graph, your render pipeline, what sort of tricks you can do with buffering, which graphics API you're using, etc.
awesome thanks for the tips, that's good to hear that cljs is definitely viable.
Currently trying to get to the bottom of the bugs in cljs-play described here: https://github.com/oakes/play-cljs-examples/issues/4
I think the author of that comment is missing an important detail. In the browser, you are always going to run at 60fps — no faster, and no slower (unless your code/rendering takes too long to run each frame). So even if the player has a 144Hz monitor, the game will still run at 60Hz.
When you're doing more advanced work, you'll want to use the amount of time elapsed between frames as part of your physics sim. But if this is one of your first game projects, you might be better off ignoring that detail and just coding the game as if every frame represented the same span of time.
That'll make it easier to get started with physics and animation.
The article they linked in that comment does do a good job of describing how to set up a good timestep, but there are choices you'll need to make based on how you design your game, and how you expect it to run (the article does a good job of explaining some of these under "Panic! Spiral of death")
But if you've never run into these problems before, using these solutions might be a little too.. defensive.
I say, keep this article in your back pocket. When you run into an issue, follow the recommendations in the article one at a time until your problem is resolved.
Chances are good you won't need to do any of it.
(And by the time you do, you'll know enough to pick and choose which parts of their solution you want to use. For example, you probably want to apply some smoothing to deltaTime values, since the framerate will be kinda spiky in non-Chrome browsers — a technique they don't cover. But again, not something you need to worry about until you actually have a big, complex game that is behaving weirdly on different machines in different browsers.)
So I’ve been considering building a large simulation game in Clojure using LWJGL
I’m trying to decide if Clojure will be fast enough in practice
play-clj wraps libgdx which is LWJGL++
I've used it quite successfully for 2d games.
it will be fairly familiar to you if you've used LWJGL - I did Java games years ago with it, and the transition was fairly easy
I’ve looked at it - I’d rather do my own thing - my question(s) are mostly about whether Clojure can be performant enough
I know I can always stick things in deftype
/ defrecord
, etc but I’m not sure about Clojure’s performance at scale
(Or use volatile / transients)
I use Clojure at work actually for large modeling simulations and it performs pretty well
@ivanreese yeah for sure
Having a repl in-game would just be so sick
one thing that is unfortunate is that using Clojure limits me to *nix / osx / windows
but it’s a large simluation game so I guess if it ever does well I just pay someone to port it 😉
Awesome thanks so much for this info. The problem is, it seems like there are actually major performance/loop issues out of the box with the super Koalia game demo that make it unplayable at least on my computer (with bugs like falling through the ground). I assumed that they might have something to do with the issues described in the linked loop article. I started checking into this and haven't confirmed or ruled it out yet (the bugs might be unrelated) @ivanreese
My initial attempts to measure the fps with the demo show it at only about 10 fps on my pretty specced out computer. I could have the measuring wrong. But I'm not sure yet if that in itself is causing the buggyness or is just a symptom of it
Considering minecraft was built in java, I’m betting it’s at least feasible to build a sim game in clojure, might just be hard to get right
having a repl would be so awesome though, you basically boot the game and never restart it while developing
@iwannaseethelight you're right, having the REPL while the game runs is really good. Debugging especially, tuning of configurable parameters... so much fun.
yep
I was an engine programmer for a decade, hardcore low level c++
Yeah, Minecraft was Java/LWJGL I believe.
but I’m a hardcore emacs user and was using elisp for years so when i found clojure i was like “omg”
Yeah... saved my sanity from a career of Java.
i think the hard part is the immutability though as far as performance goes
that and rendering
Why rendering?
You mean time consuming?
you don’t have the luxury of an engine so if you want to do anything complicated at all you’re hosed - aka, any 3d animation, skeletal rendering, lighting, complicated shaders, etc
I get it.
my game is top down 2d ala rimworld so i’m probably ok, but it’s such a waste of time to write a renderer
I'm old school...
2d shmups 🙂
had the crazy thought of using unity and communicating with a clojure process over udp 😛
That would likely slow things down far too much
well, UDP is better than HTTP...
TCP]
yeah it likely would
there are big disadvantages to using clojure
namely - gc issues, having no renderer, ui framework, etc., and being limited to desktop machines
pros are - it’s more fun to build imo, and you have the expressivity of lisp
rimworld has done pretty well on steam (no mobile) haha
and when i say pretty well, he’s swimming in dollar bills haha
i actually decompiled the source for that game, it’s all c-style
no ui / renderer / limited to desktop / performance issues are the biggies
especially those first two
I'm happy enough just having Clojure as a medium to express games in 🙂
one other thing that’s nice about clojure i guess is it’s concurrency / parallelism mechanisms
yes, but in 2d I wouldn't bother with anything other than a single thread of execution.
for other styles I can see the benefits
but if you can avoid it with a single game loop I tend to avoid it 🙂
yeah maybs
it’s likely bat shit crazy to even consider building a game in clojure though haha - should use unity and call it a day
Well, honestly it's like asking how long a piece of string is. Some games are fine in Clojure, and mine are fine performant-wise for what they are. If you're trying to do something more involved, more computationally intense then yes, the extra GC work will really slow things down.
My advice is if you want to give it a try, then go for it.
To @ivanreese’s point, you can use things like transient
to make things a bit better
You can also do 90% of the game in Clojure, and the perf-critical 10% of the game in something closer to the metal.
Mirroring the way most AAA games are split between C++ and Lua, or how many indie games using Unity or Unreal use some sort of easy-to-use scripting language on top of a high-perf core engine.
As for... no renderer.. there have got to be renderers for Java, no?
And if you have a renderer, you have a UI layer — just build it out of game objects.