0
\$\begingroup\$

For reasons outside the scope of this question, my game has several full copies of the game environment running asynchronously. At any one time, only one of these is rendered.

This is trivial to support in a traditional, object-oriented architecture. Instantiate a few copies of the environment, run each one in its own thread (I actually use a parallel task system for cases where there are more environments than CPU cores), and only call call draw() on the one you want rendered.

The time for large refactorings has come, and I'm considering converting to an entity component system such as Entt. What would be the best way to achieve this same functionality?

The best I've come up with is each environment being a self-contained ECS, managed by an object-oriented system (which would also handle things not replicated, such as UI). The render system would be disabled in all environments except the one being rendered.

I don't like that solution though. I don't want the render system for the game environments to be separate from that of the UI, etc. I also don't like the idea of mixing ECS and object-oriented architectures.

Is there a better solution?

\$\endgroup\$
  • \$\begingroup\$ It sounds like you've discounted it with your last paragraph, but Spaces is a rather clean approach to accomplishing this. Ref. gamedev.stackexchange.com/questions/48704/… \$\endgroup\$ – darkside Nov 13 '19 at 17:45
  • \$\begingroup\$ @darkside If managing multiple entity-component architectures with an object-oriented system is considered standard, I'd definitely reconsider my stance on that. I had assumed that there was a more elegant solution. \$\endgroup\$ – Omegastick Nov 14 '19 at 1:42
1
\$\begingroup\$

I presume since you want a system similar to Entt you're writing in C++.

Environment Rendering

One of the simplest solutions you may find for the rendering system would be a simple boolean property on the environment class something like IsSelected or IsActive to represent which one is selected for render.

The relevant class handling your environments would then simply need an if statement encapsulated in a for each statement to evaluate whether or not to render based on that properties state as well as any other logic you want executed differently based on states of the object such as disabling the render system. You may want to use Events or perhaps even a more simple approach execute this on the set accessor when the relevant properties change values.

ECS

The use of a common abstract base class or interface perhaps named something like IRenderObject would be effective here to have a common type to use for both Game Objects/Entities and the UI alike. I think you may prefer the interface pattern here as from what you said it seems like you want to get around the limitations of class inheritance in an object oriented environment.

public sealed class Entity : IRenderObject 
{
  EntityComponent[] Components { get; } // Could use List<T> here as well or implement IList<T>
}

public abstract class EntityComponent {}

public abstract class UIElement : IRenderObject {}

By looking at your question I can tell you're probably going to have to put a lot of thought into class versus structure. As you can see from my example here it is possible to efficiently write ECS in an object oriented environment.

Based on what you said you may want to use structure which is also why I suggested an interface for IRenderObject as I'm sure you're aware structs don't support inheritance however they can implement interfaces.

So in your environment/environment manager classes you'd want to use IRenderObject as a parameter often to support both UI and GameObject/Entity (whatever you're calling it). As stated on page 22 of C++ Succintly

The difference between a class and a structure in C++ is simply that a structure’s members default to public whereas a class' members default to private. That's it. They are otherwise the same. There is no value-type versus reference-type distinction as there is in C#.

If you are writing this in C# structures would likely save RAM at the cost of excessive CPU time for defining entity. Structures versus Classes is a debate I've seen in various places. That one is of course going to be up to you to decide what's appropriate for how you're doing it. I hope the information I provided above will help you choose what's right for you scenario though.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Yes, I'm writing in C++. The system you're describing (A GameObject class which is inherited to add functionality) is not an entity-component system. IMO the Unity manual gives a pretty good overview of how an entity-component system works. \$\endgroup\$ – Omegastick Nov 14 '19 at 1:51
  • \$\begingroup\$ Yeah there are a lot of good ways to do that there. The Unity Manual does give a fair outline of ECS on the conceptual level too, I agree. I've explored inheriting from a GameObject class as well before and it still seems like a worthwhile approach too. \$\endgroup\$ – Hawkeye4040 Nov 14 '19 at 2:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.