Vigorous writing is concise. A sentence should contain no unnecessary words, a paragraph no unnecessary sentences, for the same reason that a drawing should have no unnecessary lines and a machine no unnecessary parts. This requires not that the writer make all his sentences short, or that he avoid all detail and treat his subjects only in outline, but that he make every word tell.
— "Elementary Principles of Composition", The Elements of Style
I know no disrespect was meant, but calling an artist talented disregards the hard work that went into developing their skills. Unless you are talking about someone's unrealised potential.
If we read their comment assuming good faith, a Hacker News guideline, its clear they are merely trying to give credit or otherwise say something positive.
I started the post by stating that I know no disrespect was meant.
It is precisely in this context that I want to clarify how this very common way of expressing artist appreciation can, and often does, rub the recipient the wrong way.
Anecdotal, but I wouldn't be sharing this unless I knew they many of my peers artists feel the same way.
New game engines and ECS frameworks are cool to see. Taking a look at the ECS part, Bang, here's an example of a component abridged/adapted from their Ludum Dare entry:
internal readonly struct CarComponent : IComponent {
public readonly float Speed = 100f;
[Slider(1,20f)] public readonly float Mass = 1;
public CarComponent() {}
}
and of a system:
[Filter(typeof(CarComponent), typeof(AgentImpulseComponent))]
[Filter(ContextAccessorFilter.NoneOf, typeof(DisableAgentComponent), typeof(CarEngineStoppedComponent) )]
internal class CarMoverSystem : IFixedUpdateSystem {
public void FixedUpdate(Context context) {
foreach (var e in context.Entities) {
var car = e.GetComponent<CarComponent>();
Vector2 startVelocity = e.TryGetVelocity()?.Velocity ?? Vector2.Zero;
var result = DoSomeCalculations(car, startVelocity);
e.RemoveFriction();
e.SetVelocity(result);
}
}
}
Looks a bit like DOTS (but I haven't really tried that one either). A system is a class, and which interface it implements determines when it runs. Haven't seen yet where systems are get added to the game / how systems of the same kind get ordered. I'm also curious how a system that does multiple different querries (e.g. one for cars and one for obstacles) looks like.
Bang seems to use source code generators – unlike the generic GetComponent<T> above, TryGetVelocity, RemoveFriction and SetVelocity seem to be generated based on the existence of the Velocity and Friction components. I'm not sure why that is, maybe to cache the component id?
This isn't an archetype-based framework, instead each entity stores a dictionary of component id => component and each system tracks what entities match (also, each entity stores hooks for e.g. when a component gets added, which is used update which systems know about this entity). I don't know how good that's for performance, but for plenty of games performance isn't as important as ease of development.
Also looks like changes are applied immediately. Does this mean that if a system add/remove a component to an entity that affects whether the entity matches the systems filter, it depends on the entity id whether the system processes the entity the same tick?
Curious about this too - it can be frustrating to manually have to add new systems to a fixed list (the amount of times I've got stuck into building a system, then wonder why nothing's happening at runtime - because I forgot to new() it and add it to the system group!), but at the same time, it's often important to fix at compile-time the order that systems run in as they can often be implicitly dependent on each other. I didn't see anything in the docs from a glance that would allow this dependency/ordering to be explicitly marked, so I'm curious to see how it handles this.
Very nice. The editor is very stylized, I like it. I’ve always liked monogame because it’s performant and cross platform, though I’ve never made huge games with it, just a demo here and there when I get the itch.
I've had strong success with trivial object management & explicitly invoking GC on a delay that is some small multiple of the simulation delay. The sweet spot seems to depend on scene content and style of gameplay (how the scene objects are mutated). For Q3A-style scenes and gameplay, it is extremely robust. Very few scene elements change tick by tick, so GC pauses are mostly irrelevant.
More specifically with .NET6+, I am seeing GC pauses measured in the 1~5ms range in my DIY engines when I strategically call GC.Collect() on a rapidly-recurring basis. Another tweak I made was to disable concurrent/server/background GC in the project config. Foreground+workstation GC appears to provide the lowest jitter in this arrangement. My engine's main loop operates on batches of events pulled from a ring buffer abstraction, and if one of those events just so happens to be a scheduled GC, then I deal with it right there in-line on the same thread. I do not attempt to defer it to a GC thread or some other weirdness.
The only strategic options seem to be to either explicitly manage all the memory 100%, or take out the trash as often as possible. You could also entertain the cruise missile GC strategy, but Microsoft has made it nearly impossible to completely disable GC in latest .NET without employing black magic low level DLL hackery. I can definitely see a situation where you don't care about GC because you can just recycle the process between business events, rounds of gameplay, etc. Process.Exit() is a viable GC technique in some domains.
Yes and here is a really great talk from Miguel de Icaza about some of the history of adding C# to game engines, and why he's excited about using Swift in Godot because he claims that Swift's reference counting avoids the issues of GC pauses.
Note that GDScript (the primary scripting language for Godot) also uses reference counting for its memory management, so it doesn't have the GC pause issues.
This isn't just a language-specific feature and is actually one of the core design decisions made in the C++ engine. Almost every object in Godot inherits the RefCounted base class - as a consequence even in C# scripting mode Godot-specific objects generally have reference counting semantics (and therefore also provides the WeakRef type to deal with reference cycles yourself.)
> Note that GDScript (the primary scripting language for Godot) also uses reference counting for its memory management, so it doesn't have the GC pause issues.
This is a great point, and something someone pointed out in the Q/A portion at the end.. I don't think Icaza cared though, he seemed very motivated to slay the dragons of his past and make good after working so hard to integrate C# into Godot.
De Icaza suggests that the GC hasn't improved sufficiently even in the modern .NET era, and maybe that's true in certain cases. But in practice, dozens of big-budget 3D games have been made with Unity, using a janky old Mono runtime that performs far worse than .NET 8.
Swift is a really interesting language, and Apple does distribute official toolchain binaries for Linux and Windows. But yeah it's still a bit of an awkward choice if you're not using Xcode, hopefully that improves.
I agree here, and I think Icaza is just motivated to make something for himself, because as he explained in the talk, he loves Apple products and APIs.
Swift cross-platform would be a great thing.. I see that The Browser Company is using it for their browser project [0]. It's got a good mix of speed and ergonomics, and Apple seems hell bent on using swift for everything, even at the kernel level (I can't look up sources atm but Sean Parent has said this on ADSP podcast, and you can see the various talks from C++ conferences about swift as a "successor language"). You're right though, Swift is always going to be beholden to Apples whims, just like C# and Microsoft. I feel like Rust has the best shot at being "the cross-platform language to rule them all", but it has a long way to go in terms of being as ergonomic as Swift or C#.
Modern GC implementations offer an important advantage - very cheap allocations and batched deallocations which allow to sustain high allocation traffic that goes through the heap.
This comes at a cost of non-deterministic memory usage and object de-allocation. Further tradeoff is made between GC pause times, allocation throttling (Go) and even higher memory footprint (ZGC).
My knowledge on the exact overhead of Swift's reference counting is very limited but there's a good chance it comes with significant upfront cost that you don't have to pay in languages with GC or with compile-time-defined allocation semantics (Rust and C++ RAII). There's a reason why Apple invested in atomics being as cheap[0] as they are on their ARM64 cores.
Overall, every time I find Swift benchmark numbers on the internet, they turn out to be far[1][2] from near-Rust performance despite being a language built on top of LLVM.
I wonder how much of the extra issues Unity has is because it is a very old version of Mono, since more modern versions of .NET have become so much more performant (especially Core 3.1 into 5+). I was sad when .NET 8 came out too late for Godot to fit in the update for Godot 4.2, so I believe they intend to make the update for 4.3.
Unity is leaving quite a bit on the table by not being on a modern version of .NET. Unity's C++ side seems to have (or had) assumptions about the garbage collection. Progress and challenges on .NET in Unity can be seen in this frequently updated forum thread https://forum.unity.com/threads/unity-future-net-development...
Unity's long term plan appears to become more tightly integrated with .NET and to avoid maintaining their own .NET stuff.
Yeah back before I switched to Godot for my game dev dabbling I was keeping an eye on info about the upgrade to a more modern version of .NET, but I got less and less interested and saw Godot 4 was going to have .NET 6 out the gate so just switched (and all of this was before Unity went full idiot which fully removed any interest I have in going back).
In .NET, GC is triggered when a user thread runs out of memory in an allocation budget and needs more, similar to what you described [0].
Generally speaking, indefinitely preventing GC from running is not possible (you always end up putting some data on the heap) therefore an optimal strategy is similar to any other language - limiting allocations and reusing memory through object and array pooling. This will ensure that GC pauses are as infrequent and as short as possible. It's important to note that if there is sufficient allocation budget - the GC will not run.
This way, in a well written code the GC may only ever trigger every few hundred frames and only take a millisecond to run. In fact, OSU! has been able to get consistently good frame times even back on .NET Framework.
My experience with Unity on consoles is that it is very much an issue but can be avoided with some careful architecture choices very early on in development. If you are not careful about allocations, the reserved managed heap size grows and GC pauses quickly deteriorate the experience. There’s also no way to reclaim memory and very soon you’ll have a giant C# heap with not enough memory for native code in engine to load textures etc. This is very hard to recover from, hence to need to be vigilant from the start.
I've a bit of ECS experience in Unity, and I found ECS in Murder much easier. The devs have done an awesome job. I
made a small arcade game project with Murder
https://nopetrides.itch.io/bombs-away that is available to play
Unity has a ton of extra layers since they are trying to support a mixed game world with both game objects and entities.
In order to make a entity from a game object, you have to bake the game objects using something called "authoring". You also can't debug any of the entity stuff visually, only using some tools that display information about the current world state and number of entities. You can't click on entities to drag them around or inspect them.
In Murder, the editor lets you set up your sprite with hit boxes and entity components similar to working with Unity prefabs, but you can just drag those into the game world "scene" and they are already entities ready to go. Any systems will include the entities that it filters for without any additional steps. All you need to do is write the scripts for the components and systems, then add the component onto an entity into the world and add the system to the list of systems running in the world. Not to mention doing all that dynamically with support for more complex implementations.
TLDR; ECS in Murder is just regular C# with some different context. Learning ECS and using it in Unity was like a whole other world even for an experienced Unity programmer.
But is it widely used? Stable? Popular? Really nice to use? Actively developed? Is it infrastructure that other higher level tools build on, or is it like unity?
It’s a reimplementation of Microsoft‘s popular XNA framework that was used for a number of successful games. Monogame itself has been around for a while and my impression is that it’s a mature and stable project. I would put it in between libraries like SDL that are often used as infrastructure and full engines like Unity.
not by major game studios anymore but plenty of very popular indie titles use it, yes, yes, yes, yes, its a framework/sdk that comes with everything you need to make a game, though its more a code first model so it isn't "editor-centric" like unity.
- is quite tasteless, less so if murder is mainly something you see on tv, but for some people murder is sadly much less of an fictional rare thing
it it would be a game, story etc. which has that name and covers that topic it would be fine but naming something pretty unrelated to that murder is just quite a bit of tasteless and unnecessary edge; if it had a flock of crows as a log it would at least be a funny joke
Nobody is googling "Murder" looking for a game engine and being disappointed that they can't find it. If you search "Murder Engine" this is the first thing that pops up.
> - is quite tasteless, less so if murder is mainly something you see on tv, but for some people murder is sadly much less of an fictional rare thing
I have an immediate family member that was brutally murdered. I also have no problem with the name of the engine. Of the things to take issue with, this seems silly. You would hate LOVE2D which has libraries famously named ANAL and LUBE.
To clarify I find it tasteless and edge, i.e. a bad choice. This doesn't mean I have a problem with it, nor does it mean I'm offended by it or think others would be offended by it or hate it or anything like that.
I also am not sure why you think I would find LOVE2D tasteless. The name has a clear connection to what it names, it paints a clear and positive picture and has a slightly less obvious joke in it onto which they then double down by how they name some of their libraries. That has style and taste.
But murder is lacking all of that, or at least it's too non obvious. This disconnect between the name and what it is/the picture it paints is why I called it tasteless and edgy. It feels like there was either a lack of ideas or it wants to edge on and provoke but the picture this paints isn't beneficial/good for a 2d game engine in any way as far as I can tell. Even comes with a (small) to cause harm and require a renaming later one.
> To clarify I find it tasteless and edge, i.e. a bad choice. This doesn't mean I have a problem with it, nor does it mean I'm offended by it or think others would be offended by it or hate it or anything like that.
If it doesn't bother you and you don't think it will bother others, how is it tasteless?
> The name has a clear connection to what it names
So Murder Engine is fine then.
The desire to clutch one's pearls in disgust over any little thing is showing up a lot in this thread, I think.
> one's pearls in disgust over any little thing is showing up a lot in this thread,
not really, but I guess arguing with you about it is pointless as you are either ignoring or not understanding the points I am making and instead try to exaggerate things by implying that finding something tastless means much more then it does
except that I did explain, but you just pretend that part doesn't exist
and somehow after I did you started becomming all provocative and manipulative in how you phrased sentences so that it seems I sayed/mean/think things I do no
so idk. by I don't think I'm the person with the problem here
You're being weirdly aggressive about this. I think they explained themselves pretty well. I don't agree with them at all but they have said how they felt and why.
I asked a clarifying question and then made an assertion about a behavior. I personally wouldn’t call that “aggressive”, but to each their own I suppose.
> I have an immediate family member that was brutally murdered.
Ah yes, I remember electing you to represent people with brutally murdered family members at People With Brutally Murdered Famiky Members Anonymous.
Love2D is cute, Murder, ANAL, LUBE are tasteless. Maybe deadbeef is too. It's fine, it is what it is, bad names are sprinkled everywhere. Let it be known as tasteless. It's OK.
Presumably the members at People With Brutally Murdered Famiky Members Anonymous don't have that much of a problem doesn't already have a problem with the non-consensual homicide depicted in most videogames?
Of all the things to get triggered by...
Personally I'm glad that there are still projects with names not chosen by the public outrage committee and then approved by the ad-friendlyness commission.
Never did I claim to represent everyone who has had atrocities happen to them. I'm just giving a data point that not everyone who has had someone murdered recoils in disgust at the sight of the word. Taste is a matter of opinion. The person I replied to happens to think that ANAL and LUBE are perfectly fine as they thematically match the name Love2D. You think it's tasteless. All valid opinions.
yep, I'm also never said anything beyond me not liking it in a specific way. Through given how the internet tends to be I could have been more clear that I'm not offended, neither think it will offend other, neither hate the name etc. etc. people just love to jump to conclusions.
It's just that it looks like a very promising project and bad names can easily come back and hunt a project iff it has become much larger and more successful. So it having in my opinion a bad name felt like something which isn't irrelevant.
I think that the name is too generic and popular. You see "murder", the word, in most news outlets, vast majority of movies/games/etc. - any media.
Sure, you have "Unity", "Unreal", "Godot", ".NET" and etc. but I would argue that they are distinct and unique because they have some heavy-weight organizations and popularity behind them. I also think that they are not on the same level of generic use as "murder".
This engine's name, however, will have to compete with the generic "murder" that is already used in various different contexts. Surprisingly, you can still find it as top result if you search "murder engine" so they got that going for them.
Still, would of preferred if it was maybe some variation of "murder" word if they want to stick with that.
Agree it's terrible SEO but eventually "Murder engine" might be decent enough.
At least it's edgy or lol or punk or or whatever box it ticked.
The beauty of having the freedom to do whatever and see what it does for you.
Man I hate to make this sort of comment, but is this a good name for this engine? I’d hate for a demo to get pushed down because a YouTube / Google algorithm doesn’t like it.
ehhh its a cute name playing off of the "murder" of crows theme, I like it, makes the theme feel cohesive. Also I don't get the focus on making sure you have the perfect SEO for every side project, seems like a good way to not get anything done.
I like the occasional HN troll as much as the next guy, but I’m afraid that it wasn’t a joke. The page has screenshots with big fat pixels and says it’s an ECS game engine so I assumed it was, well, a game engine for the ECS. I since learned that ECS has another meaning that I wasn’t yet familiar with.
I might’ve realized this wasn’t for the Amiga if I had read the page (or looked at the screenshots) better though.
Since engine is targetting pixel art, isn't ECS a bit of an overkill...?
And yes, technically artstyle has nothing to do with game architecture.
But in practice, most games of this style are pretty small, and thus don't really have any real performance requirements, so ecs'ing everything is overengineering compared to oop-style, coupled architecture, no?
One of the commonly mentioned performance advantages of ECSs is the structure of arrays style, which Murder isn't using, so I'm guessing that they're using ECS less for performance reasons and more because they favor the programming style.
Hugely popular little indie game Vampire Survivors, for example, requires some thoughtful optimization to have a zillion objects on screen without lagging to death. ECS isn't the only answer, but it is a valid one.
I think Factorio is a better example; items still exist when you don't see them on the map, and assuming you have a somewhat optimized base the performance is very acceptable until you are around 383k items/s being created and destroyed (50kSPM in the in-game parlance).
Do they have to? Couldn't you come up with some chunking based system where the game only monitors the 'inputs' for given area and as long as those are stable, skip simulating entire chunk and only generate the output?
* a mechanism to constantly evaluate whenever a active chunk is worth promoting to a "hibernated" chunk, with its overhead and;
* a very steady state factory chunk. But endgame steady state factories already overperform your average factory by a lot in the first place.
It is the chaotic state non-endgame factories that currently need optimizations the most. And it is speficially them that don't reach steady state; one small moment of instability in the inputs and you need to start evaluating the state of your entire factory again.
I think that clustorio or the next expansion approach, where you have several "surface" maps that each have well defined limited I/O interfaces "chest or spaceships", in a way that you could split off the massive state of the game into a cluster of smaller servers is the way to go.
> But in practice, most games of this style are pretty small, and thus don't really have any real performance requirements, so ecs'ing everything is overengineering compared to oop-style, coupled architecture, no?
I would call out that "performance requirements" those days aren't just "it runs smooth enough for me". It's also about "it doesn't waste all my game device battery". I appreciate when you can run games for 7 hours instead of 2 hours on a mobile device.
More that pure CPU/GPU use, the main battery life villain for your average software is horrible memory access patterns.
Doing logic or math (even including FP math) is basically energy free compared to fetching data from DRAM or SRAM.