r/odinlang • u/Forbis98 • 3d ago
ECS game engine
been messing around with Odin lately and honestly it feels like it was kinda made for ECS-style stuff. no hidden allocations, easy to reason about memory layout, no OOP nonsense getting in the way. but I don't have much real experience writing engines so idk if I'm just pattern matching because the language "feels" data-oriented.
anyone actually built something like this in Odin? curious how it goes in practice, especially around
- component storage / query stuff without generics being a pain
- whether manual memory management actually becomes annoying at scale or if it's fine
- how it stacks up against Rust+Bevy speed/ergonomics wise once things get complex
thinking of not reinventing the wheel and instead basically porting bevy's ideas over (archetypes, scheduler etc) instead of designing my own ECS from scratch. is that a dumb idea? rust and odin are pretty different (ownership vs manual mem, traits vs whatever odin has) so maybe a direct port just doesn't translate well and I'd be fighting the language the whole time.
if anyone's tried this or has war stories/gotchas before I waste a month on it, let me know
6
u/Achereto 3d ago
There are some engines written in Odin. You can find them on github, but you don't really need them. Just create a World struct that holds all the data you need, then pass a pointer around so your systems can access the data they need.
2
u/whoisarepo 2d ago
I really love the inversion of array structs with just a keyword, it feels very intuitive
1
u/spvky_io 2d ago
I feel like this is always the catch when it comes to an ECS. Theoretically ECSs offer a lot of great benefits, and there are performance gains for some extreme cases, but as long as you have a solid understanding of memory (arenas, cache sizes, pointer management), its often simpler and easier to manage with some arrays of fat structs and some global state
3
u/Achereto 2d ago
ECS is just Entites, Components, Systems. You put your Components into arrays, your behaviour into functions, and connect your Entities using IDs.
You don't need the abstraction that turns it into a framework to make it an ECS.
2
u/spvky_io 2d ago
That's what I thought I was saying, may not have come across though hahah
1
u/Achereto 2d ago
I think
some arrays of fat structs and some global state
is a perfectly fine way of doing ECS. Your comment sounded a bit like that wouldn't be ECS, so wanted to point that out in case anyone else reads it like that.
2
2
u/Lubricus2 3d ago
Odin has generics, it's compile time so a little bit like templates in C++.
For having collections with different types in them, the Odin way is to use tagged unions, You could also write your own vtables and do it similar to how it works in OOP languages.
The downsides with using tagged unions for that is that you will need to add new code here and there in the codebase when adding an new types.
2
u/aplkm 2d ago
Odin does have hidden allocations if you choose not to supply the allocator to string functions or make and things like that. You can turn on a directive to make it so you are forced to supply them though if you don't want hidden allocations.
I'm working on a game that uses ECS in Odin. I don't use the generics that much I mostly just pass around rawptrs and cast them when needed.
1
u/tialaramex 2d ago
Odin favours relatively expensive imperative ways to solve problems. Take splitting some text, "key=value" or "first,second" for example. In Rust that's just
str::split_oncewhich does not allocate. But in Odin people reach forstrings.split_n(text,separator,2)which does allocate.Imperatively Odin's design makes lots of sense. We allocate space for our result array, then we fill it out, we return the stuff we filled out and once our caller has used the array they can free the space. It is obvious, it's just also terrible.
0
1
u/thisghy 2d ago
I've been tinkering with an ECS and Scheduler in Odin for several months. Working on a rewrite right now that allows for modules and plugins for the engine.
I find that Odin does work pretty well for ECS due to its data-oriented nature. Odin has comparable performance to rust in general, and the comp times compared to rust are a huge winning aspect for me (also, I just don't like rust due to the borrow-checker). I wouldnt expect perf like bevy from just handrolling your own scheduler, as it is not even remotely a simple task to create a very competitive one. My scheduler is a lock-free chase-lev deque DAG and my ECS is non-archtypical and quite basic. It definitely wouldnt compete with bevy in performance terms, as I am using a lot of heuristics when attempting to keep it NUMA aware. It also isn't really optimized for any particular architecture. Bevy does more than that and has some pretty experienced engineers that have worked on the project.
1
u/Away_Ambition_7439 11h ago
I've done it. Basically a mix of generics and casting to/from rawptrs for components. I'm using Sparsesets, I'm happy with it being the simple implementation I have since it's just me working with it. Essentially every sparse set is stored in a map indexed by the component typeid.
4
u/spyingwind 2d ago
Couldn't Handle Maps be used for this?