I am currently rewriting a project I have been working on last year and I’m utterly stuck trying to "correctly" separate the game-logic from its representation. I know why this is beneficial and I sort of get how to build the representation into its own subsystem but if you actually encapsulate all the game-states into a different object or even library, how can you draw the scene?
Say we are working on the Super Mario game. There would perhaps be some Mario-object that encapsulates the different states Mario can enter (e.g. Small, Big, Fire-shooting, Mounted, …). These states are not purely visual since Mario’s movement-speed or damage-handling depends on this.
However, the way Mario is drawn also depends on this very state. So how would the rendering-layer know which sprite to bring onto the screen?
Pretty much everything the game-logic does causes some sort of animation, sound, or other output. In a way, having the drawing-logic mixed with the internals seems to be the cleanest since they really do belong together.
If you do separate the game-logic from its representation, there needs to be a way to access the data. What’s the best way to do that? I could think of these:
Data-binding by using some Event-system
Every time some state in the logic-layer changes, it could publish some event to which all other parts of the game can subscribe to. Upon receiving an Event, they can update themselves and load the appropriate animations.
However, this feels like we’re removing the responsibility of drawing the state onto the screen just to add the responsibility of firing an Event, which might actually be messier: There would be Events for each entity and each state, every spell that can be cast, every changed movement-parameter, plus every started, finished and interrupted attack – the list is huge compared to a function that “just renders the internal state”.
Also, there is a lot of bookkeeping to be done since each Event needs to manage a list of subscribers, which would probably be an Interface resulting in many indirect calls, which might cause a performance-hit as well.
Access the data from the rendering-layer
The representation-layer could just query the state, either by simple Getters or a complex Entity-Component-System where the data would be accessed plainly, anyway.
It still feels wrong to open up the (encapsulated) state like this, but it seems to be cleaner approach. In another post, I saw the use of the visitor-pattern, which sort of does this as well, but then there would be a Draw()-method on the game-object again, which sort of defeats the purpose, doesn't it?
Any input is highly appreciated cause I really want to stop thinking about it and just get into coding again. :D
Thank you so much!