Hacker News new | past | comments | ask | show | jobs | submit login
Core: an experimental new way to write videogames (github.com/damn)
280 points by resatori 29 days ago | hide | past | favorite | 213 comments



Oooh, this is cool. I always like to see different approaches to game dev (despite never having published a game!). So far I've tried

- Bevy (Rust ECS engine), which is nice at first but has a lot of problems with its implementation and can become rather messy. I think it's heavily dependent on the game. Part of it will be my own incompetence.

- Unity. IMO the system of gameobjects with composed modular components is the most utilitarian - it gets out of the way, and it's easy to avoid spaghetti without requiring a really strict engine-dictated structure.

- Godot. I hated it. All of the awful heirarchy of OOP, a really poor builtin language, and "signals", which are meant to decrease spaghetti but only increased it for me. Maybe I was using it wrong? I very rarely use inheritance to the point of being bad at using it.

- Pygame, back when I first learnt to code. It's quite nice for small projects - it's procedural at heart but you can make your own OOP or functional layers over it. There have been some surprisingly large projects made in it.

I don't know Clojure, but it's interesting to see someone make a functional implementation of something that stereotypically seems like a good fit for OOP.


As a professional game dev who has years of experience producing real products in both Unity and Godot, I am totally not with you about your thoughts on Godot vs unity.

Godots signals are such a huge step up over Unity's built in classes having a lack of modularity.

How do you even make sense of that? Godot vs Unity basically have the same scene/node/component model except Godot does it better imo. Eg) What is the difference between a prefab vs a scene in Unity anyways? Basically nothing, it's just (I'm speculating) a tech debt mistake in their design, probably still going because of how light maps work today.

Unity's advantage over Godot is it's 3D renderer, built in physX, il2cpp backend for C#, profiler, general runtime performance and console support.

Godots design is objectively more cohesive, as Unity has simply splintered into 10 different design directions since ~2018.

I'm not trying to be a hater, I just think signals are a huge advantage for writing modular, simple stuff in Godot. I think there's plenty of great reasons to prefer Unity to Godot but "signals" is not one of em.


I think the original commenter just really likes "plug and play" solutions with a lot of hand holding which is what Unity is excellent at. The problems come down the line.

Godot is objectively a way way better tool


> Godot is objectively a way way better tool

If you like things like Godot, Godot is the type of thing you will like.

Seriously though, Godot works way better for me using C# than it does with GDScript and the OOP structure means I can refer to classes by their identity.


It's definitely not a "way way better tool" and no serious game developer would say that. Everyone agrees that Godot has a lot of catching up to do but we're still using it because we believe in the foundation and what it will eventually become.


I'm a serious game developer, been in the industry for decades.

I would say that. Godot is a way way better tool.

There, I've falsified your claim.

But more seriously, it's a faster dev experience, it's more ergonomic, it's not cluttered with half baked "new" ways of doing things that don't do everything the old ways do. There's no reason to pick up Unity unless you are being paid to, IMO.


Or any of these

> Unity's advantage over Godot is it's 3D renderer, built in physX, il2cpp backend for C#, profiler, general runtime performance and console support.

And correct me if I'm wrong, but Godot doesn't have hot code reloading where you don't have to restart your game.


Godot has a good 3D renderer. It has a built in physics system and an off the shelf upgrade to Jolt (which was used in horizon forbidden west). There's absolutely a profiler (https://docs.godotengine.org/en/stable/tutorials/scripting/d...).

Hot reloading is supported.

Console support is some work. Possible, but work.


I'm a Godot contributor.

The 3d renderer is okay, but I'm hesitant to call it good. It's not as good as Unity nor Unreal, imo.

The internal profiler really sucks.

Everything is possible if "some work". Porting to PlayStation 5 is probably a lot of work.

I'm a Godot fan boy, but we gotta be honest about its flaws.

If your targeting 3D on console, definitely go with Unity or Unreal imo.


It does have hot reloading at some level. I use GDSCript for a lot of stuff and it hot reloads. And you can use live++ with it to have true top level hot reloading. We implemented a hacky live reloading for native code in shared libraries which works as well.


That doesn't make any sense. Unity may have a pedigree of being for beginners, but in recent years they can barely keep current documentation on their new systems. This smells like a comment from someone who has never used it.


I haven't used it in the past 3 or so years, but I used to use it quite extensively before that.


Fully agree, in Godot a Scene and a Node are the same thing which makes it much simpler conceptually. Also, having a true text based scene format makes merging commits easier than merging unity changes.


GDScript sucks big time, it's not even close to C#. They should drop that Python like language and go full in C# integration.


The core developers are too enamored with GDScript, but that's fine, C# and C++ (GDExtension) support is excellent. There are only a handful of API functions which are hampered by their need to support GDScript, so it's something you can basically just ignore.

You don't even have to use Nodes much, though they're great for lots of stuff. For real performance, you can drop all the way down to their thin wrapper over Vulkan and do whatever you want.


GDScript makes simple things simple and complicated things complicated. It's pretty good for the simple parts of your game. You can still use C# for its complicated parts as they integrate well.


What "sucks" about it? Since they added type checking it's been perfectly fine, besides the notable omission of nullable types (which is... a strange omission, to be sure).


No tuples. No structs. No real debugger. Extremely limited profiling tools. Autoformatting breaks code more often than not. No interfaces. Extremely weak async story. No refactoring tools, external IDE features like jump to definition. Built in editor is slow and buggy. No destructuring assignment, no enumerate for loops, no looping over key and value together from a dict.

GDScript is, in my opinion, unsuitable for anything more than a couple hundred lines at most.


I agree with this. I suspect it's part of a more general Godot philosophy that involves full in-editor workflows with highly detailed scenes, many nodes, and with small scripts attached to all of them.


Your comments are accurate, but they aren't the whole story.

> unsuitable for anything more than a couple hundred lines at most.

I work profesionally in ~5 code bases with ~10,000 lines of GDScript each. I think GDScript is great for UI widgets. I dont think you can say it has a 'line number' limit. It has a 'complexity' limit.

If your writing a ton of tiny little classes that do one thing (like play a sound when a button is pressed), then GDScript is probably the best language for that. Certainly c++ is not the best, and C# is perhaps worse as well. Note: GDScript doesnt need to be compiled _at all_. In unity, its common to have an annoying 'hang' every time you alt-tab from vscode back to unity, as the c# is compiled. In Godot, I can write a new UI widget directly in the editor, with no compilation hang, with hot reloading. It's simply a smoother experience for writing the mountain of basic plumbing that you write when making a commercial game. It's not all complex algorithms here, it's just a crapload of boring ass code. And GDScript is great for that.

Most of the code in games is tiny little things that manage sequences of animations. There is seriously so much small code to make a UI look and feel nice. Writing this code in GDScript is way faster and ergonomic than any other language I've used.

I agree, GDScript has many flaws, but from where I'm sitting (small studio, been in the industry for 10 years), GDScript is a massive boost for my productivity.

For complex stuff, I like to figure out the algoirithm in GDScript then rewrite it in C++ if it needs it. Works great. Again, massive increase in productivity.


I love everything about Godot so much, except for its UI system

It is just so confusing to me and took me over a day to get a simple menu aligned how I wanted

it might just be me not understanding how it works though


Godot’s UI system is easier when you realize that Control-derived nodes are even more granular than even HTML elements. They’re more like Tailwind classes.

Yes, your UI will be a tree of Control nodes 20 levels deep, and that’s fine.

Your root UI node will probably be an HBoxContainer, or VBoxContainer, each of which simply arranges their children horizontally or vertically, respectively. Between those two nodes you can create 90% of UIs you’d want to.


I recommend trying Zenject in Unity! It provides a pretty good dependency injection framework, but more importantly in reply to your comment it has a very easy to use signal bus implementation!

Now I have not tried Godot so I don't know how the two compare, but for where I work Zenject was basically the a-ha moment that made it possible to develop Unity apps/games that don't devolve into a huge unmaintanable mess.


I thought everyone was abandoning unity after their fiasco


A lot of people made a lot of noise about it and it hasn’t been long enough to tell for sure, but there is no real competition to Unity in many situations without a lot more work falling on your dev team.


Unity is a bit of a mess but to compare apples to apples when Unity has more features seems not quite fair.

Are signals significantly better than Unity events or is it more that the API uses them heavily?

Honestly, why doesn't Unity retool SendMessage() and public API callbacks to be an exposed Unity event? Unlike merging prefabs and scenes, that's not even a breaking change.


> Godot. I hated it. All of the awful heirarchy of OOP, a really poor builtin language, and "signals", which are meant to decrease spaghetti but only increased it for me. Maybe I was using it wrong? I very rarely use inheritance to the point of being bad at using it.

Not game dev either but I do have to say that I find Godot's design to be one of the best oop desings I worked with. I tend to not use oop much today (C++ embedded), though I did learn programming with C# so I'm fairly used to inheritance.


Godot is excellent, and I believe it will be the "Blender of game making" in 5 years or so. Version 4 is ready for prime time and is able to tackle most indie projects. Where Unity beats Godot is in the "Triple I" and "Double A" categories, as it has better 3D/performance features, tooling and add-ons. Neither engine is the best choice for AAA projects.

For 2D and simple 3D games, I see no reason to use Unity anymore; I predict a steady decline in Unity's market share as Godot slowly overtakes it.


> Where Unity beats Godot is in the "Triple I" and "Double A" categories, as it has better 3D/performance features, tooling and add-ons

While this is true it does come with a big caveat. Every single AA developer has had access not only to the Unity source code, but in some instances also to Unity employees who became directly embedded in the production cycle. There’s a GDC presentation from the team behind Ori and The Blind Forest where they talk about how some Unity devs were flown to Austria to help out with custom tooling. Playdead also has a really nice blog where they talk about all the changes they had to make to the engine in order to achieve good lighting performance/fps for Inside. https://blog.playdead.com/articles/inside_presentations/insi...

I’m sure that if the Godot foundation had enough resources at hand then you would also see more games like Cuphead and the ones previously mentioned above.


In the GMTK game jam, there was a -dramatic- shift usage towards Godot from Unity this year


I'm a commercial dev, previously used Unity, now using Godot. This comment rings true of GD Script and signals. I get around this by using C# and its event handling.

Working with nodes and editor bugs (or features? Hard to know really) is probably the most frustrating - you can really feel that this was initially built for 'smaller' projects.

For this reason, I rarely use the editor outside of setting up the scenes and a general hierarchy.

Daily tools: Emacs (with C# LSP) most of the time. VS Code for debugging. Godot editor for tweaking the scene tree.

Perhaps this perspective is useful for other devs thinking about Godot.


How does Godot performance compare using C# versus GDScript?


Not sure. I hear C# is at least as fast if not faster, though there may be situations where GDScript is more performant.


i haven't tried c# with it, but gdscript is slow, comparable to cpython. intuitively i'd expect c# to be an order of magnitude faster


I gave Godot a good shot. There's reasons not to like it, but IMO GDScript is not it. It's basically python with slot/emit semantics to integrate with the editor, which is actually rather nice, compared to other more complex ways of achieving such integration - via build systems, or some metadata or external configuration files. In Godot it's integrated into the language.


> Godot. I hated it. All of the awful heirarchy of OOP, a really poor builtin language, and "signals", which are meant to decrease spaghetti but only increased it for me.

Having programmed for over 25 years now, this was my experience. I feel like a little more IDE introspection or tooling to make the signal/listener connections more manageable, is the special sauce that's missing. The event pubsub moel becomes unmanageable to document/control with any non-trivial application. Godot has no encapsulation or tracking support, allowing all modules to hook to any event leads to spaghett, which you learn when working with large projects in various languages (JS et al).


I disagree that GDScript is a poor builtin language. It is somewhere between Python and JavaScript. It gets the job done and there is a lot you can do with it. Signals are great for things like state management. I'm not really sure what you mean by spaghetti code and how signals are supposed to help. I do agree that there are some annoying OOP aspects like providing a path to a scene (module). It's verbose but not unlike library imports in other languages.


When using the optional typing in GDScript, I'm surprised at how many errors are caught before runtime. The optional type syntax is nicer than Python's and the auto complete is good.

Godot could have built on Python, but they would have had to also include a language server (and maybe ipython or jupyter or something) to get the full seamless experience that GDScript gives. Including all that seems a bit much.

So, like you, I appreciate GDScript and have sympathy for why it was created.

Also, GDScript hasn't done anything like implicit type coercions (see JavaScript) and so GDScript can improve without breaking backward compatibility. If needed, breaking backwards compatibility in GDScript won't be as bad as breaking backward compatibility in a real programming language, so they can steer it where it needs to go for the benefit of Godot.


early versions of godot were actually python modules; they added gdscript because embedding python was taking too much work


I recently learned that the popular game Balatro was made in LÖVE. I had never heard of it until then. But looks interesting.

https://love2d.org


LÖVR (MIT) was posted last week: https://news.ycombinator.com/item?id=41446248


Also Moonring. Not as huge as Balatro, but fairly well-known too.


Loved that I could open up balatros game files and examine the source. Pretty cool how far the author took the framework.


I had similar fun with Don't Starve when I opened up some files in the game directory and noticed they were all Lua, all using an ECS system, and easily extensible. Having never used Lua before, I made a rudimentary multiplayer server for it by opening a socket and sending game events to another instance of the game on another machine. I planned to actually start making it into a multiplayer mod but then they announced Don't Starve Together and I scrapped my implementation for obvious reasons.


I find libGDX to be highly underrated. For me it hit just the sweet spot between being too low level and too fancy with Entity Component System for everything.


I've been a game dev (and services dev) for a two decades and I could not disagree with you regarding Unity and Godot more strongly.

Having gotten into Godot with v4, it was a huge breath of fresh air coming from Unity and Unreal (which isn't really hobby friendly).

Composition of nodes is quick, easy to compartmentalize, and having signals as an interface makes building them very, very quick. Yes, the debugging story on Godot isn't quite there yet, but I genuinely doubt I'll ever touch Unity again unless I have to for a job.


Don't want to be a bother but if had the time I'd love to hear your thoughts on this

https://github.com/ensisoft/detonator

It's a (2D only) game engine I've been putting together for years and obviously not yet at a level comparable to Godot, maybe more like haxe or lowe2d.

The target is simple single player, single developer "weekend" games.


> - Bevy (Rust ECS engine), which is nice at first but has a lot of problems with its implementation and can become rather messy.

Can you expand a bit about why this was messy or comolicated? I found the paradigm leads to pretty well organised code (sometimes you get the odd large system, but it can be broken down into smaller systems, sub systems or composed out of smaller functions).


I started using Bevy for a small game and abandoned it after a little while.

There are two issues:

1. The fundamental issue is that the ECS model has independent subsystems communicating via a relational database. This breaks the connection between function callers and callees, makes control flow incredibly hard to trace, and means the type system can give you very little assistance.

2. Bevy also does not leverage Rust's type system in other ways. E.g. you can use resources that you forget to create and it will only crash at runtime instead of giving a compile time error.

I think you can create a good game in Bevy, and if you come from a C/C++ world you probably won't notice the lack of type safety. It didn't meet my goals, however.


> 2. Bevy also does not leverage Rust's type system in other ways. E.g. you can use resources that you forget to create and it will only crash at runtime instead of giving a compile time error.

Would something else even be possible in Rust? My understanding is that you cannot really add type safety in the way of "This should be a i64 and between 32 and 128, otherwise fail to compile", so not sure how it could be addressed by the language.

Or taken to the extreme "Fail to compile if the user creates an instance of this but doesn't call function F with that newly created instance"


Let me explain a bit more about "you can use resources that you forget to create and it will only crash at runtime instead of giving a compile time error".

Plugins are the main abstraction in Bevy. A plugin has two parts: build and run. Build creates stuff, and run uses stuff created by build and created by the build of other plugins running at the same time.

Build is pure side-effects, so the result type of build tells you nothing about what it builds. Therefore there are no types that can constrain what resources run uses, and therefore failing to create a resource that is used in run is a run-time, not compile-time error.

The alternative is the build returns a type representing the collection of resources it creates, and run's type is a collection of resources it uses. This requires some type level programming (a type level heterogeneous set). This is some of the simplest type level programming, but type level programming itself is quite foreign to most programmers. I assume this is why the Bevy developers went for the easier to write solution that doesn't enforce constraints at compile-time.

More generally, just like in regular programming some things are easier and some are harder to do in common type systems.

Your first example (integer constrained to a range) is harder because you need to solve linear inequations at compile-time, which is not a feature of most type systems (though see refined types).

You second example (must call a method) is relatively easy with linear types, as they express "must do something with this value".


> You second example (must call a method) is relatively easy with linear types, as they express "must do something with this value".

Interesting, could you possibly share an example on how that would look like in Rust? Haven't come across it yet, and would certainly help with some things.

Lets say we want to make sure if "MyStruct" is ever defined + created, we want to make sure the program somewhere calls "register_struct" with an instance of that struct.


Rust does not implement true linear types, only affine, so I believe your parent is mistaken.

You can do a dynamic check to encode this, but that's not super popular. You can also issue a warning, and in theory turn that warning into an error, but it may also trigger on code unrelated to the specific struct you want it to, so I don't think that's a full solution either, and others may use your code without the warning, getting less guarantees.


While any design requires discipline, ECS systems have little or no coupling between them, and they very easily end up all over the place; in addition to the chaotic design, one ends up also not having an idea of what happens when.

For this reason I agree - developing games using an ECS design requires more discipline to manage complexiy, compared to an imperative one.


I've not had much issues understanding what runs when, because for the most part I didn't need to care that much, and when I did it was possible to order/schedule systems in Bevy. That's even a bit easier nowadays too, since the API improved!

With regards to the chaos: I think it can be avoided, but like you said it requires a bit of discipline. I don't feel like it required that much more than normal software engineering (but I'm also the type of person that documents and tests everything even on personal projects lol). The plug-in system makes it easy to help bring order too.

This is all through a bevy-tinted lens, since I've done very little game dev (dabbled with UE and Godot) outside of bevy, though!


I agree with this - ECS lets you write totally decoupled, composable bits of game logic very easily, which is super powerful. But in my experience if you're not careful you end up with a hundred perfectly decoupled little things and it's really difficult to remember how they actually all come together to make the whole game you've built.

Easily grokable filenames and file structure are very important, and bevy specifically has a pretty nice plugin system which lets you really clearly 100% isolate groups of state/logic into more sensible sections instead of ultimately having some root level game loop that's directly setting up your 100 tiny little poorly named things.


Yeah, I'm one of Bevy's maintainers, and I've seen folks get tangled up (or overengineer things wildly) if they go in without a clear plan. ECS (and a strong compiler) makes things much easier to refactor, but I generally agree that the more flexible nature demands more discipline.


I'm not that familiar with Godot but the built in language always felt like a misstep. Maybe someone more familiar with it can make a defense.

I view 3 users 1. Complete Novice 2. Engineer dabbling in games 3. Professional game designer.

For #2, they are more likely to prefer C# as they probably already have experience with it, or otherwise will be familiar with the similar Java language. Also it's a nice resume boost to say you've used C#

For #3, I can't imagine the godot language is better for large scale games than any custom language. C# just has way more resources put behind it

For #1, I kinda see it. But they would probably be better learning a language with more tutorials available. Or if they're struggling, pygame is probably a better place to start.


Godot has supported C# for a while now. There is no need to use GDScript


Unfortunately Web Export is not supported with C# in Godot 4.X. And probably won't be for a while*. It's the ONLY reason I even bother with GDScript.

https://github.com/godotengine/godot/issues/70796#issuecomme...

And despite my best efforts to statically type everything in GDScript, the language is full of holes that lose all the safety.


I wish that was true. I just started rewriting my project from C# to GDScript today so it can run on 32 bit ARM android devices.

Let's say I'm not a big fan of the language. Why the hell they decided to not implement normal for loops, was just googling how to iterate an array backwards and most people were like "just invert the array and iterate over it, bro"

They should have just used Typescript, it's a sweet spot between safety and productivity.


The docs have an example of iterating an array backwards:

https://docs.godotengine.org/en/stable/classes/class_@gdscri...

    var array = [3, 6, 9]
    for i in range(array.size() - 1, -1, -1):
         print(array[i])
Admittedly not very pretty but it certainly works.


After reading several posts above yours describing the level of effort and pain trying to use this scripting language and how multiple people in this thread avoid trying to use it as much as they can, then reading your small code sample, it's hard to not describe as a level of perception whiplash.

"why god why can't they just have for loops!?!?" and the problem was just ... knowing how to foreach over a range correctly? the idiom and language syntactical preference that python, a language older than java, has done for decades...?

Really trivializes every complaint and the assumed skill level of every person that I see in this thread complaining about gdscript to the absolute lowest level. Thanks for the post!


I disagree.

The doc states that range function returns an Array, so it looks like to iterate backwards you basically allocate array of indices and use those indices to get values from an original array. Not much better than reverting original array, if you will ask me.

Maybe there is some optimization for trivial scenarios, but the referred doc doesn’t mention it.

It really looks like python 2 case when you needed to remember that dict.items() returns copy and most of the time you needed iteritems().


While that's true, the caveat here is that unlike Python, GDScript does not have a garbage collector. The main performance problem with creating an array copy in a soft-real-time application like a video game is usually not the allocation, but the additional GC pressure, which could cause frame jitter. GDScript does not suffer from that latter problem.


This is one of GDScript’s right spots for sure. But if this is the performance bottleneck (in a dynamic scripting language) you’re facing, then maybe that bit of code should just be a GDExtension, written in C++.

I would imagine for most games the performance impact from this won’t matter much.


The problem in this case is not the potential performance bottleneck, but the bad ergonomics for a dev, that leads to the complain. The rest is consequence.

And to me it looks like pure language/stdlib problem. Like for me, the proposed solution looks ugly both from syntax and what is going on behind curtains perspective.

I would rather not to code in a language that makes/tolerates decisions like that.


I mean if this one thing is enough to turn you off, you do you. I find GDScript to be 98% good for a dynamic scripting language.

Personally I’d just reverse the array and then iterate it. It’s going to make about zero difference.

Every language has its sharp edges.


cpython is slow enough that copying the list of keys was rarely a significant bottleneck


I agree! I use both GDScript and C# with Godot, and GDScript is excellent. But, I’ve been programming for 40 years, and my baseline is “all programming languages are bad” :) All I need is a Turing machine with nice ergonomics and I’m happy. I’m very easy to please.


I had high hopes when I saw the yield keyword in the reference, but then saw it's basically just a reserved keyword as they don't seem to actually support generators. I would guess the less eye-bleeding version of all those 1, -1 things is just making a ReversedIter and using that: https://docs.godotengine.org/en/stable/tutorials/scripting/g...


I presume they do for loops the same way Python does? Which takes a couple of minutes to get used to and is perfectly fine. I wish C# did this more like Python to be honest.


GDScript is closely tied to the engine, making it incredibly easy to affect any part of your project. It's also very terse and simple to use, and anyone with a passing knowledge of Python should be able to pick it up in minutes.

I've used C# for my day job for years, but never felt the need to stop using GDScript for any of my projects.


Now I’ve never used it, but there’s always a case with an engine with its own objects to have a language that understands those objects natively.

Unreal Engine started out that way.


UE is going to be amazing (It mean it already is, but WAY more so) once verse is integrated into it.

The "so, you have a choice of c++ or drawing lines between boxes" is missing a lot of middle ground :)


Godot lets you use whatever language you want. C# included.



I don't use godot and know more about its limitations than its advocates in this thread. Are they being disingenuous? Do they just not know basic information about their own tools?


>and "signals", which are meant to decrease spaghetti but only increased it for me.

Signals are basically just event subscriptions. In fact, if you use C# with Godot you can actually just use C# native delegates/events.


And you don’t need to use signals in Godot at all.


Isn't pygame closer to SDL or raylib than a game engine ?


Pygame is a wrapper around SDL.


I'd recommend giving Raylib a look if you haven't. I've been working on a couple small ideas using it lately and it feels very aligned to being a game 'engine' for people who come from a more classic software engineering background.


Try out Stride3d. Sorta like Unity, but pure c# engine and much better architecture.


I'm not sure why you were using Inheritance in Godot? Just use the "gameobjects" paradigm as you did with Unity.


If you need to customize the behavior of certain interactions (such as modifying physics with a specific type of object), you need to subclass since some behaviors are only available as overrideable functions, not as signals. Also the documentation tends to push this approach.


I totally agree for Godot. All the worst mistakes of OOP which I thought we got rid of years ago. Bizarre situation


Godot much prefers composition over inheritance. It's possible to use inheritance in Godot, but no-one recommends it, except maybe for a data structure.


It says game development can be made simple and then throws a whole of jargon at you: clojure vectors, datomics, atoms, transactions, malli schemas...

Can someone explain?


Copy edited their blurb:

Core is an experimental tool that simplifies the process of creating Action Role-Playing Games (Action-RPGs) by providing a unified set of tools and a streamlined approach to game development. It represents game elements (entities) and their properties (components) as simple data structures, allowing for greater flexibility and easier modification. The entire game state is stored in a single container (app/state), making it easier to manage and update the game's data. Core also provides a graphical user interface (GUI) for editing game content stored in a single file (resources/properties.edn), making the development process more accessible to non-programmers. By using Malli schemas for data validation, Core ensures that the game content is consistent and error-free, reducing development time and improving the overall quality of the game.


To be fair, it asks whether game development can be simple. It just so happens that the answer is probably "no".


Game development can be simple, but the game with either be boring (games with thousands of identical rooms are simple to make), or trivial to finish with no replay value (because there isn't much you can do). In the real world games are all complex as making an immersive world requires complexity.

There are a few games like suduko that are about that are simple and yet have high replay ability. If you can come up with another game on these lines great, but such games tend to be very different from the things. Good luck in making an exception.


Betteridge's law of repo descriptions, or something


Mandatory "simple is not the same as easy": https://www.youtube.com/watch?v=SxdOUGdseq4

Clojure vectors are just lists, basically.

"Atoms" are mutable references to immutable datastructures (Clojure is immutable-by-default). You can kinda think of them as pointers, but with specific update semantics.

Transactions are similar to database transactions: mutate several datastructures simultaneously, but only 'commit' the changes if all operations succeed. Roll back and (optionally) retry if any part fails.

Malli schemas are just a way of doing typechecking in a dynamically-typed language.

Datomic is a bigger topic. It's an implementation of a non-SQL database system based on immutable datastructures, in which all changes are appends rather than being destructive, allowing you to 'rewind' the database and view it at any point in the past.


Clojure the language has a built-in state management model, which this project attempts to apply to game development. The best way to learn about this model IMO is to watch the talk 'Are we there yet' by Rich Hickey (author of Clojure).


Well Balatro didn't so it's not hopeless.

I don't think gamedev was ever simple, but I do believe the process can be streamlined. From my experience the biggest choke point (outside of keeping everyone aligned properly) is asset production. Arguably the most important aspect to make games sell, but the 3d asset pipeline has only gotten more complex.

If you can streamline on that (and stay lean as a team) I imagine you can dramatically shorten development.


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


This is common among programmers. They come up with some insane, convoluted set of rules that they happen to like and then declare it simple and elegant. To anyone on the outside it looks schizophrenic in nature.

Of course it has a component system. I just hope no one sees this mess and thinks that if THIS is considered simple, videogame development isn't for them.


Maybe it is simple. I won't truly believe it until they battle test it with a decently involved game.

And I'm not even talking some fancy 3d title. How much would I fight against the framework if I wanted to try and recreate Thomas was Alone or Baba is You? Seemingly simple games but ones with very involved systems and state management.If it can truly handle all those edge cases and saves me times after rampup, I can concede it as simple.


It looks simple and elegant to me, and I've only used Clojure a little before. Perhaps you're just not very experienced as a programmer in anything except mainstream languages.


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


Clojure the JVM Lisp language, not closure the concept I think.

A clojure vector is just a vector. Like a Java vector or C++ vector.

The rest seem to be Clojure concepts or libraries. It's a bit disorienting because the language isn't capitalized in the link.


Have you considered googling "clojure X", where X is each of those things in commas? Other than datomics which has some result pollution everything else has great first page results.


I did, found the clojure docs. Now I'm even more confused. What is so special about clojure vectors - as opposed to a python list, or C array? Some uses in the example seem like a better match to python dict, a C array of structs (linked list of structs?), perhaps a C++ std::map. Depending on what your goal is I know of dozens of different data structures and algorithms (they are part of the basic things a CS major covers) However clojure was called out specifically as if there is something more that is both important to this discussion and non-trival in some way with the way arrays/lists/vectors are implemented in other languages.


The key idea behind Clojure data structures is that they are immutable, but don't require a full copy on update, because an updated version partly reuses the initial version. The data structure that enables this is called HAMT (hash array mapped trie). Clojure's implementation modified the initial Phil Bagwell's implementation of HAMT in a subtle way in order to make performance characteristics not degrade over time.


Interesting, it makes more sense now. Though I'm not clear if you want/need that in a video game. In general you want two data structures, one current state of the world and one next state - since they have a lot of similarity it at first makes sense to do what you say, except the you lose the advantage of vector: it is very cache friendly to iterate on a vector, or even two vectors, while it appears (without knowing internal details) that your HAMT is less cache friendly as the next element is not in the next memory location.

Of course I'd need benchmarks to make a real judgement. The above is my gut reaction.


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.


As a game dev, this GitHub is comical to me. Bordering on parody of the kind of academic navel gazing that game devs stick their nose up at. Cherry on top is the ugly screenshot.


This seems like the wrong site for you, then? Hacker news generally has stories about interesting new ideas. It's not really the place to discuss incremental improvements to C++ and Unity.

I can think of a couple games that sprang from odd academic navel gazing like this. A sibling comment mentioned Jonathan Blow; when I read about this project, it immediately reminded me of Braid. I remember when procedural generation was an ivory tower topic. Hell, every development in 3d graphics started life as a totally impractical paper at a conference. There's a lot of things that are mainstream in games now that were once niche academic notions.

I don't understand the hostility.


To me at least, the great value of this site is that people can and do write their honest opinion. Maybe the style of the parent comment wasn't that good, but I agree with the take that there does not seem to be much of value in the project, it enables a style of game that has been done to death by amateurs and indies, and there are probably better tools out there for making that kind of game as well.

Braid features actual novelty in game design, enabled exactly by not using an engine with a fixed view on how a game works. I don't see how this compares.


> it enables a style of game that has been done to death by amateurs and indies

What style of game is that? I guess RPG? I think that's just because it was a convenient way to demo the concept.

The two interesting things about this, AFAICT, are that it enables mutable state during development in an interesting way, possibly allowing for repl-driven development of running games. That's neat. Like, play the game, get to a point where (for example) the game balance isn't right, and pop into a REPL to make adjustments. And possibly, rewind and replay the scenario in the process to try alternatives, which is related to point 2:

If this is using a datomic-style model, it's presumably keeping an immutable history, allowing for both an interesting development environment (where you can play, rewind, adjust, replay, etc) and interesting new gameplay possibilities.

I don't think anybody is suggesting that game devs should immediately jump on board and start developing on this platform. Again: I don't get the hostility. "Hey, here's a neat little game engine based on unfamiliar concepts." "That's dumb, nobody could develop a AAA game on that today, you should be ashamed for posting it!!" Just...chill out a smidge.


> I don't understand the hostility.

Saying this while telling me this is the wrong site for me. Nice.

My comment isn't hostile. My opinion on this github has value and I am not alone. I could have worded it 'nicely' but if you find every brutally honest comment to be hostile, then maybe this site isnt for you.


I'm not telling you this is the wrong site. I'm suggesting that maybe if you're looking for news on mature, production-ready game development software, with no hobby project tangents, there's probably better places to find it.

And I'm not offended by your 'brutal honestly'. I'm just mystified. You could comment "this is neither production-ready nor industry standard!" on half the posts on this site. Personally, I like being exposed to quirky new ideas, even if they don't always pay off. If I found them actively offensive, I'd have to question why I was wasting my time here.


I think it would've been better received if you elaborated a bit more on why you find it bad. And a bit more on where did it come from (how a gamedev world is compared to it). I mean i can guess what you meant, but it's a bit ambiguous in what way you meant that exactly.


The screenshot is not "ugly", but I agree that the README is functionally useless -- no documentation, no examples, no indication of why I'd want to use this. Fails on a fundamental level to communicate what it's about.


On the other hand, making things intellectually stimulating: even if you waste 100h making clojure datomics in order to make 1h of level content, 1h>0h, and if it were boring and therefore you wouldn’t make it at all, you’ve come out ahead. The “Jonathan Blow uses Jai” thesis of indie development.


it _does_ say it's experimental.


This post has generated a surprising amount of conversation for how little documentation this repo has. Looking at the code this looks more like a project rather than a game engine. The property editor looks interesting. Seems like this post is being upvoted based on the title vs the content.


Kudos to you! I’m happy to see another Clojure developer like me using the language for game development, even though we sometimes make things harder for ourselves :) Currently, I’m developing a 3D multiplayer TPS shooter using Clojure. For anyone interested, here’s a demo link: https://prototype-game.pages.dev

I’ll also be posting a blog post about the journey soon!


It is one of my favourite things on the internet when a bunch of people can go to a virtual space and hop around and use an in game chat impromptu like this. Thanks for sharing.


Thank you for checking that out!


I love Clojure, but isn't a functional language with immutable data structures an odd choice for developing a video game?


It is completely possible and has interesting trade-offs.

Here are some of my favorite blog entries related to functional game development:

https://prog21.dadgum.com/228.html

https://prog21.dadgum.com/23.html

https://prog21.dadgum.com/24.html

https://prog21.dadgum.com/25.html

https://prog21.dadgum.com/26.html


After doing functional programming for a while now (6 years of Elixir) it seems obvious to me that it is possible and no more complex than using imperative logic. In fact I would go so far as to say that managing complexity (i.e. state) is much easier to do in a functional style than imperative.

Functional is all about transformation of data structures, and a game is nothing more than a function that takes {state, mouse, keyboard} as input and returns {new_state, output} where output is a set of Vulkan commands, or pixels that you bitblt to screen. Rinse and repeat in an vsynced infinite loop.

I think the linked articles above betray the fact that they were written 15 years ago when functional programming was a niche quasi-academic idea and no one was used to building stateful programs with it. 15 years ago it was all about Java and C++. Lisp was as forgotten as it is today. In 2024 most above average programmers have experience in functional logic, and it is not that arcane of an idea. The reason that it is not widely adopted is that functional programming is not as performant as imperative semantics, and you need all the speed you can get. On the other hand, imperative often means buggy mess as game complexity grows and painful debugging session trying to understand who and why changed this state variable.


Could an expert strong man the argument that functional programming languages like Haskell could in theory be more performant than C because of the nice properties of pure functional languages?


CPUs are imperative and pervasively mutable. Languages like Rust are able to have so called zero-cost abstractions that are reminiscent of functional programming (iterators for example) but the thing is abstractions are by nature always slower than the real thing.

But not all games are AAA FPS that require ingenious optimized codepaths to perform well, not in this day and age, so this is why you see commercial games running on "slower" abstractions such as C# (AOT compilation doesn't make it less of an abstraction layer), so you can very well design a commercial game in Haskell or Scheme or Lisp or Clojure if you wish. Nothing stops you, apart from the lack of serious game dev frameworks built in those languages.

It all depends on the compiler, really, and it is asymptotically hard to compile functional languages so they perform as fast as C for example. There is no market for "high performance Haskell or Clojure", so there is no compiler that good either.


"Cost" in C# comes from the (ab)use of classes for transient data, virtual/interface calls and automatic memory management. Another source of difference is in compiler capability of Unity's own flavours: IL2CPP, Mono and Burst, versus .NET's CoreCLR JIT and NAOT versus GCC/Clang. However, the latter has much less impact on "application code" and more impact w.r.t loop autovectorization, for which in C# you're supposed to use bespoke portable SIMD API which is fairly user-friendly. For the former, you are not "locked" into a particular paradigm like with Java or Rust and can mix and match depending on how hot a particular path is (for example - construct buffer slices with LINQ because there are only 16 of them, but each one is 512MiB large, so do the actual work with Vector<T>).

JVM languages have a huge gap* in low-level capabilities where-as C# sits next to C and Rust in many of the features that it offers, even if the syntax is different. JVM implementations also come with significantly higher FFI cost. This makes them an overall poor choice for game development. Your experience of writing a game engine in pure C#, calling out to rendering and other device APIs will be massively better than doing so in Java/Kotlin/Clojure/etc, because of both runtime capabilities and ecosystem of interop libraries.

Also, C# has zero-cost abstractions in the form of struct generics which are monomorphized like in Rust, and performance-sensitive code relies on this where applicable in "modern" codebases.

* Projects like https://github.com/bepu/bepuphysics2 are impossible to implement on top of JVM without calling out to native components. This might change once the incubating Panama vectors improve upon their API and what they compile to.


GHC is effectively an attempt to strong-man that argument over a couple of decades, and in short, it failed. It has pretty good performance for what all Haskell is doing, but if you want to write C-speed Haskell you are restricted to a tiny portion of Haskell that you can only understand with deep knowledge of GHC, and based on what I've seen of it, it is completely unrealistic to call it "Haskell" anymore. It's more a language that happens to be embedded inside of Haskell, but unspecified. (Sort of like "the performant subset of Javascript if you want the JIT to do its best"... it exists, but it's undocumented, it isn't the same between engines, and it's very hard to write it without an intense knowledge of the innards.)

The "sufficiently smart compilers" turn out to either not exist, or be beyond the ability of even the smartest humans.

This is not celebration of that, or condemnation that anyone tried. It's a major bummer, actually, and I am suitably bummed. I'd love to have the Sufficiently Smart Compiler. But wanting doesn't count for much. At this point if someone wants to argue that something at a Haskell level of "functional programming" can run at C speed routinely, they need to produce the compiler; we ran the gamut on mere theories.

(I have to qualify it that way because we do have a lot of evidence that you can have "functional flavored" languages that run much more quickly, like O'Caml (at least in single thread) and Rust, if you consider that "functional flavored". But straight-up Haskell does not appear to be able to "just" get transformed to C-speed code reliably.)


Only in some very specific situations, which amount to an arbitrarily smart compiler and arbitrarily dumb C code. Haskell does provide more opportunities for the code to not do something you tell it do because it can prove you don't use the result, but it is a dumb programmer who is writing code to do those unneeded calculations, and thus a good programmer would eliminate them from C.

A lot of effort has gone into optimizing C compilers, Haskell is easier to optimize in theory, but in practice it isn't enough easier as to overcome the massively larger amount of effort put in C.

In the best case for both the code will be roughly the same speed. However the best case for both can look very different and any comparison is suspect as it is likely that whoever wrote the code wasn't as good at one as the other and so wrote bad code.


C is basically portable assembly so handwritten C can be as fast as the hardware can allow.

High-level languages like Haskell can and do approach the performance of handwritten C if you encode enough information to get the optimizations for free:

https://stackoverflow.com/questions/35027952/why-is-haskell-...


>a game is nothing more than a function that takes {state, mouse, keyboard} as input and returns {new_state, output}

but that's a completely convoluted approach to identity in a model for a videogame. The reason Rich Hickey took that approach in Clojure to state and identity is because in the domains he cared about he wanted to prevent the destruction of past state. (he wanted to avoid what he called "place based programming" IIRC).

If you want to implement a git like versioning history say, you really care about any change to state as a collection of individually immutable snapshots. But in a videogame that's completely artificial. Nobody thinks about a persistent entity in a game as a collection of states at a million points in time. It's much more natural and performant to think of your entities as persistent and mutable and you basically only care about where they are now.


> you basically only care about where they are now.

You care about what they are doing now, and what they should do on next render based on the rules of the game and the player’s input. To me, that looks a lot like (state, actions) => newState.

I’m not sure how much of a difference there really is between having objects track their own state vs having them pull their state from somewhere in a single State tree. The advantage to the latter approach IMO is that it simplifies cross-cutting concerns (“player deals bonus damage when all enemies are affected by poison”), and it helps immensely with debugging to be able to query the exact, full game state whenever it’s needed.

My brain has been rewired to find FP easier to reason about than OOP. This won’t be true for everyone, and it isn’t always the right tool. I think it works well for game dev but can be held back by performance concerns.


It's not that artificial, it's basically a traditional game loop where mutation happens in the background between iterations. It has many of the same challenges too.


Coming from clojure I'm very wary of any non-mainstream languages like Elixir, Rust, Clojure etc.

It's a costly business mistake to build your tech stack using any of the above languages. The trade off simply is not significant enough to matter vs using mainstream languages with 10,000x the number of mindshare.


The cost is not paid today, but in the future when whatever you choose is no longer supported. If you write in something like C++ or Java running on Linux or Windows I'm confident that in 20 years you will find a tool that can build your code for the latest computers (not just the compiler, but the other tools as well). Of course Python 2 is a perfect example of why even the highest confidence choices may be wrong.

Rust is starting to look like it will make the jump to likely to be around for the foreseeable future, but only time will tell.

Of course just because you can build it doesn't mean it will work. I know of an embedded system where the 16 bit CPU went obsolete and they discovered that the C code was not 32 bit safe and worse it relied on the timing of the one CPU it was written for (though not so bad as to have to turn off compiler optimizations). I know of a product written for X11 that is porting to wayland. Keeping code running for decades is a hard problem - and one that many fail to understand. (nor do they need to - the web site you do today will need a major rewrite to fit the latest UI fad no matter what you do)


The other two languages GP mentioned, Elixir and Clojure, run on the BEAM and Java virtual machines respectively. I can’t speak to BEAM/Erlang, but your confidence that the JVM isn’t going away should remove any concerns about Clojure being supported in 20 years. It’s just a Java library, and has the same conservative approach as Java of ensuring backwards compatibility.

Clojure won’t necessarily live as long as the JVM does, in that the language could someday be abandoned, but support for its hypothetical last language version won’t be somehow removed from the JVM.


> support for its hypothetical last language version won’t be somehow removed from the JVM.

Why not? Python2 is a good example - if they make a JVM2 without the cruft and then a transition they will leave behind those that don't transition. Of course that is the worst case and I'll admit unlikely.

(also the JVM isn't very relevant to me because I work in embedded systems without a JVM)


You wrote above:

> If you write in something like C++ or Java running on Linux or Windows I'm confident that in 20 years you will find a tool that can build your code for the latest computers

What I wrote was based on your confidence in Java (the language) being around in 20 years. One of Java’s core features is backwards compatibility. Clojure’s implementation will continue to work as long as Java (the language) itself exists. There’s too much business depending on old Java software for the language to break like Python3 did.

Clojure is also a hosted language by design, and has been ported to JS, .NET, and BEAM (though maybe not completely on that one). If JVM2 were to come out, and if it supported garbage collection, it’s likely that porting it will be easy enough for someone to handle the task of transitioning the JVM1 build to JVM2. Implementing a lisp is not a rare hobby, and IMO Clojure’s language design makes it a particularly tasty flavor of lisp.


the biggest tradeoff is talent pool

you won't be able to find them in enough numbers and it would be tough to gauge their proficiency too

unless you are purely interested in it for academic purposes, its best to avoid clojure and any sort of esoteric languages. Even Rust development is riddled with false roads and mirages.

i just want to save anyone reading this 5 years of their time. You don't get better when you are constantly having to re-invent the wheel for essentially shaving off roughly 20~30% lines of code you'd write in python, php, ts. It's hardly a fair trade off


I can teach any developer Rust or Clojure in a couple weeks. I've only done a few hours of Rust study myself, and just minutes in Clojure and yet I will say that with confidence. It takes years to master, but the difference between 1 month and 10 years for an otherwise experienced programmer is not very large - either way the hard part is the problem domain, understanding your code, and other such details not related to the language. HR puts far too high a weight on skills in a programming language, in part because they are easy to measure while the ability to write good code is hard to measure.


The longer I am around the less true I find this. Can any good developer learn and contribute with a new language? Yes.

But there is also a peak performance achieved by using tools for decades that is not transferable. C experts didn’t switch to Java, they found different jobs.

For your core technology you want a few of those 5-10+ year guys.


Sure, but you only need a few of those 5-10+ year "guys". The rest can be behind and will develop those skills over time.


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?


Tim Sweeney seems to be betting that’s the direction with UEFN where Verse is a more approachable take on Haskell.


It's not that weird -- your next AA game or AAA game will probably not use it, but in React (reducer, or Redux), very interactive stuff, immutability is often seen.

Also Clojure has better performance prospects than Ruby and Python, both have seen "real" usage in commercial indie games.


It's a lot easier to embed Python than Clojure. Oldest examples I recall are Severance: Blade of Darkness by Rebel Act Studios, and (coincidence, nothing to do with the previous) Blade 2 by Mucky Foot, about 25 and 22 years ago.


Functional Programming hasn't even been tried for game development, really. There is a lack of overlap between the game dev industry and academia. The studios are (rightly) risk averse and try to use the same broad strategies to build games - OOP, maybe ECS for large swarms, etc.

Personally, I think that FP could be a great fit, but we first need to come up with architectures that solve real game development problems. We have to do this with small scale experiments first (game jams are perfect for this) and then scale up only if they succeed.

This project is exactly that - kudos to the author.


Game programmers are mostly extremely skilled and well aware of functional languages, how they work and what they do.

They aren't using them because they aren't a good choice for delivering games that need to run fast and consistently in real time.

Immutable data structures and garbage collection might be nice for people writing something, but that isn't what someone buying software wants, they want smooth and fast.


High performance real-time games it is questionable. Any genre that is more static turn based can be a great boon.


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?


There's already a commercial platform for game creation called Core, powered by Unreal Engine 4)

https://en.wikipedia.org/wiki/Core_(video_game)


Sounds like a poorly-chosen name. It's already taken by these guys: https://www.coregames.com/create


It was my first thought, specially since their thing is create games inside a game, which could be considered a "new" way to write games


It would be interesting to analyze data of "time/complexity spent on game engines" vs "complexity/interest" of produced games.

As a game developer, I expect to see a log curve of diminishing returns of novel games given any simple templating/engine system.

In other words, the better you make your cookie cutting machine, the less variance your cookies will have.


> The whole game state is stored in one atom: app/state and entities are again atoms inside the main atom (like in our universe).

I don’t know clojure. Is this normal terminology, ie to use “atom” this way? Seems like a bad name for the concept since the whole idea of “atoms” is that they’re indivisible (back when physics thought they were indivisible).


They're called atoms because operations on them are atomic, I think.


Atomic types appear in Java as well, this looks very much like an AtomicReference from a distance: https://clojure.org/reference/atoms


I remember joking 10-15 years about how Sourceforge seemed to have far more game engines than actual games. Is this another one to add to the list?


Interesting! I worked on something similar once. I would recommend you go further and try to do this for 3D/4D. Orders of magnitude more interesting! In my efforts, I hit a wall where it wasn't very interesting anymore.

Also, how about clojurescript so you could run this in browsers?

My user test: https://www.youtube.com/watch?v=gcMBaQI7d-c


> The only thing missing is a game

I've seen this story of "I want to make a game" [proceeds to make a game engine instead] happen in my own life (my engines were never any good or complete though), and in countless other programmers lives.

It may be the trap of thinking that "If I get the hard part out of the way first (which is writing the engine code, right? Right? Anyone?), then the rest of the game making process will be easy" that gets me.

Or maybe it's finding out along the way that it was more fun to make the engine than the game itself: "check it out, I completely redid the particle effects and I can now do 100x more particles at 60fps, how cool is that?"

There's way more easier-to-see improvements in the making of the engine, than in the making of the game itself, and so we (ok, I) keep optimizing the engine because those are quick dopamine payoffs compared to the slower payoff of having a polished game that's actually fun for the target audience to play. Sure, I might tell myself that the game I want is only possible once I have the engine first, so I'd better concentrate on that before making the actual game, and there's some logic to it. But without a clear idea of what the game will actually be, it's easy to fall into the trap of endlessly adding and refining features, rather than actually try and use those features in anything beyond a slick demo.

To combat the tendency of only making an engine rather than a game in my latest hobby project, I picked an already existing engine (Phaser js) and tried to get something interactive on the screen ASAP "with the stupidest, least designed code possible", and it mostly worked to get me a playable (ish) game! Granted, it's a knockoff puzzle game but hey, I sometimes find myself "playtesting" it instead of what I should really be doing, which is refactoring the code for what I'd like to have it do next, so I'm marking it as a win.


Indeed, making an engine is a guaranteed reward. You put in time, make an engine that can draw something, and you succeed, receiving a dopamine reward. But making a game is really risky; a programmer may put in a lot of time and hope, then still fail. I think lots of programmers don't want to take the risk of failure.


No relation to the Core Games game kit.. thing..

https://coregames.com/


Making games has always been simple. Making engaging games is what requires a little more work.


i am going to check it out, thanks for sharing!

I am learning Clojure and would love to use it for some hobby game-dev, but I have not found a way to compile to html so I am using Godot instead. Not really in awe of the OOP approach though.


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!


Are there any games that are playable right now implemented in Core?


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


Superb username


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


can you please elaborate?


Does nobody use cocos?


Used it for some small game jam games. It did its job adequately (i used the c++ wrapper), felt very stable even as far back as 2016 or so. But it wasn't exactly a tool I'd eagerly reach out for again if I had a small game idea.


for the love of god do not use clojure for game dev

absolutely not recommended even for solo

i would not recommend it for any sort of web app either

clojure/atomic is ovverated


; set max speed so small entities are not skipped by projectiles ; could set faster than max-speed if I just do multiple smaller movement steps in one frame

jesus wept. sweep. c'mon.


I thought this was something to do with RPG Maker[1].

They (you?) should change the name given the obvious trademark and general confusion issue.

[1]: https://www.rpgmakerweb.com/


It's like calling your project "engine" and telling people they can't call their project engine


What about calling your project "GameMaker"? Is that taken?


I think it's a "Maker" that happens to make "RPGs", not a "RPG Maker" engine. A bit like you could still call your shop a "photo shop" if there are photos for sale there.


Do I have to change the name ? Given it's just an open source project and the name is actually just 'core' . It's an rpg maker tool and functional engine.


No. By the power vested in me, I hereby permit you to keep your project's name, and to point at this man and laugh at him.


A name has to meaningfully differentiate amongst its peers, which calling an RPG making tool "RPG Maker" when it's not associated with the brand clearly does not.

It is (was) marketing failure and an unnecessary legal risk if this gets bigger and comes up on Enterbrain's radar.


[flagged]


https://news.ycombinator.com/newsguidelines.html

>Comments should get more thoughtful and substantive, not less, as a topic gets more divisive.

>When disagreeing, please reply to the argument instead of calling names.

>Please respond to the strongest plausible interpretation of what someone says, not a weaker one that's easier to criticize. Assume good faith.

>Please don't post shallow dismissals, especially of other people's work. A good critical comment teaches us something.


only the owner of the copyright can make you change, however, being able to search for articles, tutorials, bugs, solutions, etc will be easier if you give it something unique


> only the owner of the copyright

You meant trademark, not copyright. Otherwise, your point still stands.


I am actually also open for names, I don't know exactly what this thing is.


Maybe change your wording to "an RPG maker", as "RPG Maker" is already an established brand.

As for names, maybe something cute like ClojRPG?


But I don't know exactly what this thing is. I have coded like crazy on it and created a new component system & datomic-like transaction-data like effect system, so it is more than just an RPG maker. Its a whole new way to write games.

For example side effects are just vectors of `[:tx/foo param]`.


Then maybe something more generic sounding like ClojEngine? Naming is hard lol. Core is fine, but maybe add one more word to it, because googling just "Core" to find your repo is difficult.

But I highly recommend changing the capitalization of Maker to maker to avoid being mixed up with the product RPG Maker. Adding "an" helps signal that it's a descriptor instead of a name too.

Core: An RPG maker and engine for Clojure.


GamesCore - generic but serviceable name.

CrystalCore - because RPGs must have some sort of magic crystal, it's the law

CreataCore - why limit the name to RPG theme in case it develops into something larger?

Just a few quick name suggestions for OP.


If it aspires to become like Unity you could maybe call it "Clunj".


>It's an rpg maker tool and functional engine.

Proper grammar would be "an RPG making tool".

Additionally, you deliberately wrote "RPG Maker" rather than "RPG maker". Capitalization is important, kind of like how "US bank" and "US Bank" mean completely different things (former is a generic reference to an American bank, latter is the name of an American bank).

So yes, I would change the name if I were you (and you have from what I can tell, good job) because it's infringing upon the RPG Maker brand and trademark but most importantly because it's just confusing.


> Additionally, you deliberately wrote "RPG Maker" rather than "RPG maker".

I think HN automatically converts post titles to title case. (There's a short window of time to manually edit the post title to fix the capitalization.)


I am referring to the README.md that's in the repo, which originally stated "RPG Maker&Engine for Clojure"[1].

I really don't think it's unreasonable to assume this had something to do with RPG Maker when it was written like that.

[1]: https://github.com/damn/core/commit/72682f512343c596bce84f0f...




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

Search: