Hacker Newsnew | past | comments | ask | show | jobs | submit | resatori's commentslogin


Hey, you should checkout https://github.com/rednblackgames/HyperLap2D then.


Core is both an engine, a new paradigm and an action RPG in development. Just clone the repo and start with `lein dev` (clojure build tool).


https://github.com/xpenatan/gdx-teavm

This is a libgdx backend for web. Should be possible to use with clojure but haven't tried. This is actually the most interesting next step for the engine I think - would let anyone try the game from the browser!

Even if it's would be hard on performance o think it would be worth it - I would just make the game turn based then


will check that too, thanks!


Thanks, it is from a time when I read too many osho books and started a blog...


The result of the experiment is that no, it's not simple.


To be honest I think this project actually failed. It is an overengineered mess and lacks any kind of clear structure.

The main problem is total lack of specification - because I didn't come up with a story for the game or I think games maybe don't need stories. So I just coded like a maniac because it's just fun to code in clojure


To be fair, a lot of successful projects are an overengineered mess and lack any sort of clear structure.

Kudos for trying something cool, this is a space a lot of people are interested in. Thanks for sharing it.


You're already above many by admitting that this was simply a fun hobby, and realizing that this may not have as simple as claimed. Hope you learned a lot from the project.


A clojure vector is an inbuilt data structure of the language and looks like this: [1 2 3]

I am using them to construct side effects which I call 'transactions' (similar to datomic) [:tx/foo 3] where :tx/foo is a keyword and uniquely identifies the component behaviour.


Reminds me a little of this Flappy Bird demo which makes use of DataScript's Datalog rules https://frankiesardo.github.io/minikusari/#!/minikusari.tuto...


> inbuilt data structure of the language and looks like this: [1 2 3]

array / vector

> construct side effects which I call 'transactions'

setting a variable

> where :tx/foo is a keyword

variable or hashmap

> uniquely identifies the component behaviour

running a function


Check it out, it is handling hundreds of entities at >>60 FPS. And I still did not do much performance optimization (there are still many lazy seqs around and unoptimized code).

Also most of the sprite rendering is the main problem, which an atlas texture could also improve even more. (Right now all creature animations are separate texture files).

And you can always step down a level to java if the need arises!


the issue with JVM/java was always that when that GC triggers you are just absolutely hosed.

C# tends to be a bit more forgiving about when it triggers GC and how. The generational garbage collector in C# will tend to be more reliable or at least I never ran into super huge issues with the places I've used C# for game dev.

The JVM GC has this unfortunate effect of having very bad pauses occasionally. And appears to do so regardless of the type of GC you are using.

There are some techniques you can use to get around this -> re-using entities. Using C# structs. Not doing allocations/deallocations inside the main game loop if you can.

For small enough games it is irrelevant but as soon as you start to get a larger game with lots of memory allocations/deallocations it really crushes performance.


Minecraft is written in Java, it doesn't look like the choice of platform kept it from becoming a success.


It was however completely rewritten in C++ when they needed to port it to more constrained platforms, every mobile and console version uses the C++ codebase while PC has both versions in parallel. If you ever intend to release your game on multiple platforms then Minecraft isn't an example to follow unless you're up for starting over from scratch at some point.


A side effect from specific platforms not allowing Java, and Microsoft buying Mojang.

Notch surely isn't sorry for having coded it in Java.


It worked out for Notch, sure, but most indie devs don't get the luxury of only considering console ports after they're already set for life from initially only releasing on PC. Planning for cross-platform from the start is table stakes, especially now the Switch has become just as if not more of a popular platform for indie games than PC is.


Most indie devs already strike gold if they manage one platform at all.

Too much is wasted on what language, or engine to use, instead of what actually make as a game.

And even when everything is done right, it is a drop in the ocean of daily released titles.


If anything using Java made it extremely moddable and is IMO part of the reason why it became a success.


Bad performance did delay one of the big new-biome-type releases in the Java version.


Minecraft was known for allocating and freeing hundreds of megs of memory every frame. It was able to be written in java and have huge performance problems because it was so simple and low res.


Unity's new incremental gc saved our bacon.


60 FPS of 3D objects in a 3D world?


I find it very natural to work with because clojure is based on the JVM so the project uses libgdx under the hood (deploys to all platforms, huge library) and I can use lisp for everything else to do basically anything.

Combined with clojures way of handling immutable datastructures so well & the excellent protocol system (https://www.freshcodeit.com/blog/clojure-protocols-and-the-e...) I could separate the whole game easily into separate components.


Sorry, but I feel like your comment does not actually address my concern of whether having to deal with immutable data structures in a functional way would lend itself especially well to video games.

Of course, the Clojure approach is great for a lot of use cases, but video games traditionally do a lot of mutable changes to components. That doesn't mean, of course, that it cannot be done any other way, but it would certainly be a different approach.


It's important to keep in mind that Clojure uses persistent data structures. It's easy for folks with a background in other languages to assume that immutable data structures require a deep copy to modify when in fact they don't.

In my experience, it slightly favors wide rather than deep game state because wide game state implies fewer nodes that need to be re-created when creating a new state. Since the author is using ECS, it's probably wide enough already.

A bit more in the weeds and if one was using a deep game state, careful structuring of assoc-in and update-in calls might be warranted. Ideally each node would only be copied once to arrive at the next game state. Sometimes it can be more efficient to build a list of changes and then property sequence the application of the changes to the state.

At the end of the day, people don't have to use a single atom like the author either. A game state can consist of multiple mutable data structures. It's not like the Clojure-police are going to arrest anyone for it.


Oh, and allow me to add: I'm not criticizing, I'm just putting a possible concern out there for discussion. That's why my original post was worded as a question.


I don't understand your concern. Would you mind phrasing it differently?


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: