clojure-gamedev

2018-05-22T14:49:21.000539Z

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?

2018-05-22T14:51:29.000150Z

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

spiralganglion 2018-05-22T17:34:12.000070Z

The majority of game code won't be all that performance intensive, and for that there should be no problem using CLJS.

spiralganglion 2018-05-22T17:35:33.000806Z

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.

spiralganglion 2018-05-22T17:37:25.000679Z

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.

spiralganglion 2018-05-22T17:38:44.000659Z

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.

2018-05-22T20:04:49.000599Z

awesome thanks for the tips, that's good to hear that cljs is definitely viable.

2018-05-22T20:05:29.000222Z

Currently trying to get to the bottom of the bugs in cljs-play described here: https://github.com/oakes/play-cljs-examples/issues/4

spiralganglion 2018-05-22T21:49:03.000656Z

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.

spiralganglion 2018-05-22T21:50:28.000082Z

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.

spiralganglion 2018-05-22T21:50:38.000220Z

That'll make it easier to get started with physics and animation.

spiralganglion 2018-05-22T21:55:16.000479Z

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

spiralganglion 2018-05-22T21:55:48.000225Z

But if you've never run into these problems before, using these solutions might be a little too.. defensive.

spiralganglion 2018-05-22T21:56:29.000357Z

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.

spiralganglion 2018-05-22T21:56:48.000589Z

Chances are good you won't need to do any of it.

spiralganglion 2018-05-22T21:59:11.000371Z

(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.)

wusticality 2018-05-22T22:08:40.000201Z

So I’ve been considering building a large simulation game in Clojure using LWJGL

wusticality 2018-05-22T22:08:54.000255Z

I’m trying to decide if Clojure will be fast enough in practice

the2bears 2018-05-22T22:09:21.000062Z

play-clj wraps libgdx which is LWJGL++

the2bears 2018-05-22T22:09:30.000321Z

I've used it quite successfully for 2d games.

the2bears 2018-05-22T22:10:16.000250Z

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

wusticality 2018-05-22T22:19:52.000084Z

I’ve looked at it - I’d rather do my own thing - my question(s) are mostly about whether Clojure can be performant enough

wusticality 2018-05-22T22:20:27.000495Z

I know I can always stick things in deftype / defrecord, etc but I’m not sure about Clojure’s performance at scale

spiralganglion 2018-05-22T22:20:46.000042Z

(Or use volatile / transients)

wusticality 2018-05-22T22:20:48.000027Z

I use Clojure at work actually for large modeling simulations and it performs pretty well

wusticality 2018-05-22T22:20:53.000116Z

@ivanreese yeah for sure

wusticality 2018-05-22T22:21:14.000386Z

Having a repl in-game would just be so sick

wusticality 2018-05-22T22:22:18.000364Z

one thing that is unfortunate is that using Clojure limits me to *nix / osx / windows

wusticality 2018-05-22T22:22:37.000495Z

but it’s a large simluation game so I guess if it ever does well I just pay someone to port it 😉

2018-05-22T22:37:17.000152Z

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

2018-05-22T22:51:21.000250Z

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

wusticality 2018-05-22T22:55:50.000066Z

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

wusticality 2018-05-22T23:04:52.000178Z

having a repl would be so awesome though, you basically boot the game and never restart it while developing

the2bears 2018-05-22T23:07:24.000093Z

@iwannaseethelight you're right, having the REPL while the game runs is really good. Debugging especially, tuning of configurable parameters... so much fun.

wusticality 2018-05-22T23:07:34.000286Z

yep

wusticality 2018-05-22T23:07:44.000302Z

I was an engine programmer for a decade, hardcore low level c++

the2bears 2018-05-22T23:07:51.000332Z

Yeah, Minecraft was Java/LWJGL I believe.

wusticality 2018-05-22T23:08:07.000244Z

but I’m a hardcore emacs user and was using elisp for years so when i found clojure i was like “omg”

the2bears 2018-05-22T23:08:26.000323Z

Yeah... saved my sanity from a career of Java.

wusticality 2018-05-22T23:08:27.000150Z

i think the hard part is the immutability though as far as performance goes

wusticality 2018-05-22T23:08:46.000072Z

that and rendering

the2bears 2018-05-22T23:08:56.000031Z

Why rendering?

the2bears 2018-05-22T23:09:17.000358Z

You mean time consuming?

wusticality 2018-05-22T23:09:47.000302Z

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

the2bears 2018-05-22T23:10:05.000013Z

I get it.

wusticality 2018-05-22T23:10:07.000274Z

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

the2bears 2018-05-22T23:10:15.000322Z

I'm old school...

the2bears 2018-05-22T23:10:21.000306Z

2d shmups 🙂

wusticality 2018-05-22T23:10:24.000297Z

had the crazy thought of using unity and communicating with a clojure process over udp 😛

the2bears 2018-05-22T23:11:04.000142Z

That would likely slow things down far too much

the2bears 2018-05-22T23:11:16.000185Z

well, UDP is better than HTTP...

the2bears 2018-05-22T23:11:18.000397Z

TCP]

wusticality 2018-05-22T23:11:46.000385Z

yeah it likely would

wusticality 2018-05-22T23:11:51.000212Z

there are big disadvantages to using clojure

wusticality 2018-05-22T23:12:18.000062Z

namely - gc issues, having no renderer, ui framework, etc., and being limited to desktop machines

wusticality 2018-05-22T23:12:55.000035Z

pros are - it’s more fun to build imo, and you have the expressivity of lisp

wusticality 2018-05-22T23:13:13.000278Z

rimworld has done pretty well on steam (no mobile) haha

wusticality 2018-05-22T23:13:26.000067Z

and when i say pretty well, he’s swimming in dollar bills haha

wusticality 2018-05-22T23:13:36.000358Z

i actually decompiled the source for that game, it’s all c-style

wusticality 2018-05-22T23:16:42.000446Z

no ui / renderer / limited to desktop / performance issues are the biggies

wusticality 2018-05-22T23:16:48.000003Z

especially those first two

the2bears 2018-05-22T23:17:45.000324Z

I'm happy enough just having Clojure as a medium to express games in 🙂

wusticality 2018-05-22T23:18:12.000101Z

one other thing that’s nice about clojure i guess is it’s concurrency / parallelism mechanisms

the2bears 2018-05-22T23:20:45.000418Z

yes, but in 2d I wouldn't bother with anything other than a single thread of execution.

the2bears 2018-05-22T23:21:13.000372Z

for other styles I can see the benefits

the2bears 2018-05-22T23:21:37.000384Z

but if you can avoid it with a single game loop I tend to avoid it 🙂

wusticality 2018-05-22T23:37:59.000033Z

yeah maybs

wusticality 2018-05-22T23:38:26.000254Z

it’s likely bat shit crazy to even consider building a game in clojure though haha - should use unity and call it a day

the2bears 2018-05-22T23:41:19.000200Z

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.

the2bears 2018-05-22T23:41:44.000170Z

My advice is if you want to give it a try, then go for it.

wusticality 2018-05-22T23:51:31.000169Z

To @ivanreese’s point, you can use things like transient to make things a bit better

spiralganglion 2018-05-22T23:54:22.000223Z

You can also do 90% of the game in Clojure, and the perf-critical 10% of the game in something closer to the metal.

👍 1
spiralganglion 2018-05-22T23:56:28.000145Z

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.

spiralganglion 2018-05-22T23:57:56.000300Z

As for... no renderer.. there have got to be renderers for Java, no?

spiralganglion 2018-05-22T23:58:24.000282Z

And if you have a renderer, you have a UI layer — just build it out of game objects.