But I just wanted to comment that you don't need an "Entity Component System" in a game, and especially not for a very simple not-yet-a-game like shown here. (You also don't need inheritance or composition).
It bothers me that so many people are buying into this hive-mind marketing on ECS, when in reality it is just overengineering + procrastination in almost all cases.
(None of my games have ever had anything as complicated as a component system).
If you want to make a simple game like this, just sit down and program it in the obvious way. It will work. You don't need to be fancy.
Like you, I've seen both sides. Unreal lineage evolved from inheritance-based into ECS-like. Frostbyte is heavily ECS.
Googling... the author is ex-amazon, ex-microsoft - with xbone and 360 title experience. Perhaps the author was exposed to that pattern at one of those institutions, or perhaps the author saw the 2018 Rust Conf Closing Keynote and was inspired to continue down that path.
I think people tend to either go with what they've seen work in the past, or heard works well. Maybe it's cargo culting, or maybe in the case of rust (which I have no current experience with), it helps? Either way, the most important point is to focus on the fun and not let technologies get in the way of making a good game.
 - https://www.youtube.com/watch?v=aKLntZcp27M
It's definitely fun to play with new programming languages and technologies. Using games as a medium to explore a new language is a great way to learn and have fun at the same time. That said, when a game development luminary like jblow takes the time to make a comment, it's good to think about why.
It seems to bother jblow that people are buying into the use of this system without thinking about the costs as well.
Its the same as the debate about when it is the right time to move to a distributed microservice architecture from a monolith. In this case, the use of an Entity Component Systems in a small game could be compared to the choice to use a Distributed Microservice Architecture for a small application.
Monolithic applications are easy to build and maintain by a small solo developer/shop, but they don't scale as well as you increase the number of engineers and expand the scope of the product. So a monolith is split into domain specific distributed microservices to allow for an increased number of developers working in parallel. When you pick to employ this tactic is up for debate.
Building a distributed system is hard. Debugging a distributed system without solid tooling/tracing is even harder. In the microservice world we have a lot of tooling to help us. Games, usually much less so. Where you might use GRPC in microservices and have stuff like OpenTracing to lean on, in games with Entity Component Systems you'll usually have some form of a message bus/event system without the same level of tooling and tracing.
Entity Component Systems/Distributed Systems are a useful pattern to implement when your desire is to build a reusable generic game engine/application to be implemented by large or scaling engineering teams. That's why you see these patterns employed and used by large game companies/startups and game engine/SaaS developers.
In summary, perhaps jblow's point is that small/solo developers can build a good game/application without employing the ECS/distributed microservice architecture pattern. And like you said, it's also useful to try building/using these patterns in toy applications to gain experience.
While building a game using some inheritance based approach, one will quickly hit limits even with a single engineer, whereas a monolithic web app can scale to a team of a couple dozen engineers easily.
Please stop saying this stuff as it just contributes to the general confusion.
I have heard that the restrictions imposed by the Rust compiler make it surprisingly hard to get it working the normal way. The first time I heard of ECS was in a Rust talk about how it helped them stop fighting the borrow checker.
This is mostly for complex games, otherwise for simple stuff there are ways to get it working.
A full-fledged ECS can in fact be very helpful when writing game jam style code and you need to quickly iterate on ideas. Separating each unique idea into components (health, movement, ammo) and systems (physics, damage, AI) lets you turn things on and off, add new things (powerups that work on anything with health!), remove old things, all while everything keeps working in general. Closer to the end of a game jam you can also start playing with novel ideas (what if I make all bad guys suddenly start considering each other as enemies?)
I think the debate here came down to whether a person who is inexperienced with either strategy for making a game is much more efficient with one thing or another, and I can't say that for sure. But I can say that in my experience the ECS pattern has had benefits for quick prototyping and experimentation, and shouldn't be dismissed out of hand in such a scenario.
As another example of this: I just bought a big DAW and a midi keyboard, and now obviously I'm stuck coding audio filters in Rust rather than making music.
I'll mention that rust is young for this (e.g. VST dev), so if you don't want to learn rust but just want to get something finished - then Rust is probably not what you want. It's great for audio programming but the GUI buits are still immature.
However, I started with a simple stupid solution you describe. Despite that, I quickly realized I was going to end up coding an ad-hoc version of an ECS if I keep trying to do my own thing.
For reference, I am making a sim game like dwarf fortress so it has been kind of nice, though I think in the fullness of time I will probably end up writing my own ECS to replace specs or start contributing stuff to it.
I have used unity and UE4's "ECS" and I could see how they get a bad wrap. They aren't very good ECS systems and because the engine uses this model it forces people to use it.
One of the big advantages of writing a game from "scratch" is you are not burdened by weird architectures that don't make sense so experimenting first before makes sense. I don't know if I agree that ECS never have a place in game programming.
Lots of interesting game-jam entries cranked out quickly using "pure" ECS : many small components, many small systems. Playable versions of some are here - http://www.mostlyoriginal.net/
Next thing I did was in Pyglet, this time I used Scene objectes that represented a statemachine that could switch arbitraily between other scene objects. Was much more comfortable to work with but slightly more complex. But where the real difference showed up was when I tried to extend: in the first thing I basically had to have all the code in my head, in the second I could just inherit from the Scene Class and make a new one with completely new rules.
If I were to do something now I would give a ECS a go, especially in Rust which really lends itself to ECS. I don’t think a ECS is any more complicated than relying on Object orientation. The problems you will have to solve with OOP will get incredibly hairy incredibly fast and I say that as someone who came to Rust from a OOP background.
Of course you can just use my first approach and write a huge loop with a lot of if else clauses and deal with every new thing in a new way.
This is the way I’d recommend it to a real beginner, who cares about pixels on the screen and doesn’t mind if they have to rewrite half of the code if they want to change or add a tiny detail.
Usually it's for this kind of project:
It's easy to try something new all the time, but it is tough as nails to stay with something even in the many cases where it sucks and gets difficult.
Finishing something is it's own reward though, so even though it's tough it's always worth it.
While that may be obvious to you, it's not obvious to a lot of programmers (myself included) who grew up learning about object orientation, abstractions and modelling behaviour on the real world. ECS's for all their added complexity come with the breath of fresh air that is classical imperative programming where all the data is just available.
There are scant few sources for learning this, Handmade Hero being a notable exception.
There is CS literature about component oriented programming.
That's not at all what ECS's are about.
On my job, I work on a Unity3d-based match3 mobile game. I am constantly running into game logic as a performance bottleneck – modern match3 games with "live" boards that you can play on while they flow is a combinatorial nightmare sometimes. Obviously, I can't rewrite already released project to take advantage of ECS, but I constantly toy with it in my free time so we don't run into the same problems in the future - without any desire to make a complete game with these toy projects.
If you're having an area of code which has a performance problem and can be isolated into a tight loop, the new Unity ECS is probably a good choice, but only in the specific context of Unity. And not because of the idea of "entities, components, and systems", but because the Unity ECS comes with a "toolbox" that makes it simple to run parallel code over flat arrays of structs, and with a limited C# subset created for writing high-performance code.
But it's important to note that outside of Unity, or other "behemoth engines" you can get close to that performance with a lot less effort, just by using a sane data layout and running your code in a simple loop (instead of running the same code in lots of tiny pieces interleaved with unrelated code, as is often the case with "traditional" entity-component systems.
EDIT: I should note that I am not accomplished as a game developer at all, so take my advice with a grain of salt.
I look forward to supporting more of your work in the future, and introducing my SO to your puzzles.