Re: Is something like EnTT possible with Nim?
@yglukhov You're comment encouraged me to seek out a better ECS tutorial than the one I read prior to my first ECS(-ish). Thank you for that. The tutorial, for anyone interested, is at: [http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1](http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1)/
Re: Is something like EnTT possible with Nim?
Thank you for the suggestion, @yglukhov. I'm familiar with ECS and have implemented one before in Go. I wanted to try the same in Nim to help me gain familiarity with the language.
Re: Is something like EnTT possible with Nim?
@stephenwithav it's important to understand the problem ECS solves. ECS is notable for its memory utilization efficiency, gained from cpu-cache-friendly data layout. I'd suggest you read about that before implementing your ECS. But, small spoiler, neither polymorphic objects (interfaces), nor references are the options. At this point, i'd suggest not to consider variant objects either. :)
Re: Is something like EnTT possible with Nim?
Ideally, I'm hoping for something comparable to Golang interfaces. I avoided C since the early '90s due to early compiler incompatibilities. Only recently, in the past few months, have I looked at C/C++ seriously. Thank you for pointing to `variant`. I'm going to look at entt's source more closely and try to find a good equivalent in Nim. (I couldn't seem to make anything useful out of sequtils; Araq, I'm curious as to what you had in mind.)
Re: Is something like EnTT possible with Nim?
> Then I learned this morning that seq[Component] fails. That really should be obvious. A seq in Nim is similar to vectors in C++, that is basically a plain C array that automatically resizes when necessary, where resize is new allocation and copying elements. So all elements must have same type and same size as in C arrays -- as all refs and pointers have the same size, we can have different ref types in a seq and can test for exact type with "of" operator at runtime. Note that we have sum types (objects variants) in Nim.
Re: Is something like EnTT possible with Nim?
I thought I had something good last night: type Position = object x: int y: int type Velocity = object dx: int dy: int dz: int type Component = Position | Velocity proc showProps(p: Position) = echo p.x, ", ", p.y proc showProps(v: Velocity) = echo v.dx, ", ", v.dy, ", ", v.dz let p = Position(x: 9, y: 9) let v = Velocity(dx: 1, dy: 1, dz: 3) showProps(p) showProps(v) Run While tedious, it was good. Then I learned this morning that seq[Component] fails. _sigh_ type Position = object x: int y: int type Velocity = object dx: int dy: int dz: int type Component = Position | Velocity proc showProps(p: Position) = echo p.x, ", ", p.y proc showProps(v: Velocity) = echo v.dx, ", ", v.dy, ", ", v.dz let p = Position(x: 9, y: 9) let v = Velocity(dx: 1, dy: 1, dz: 3) var s: seq[Component] s.add(p) s.add(v) echo s Run
Re: Is something like EnTT possible with Nim?
Thank you, Araq and doofenstein. I'm going to try to develop a VERY simple ECS today in Nim. Somehow, I had totally missed (or forgotten) varargs and set. Those two should help make this first attempt successful.
Re: Is something like EnTT possible with Nim?
Another ECS attempt: [https://github.com/yglukhov/ecs](https://github.com/yglukhov/ecs)
Re: Is something like EnTT possible with Nim?
ha, you might be interested in this ECS implementation, from one of my failed Nim game engine attempts: [https://gist.github.com/RSDuck/6c8caf82aeb88991d440b228b3f32f06](https://gist.github.com/RSDuck/6c8caf82aeb88991d440b228b3f32f06) Note that this is mostly untested. For examples look at the bottom of the file.
Re: Is something like EnTT possible with Nim?
What's hard about `registry.view`? Please look at `sequtils.nim`.
Re: Is something like EnTT possible with Nim?
assign shouldn't be too difficult... just add a subclass of Component to the seq. But filtering for registry.view? I can't figure that one out yet. Templates, maybe?
Re: Is something like this possible?
Thx for the help. One more question : is there any way to forward declare a variable without knowing the exact type? if flag == true: var c = 5 else: var c = 10.0 The if statements here open a new scope so I no longer have access to the c variable. I was thinking I could work around this with some kind of template maybe.
Re: Is something like this possible?
use `when` , as long the variable can be know at compile time import typetraits const flag = true when flag == true: var c = 5 else: var c = 10.0 echo name(type(c)) take a note that's only for compile time, you cannot switch during runtime
Re: Is something like this possible?
While `StoreKind` can be any of `StoreInt|StoreFloat|StoreString`, once it is instantiated, it will stay that one. Instead you have two choices: 1\. derive from a common `Store` object: type Store = ref object of RootObj dep: seq[Store] req: seq[Store] StoreInt = ref object of Store val: int StoreFloat = ref object of Store val: float StoreString = ref object of Store val: string 2\. use object variants: type StoreKind = enum StoreInt, StoreFloat, StoreString Store = ref object of RootObj case kind: StoreKind of StoreInt: intVal: int of StoreFloat: floatVal: float of StoreString: strVal: string dep: seq[Store] req: seq[Store] var a = Store(kind: StoreInt, intVal : 5, dep: @[], req: @[])
Re: Is something like this possible?
Well, you could do this: type StoreInt = ref object of RootObj val: int dep : seq[StoreVariable] req : seq[StoreVariable] StoreFloat = ref object of RootObj val : float dep : seq[StoreVariable] req : seq[StoreVariable] StoreString = ref object of RootObj val : string dep : seq[StoreVariable] req : seq[StoreVariable] StoreKind = enum skFloat skInt skString StoreVariable = ref object of RootObj case kind : StoreKind of skInt: intVal: StoreInt of skFloat: floatVal: StoreFloat of skString: strVal: StoreString converter toInt(x: StoreInt): int = x.val And I do realize it's probably not what you want, because it doesn't give you the delicious automatic conversion magic when you pull values out of the dep/req seqs, but the thing is, that wouldn't work no matter what, because putting different things into the same container inherently involves loss of static type information.
Re: Is something like this possible?
Do you perhaps want it like this? type Store[T] = ref object of RootObj val: T dep: seq[Store[T]] StoreInt = Store[int] converter toInt[T: int](x: Store[T]): T = x.val var a = StoreInt(val: 5, dep: @[]) echo a.toInt