Advertisement

How to design world, player, obstacles etc classes so they can communicate, which class does what?

Started by September 18, 2017 03:17 PM
40 comments, last by bovine.genius 7 years, 5 months ago

2 few years have passed since I last tried to make my own game and like always I had to give up because I encountered an unsolvable problem.

And here I go again, hitting the same brickwall with no solution in sight.

My question is: How exactly do I design all my classes so that coupling is minimal when they need to talk to one another somehow.

Let's look at one prime example:

The player exists inside a "world", an environment, where other entities also reside, enemies, obstacles, chests, whatever.

Now the question is, who is responsible for moving the player? The player class itself in something like Player::Update()?

But then how does it know if it hit an obstacle or walks on an ice-tile or got pushed back by a boulder that hit him? For that it would somehow need to talk to the world class, or the boulder class would need to talk to the player and tell it "hey I hit you please move back 3 tiles"? Last time I tried to create a game I had huuuuuge "pass down" chains where class D was instantiated inside C but class D needed class F so I also needed to pass an instance of that into C, which didn't need it itself and since it was created inside class B, class B also needed that instance of class F. So I passed that instance along like 10 levels deep in each constructor... Not confusing at all, right? ;)

Or maybe should the "world"/level class somehow coordinate everything, move everything, since it knows where everything is, but then how does it know the objects movement logic?

How does separation of concerns fall into this, since optimally, every class should only have 1 responsibility. So what should each one do?

I don't even know how to describe it properly, hopefully you can understand what I mean.

Can someone give me a graph of how everything should be "connected"? Which class should "own"/instantiate what, should the player be instantiated by/inside the world class, or from outside and then passed in? But then in what part of the code should he get instantiated, the main loop?

I tried looking for open source projects so I can see how they did it but all of them are wayyyyy too big and I don't even know in which of the 50000 files I need to start looking.

Does anyone maybe know a very simple open source game with a similar structure that I can study? (Platformer, or something like zelda, something with a world/obstalces/player etc).

I read only the first 5 line, but I think to have a possible solution, I'll post before finish reading the rest xD

So I am a begginner and never done this, but from what I think to have understood, to do what you want to do it is needed Composition so you are not constrained by problem that can arise with inheritance.

This video below shows how, I yet have to finish watching it and probably will need to go through it multiple times before I can do that, but I think it has the answers we need. 

Another interesting video could be this, from one of the developers of Caves of Cud, he explains how the inheritance system didn't worked at all for a roguelike and how he solved with components. 

 

Advertisement

First: don't "design all [your] classes" at once. Pick individual problems, fix them, repeat until you're done. It's less overwhelming that way.

"But then how does it know if it hit an obstacle or walks on an ice-tile or got pushed back by a boulder that hit him?" - Depends on your game. There's no "one-size-fits-all" for character movement. You could have the player set a velocity value, and the world could handle all the movement. You could have the player ask the world, "can I move like this?" and get back a yes/no answer. You could have the player ask the world, "what happens if I try moving in this direction" and get back vector answering where the player actually ended up. Either way, let the world track where everything is, and adjudicate how the movement works.

"How does separation of concerns fall into this, since optimally, every class should only have 1 responsibility" - Don't get obsessed with 'optimal'. Make the object do whatever you need it to. You can clean it up later. And don't try and pre-plan this all in advance in the abstract sense. When you have 2 explicit responsibilities to talk about, then you can consider how to separate them.

"Can someone give me a graph of how everything should be "connected"?" - No, because there's no One True Way to structure a game. You just have to keep at it. You might get further by showing us a graph of what you have already, but unless there is a concrete problem with it, you need to not get 'analysis paralysis' over it. Just keep working.

Without getting into too much detail, your game should have a game loop that handles input, logic, and drawing. When you have a class for player, in your input function you would update the player's position based on key strokes. (if keyboard.up()) { player.setPositionY(-5); }

When dealing with collision, every object should have some way of checking. When you create your player class or any object you can set up bounding box collision as an example, so you would run this check when moving the player. (if player.checkCollision(object1) == true) { player.setPosition(player.prevPosition); } Now, how you go about checking collision depends on you. I personally only check objects that are within the view of the player. When dealing with tile collision, you can simply pass the player y, x divided by tile size to check index values for possible collisions, as you never want to cycle through arrays to do this.

You need to think of classes in the real sense, don't over engineer anything. If you have a human class, and a car class, the car knows if it's moving, but the human knows what car he or she is driving. I would strongly suggest you learn more about OOP before moving forward, this question really isn't a game programming related problem, but more of a general programming question in terms of how class objects interact with one another. Then you should study Game Loops, once you understand how the game loop works, you'll know how these objects interact to input and logic checks.

Programmer and 3D Artist

21 minutes ago, Horscht said:

My question is: How exactly do I design all my classes so that coupling is minimal

also read this:

http://gameprogrammingpatterns.com/component.html

Quoting that link about component design pattern:

"Intent: Allow a single entity to span multiple domains without coupling the domains to each other. "

I tried making something with Unity to get an understanding of how an entity component system works, but to me it looks a lot like spaghetti-wiring everything together ;) "Oh how will this object talk to the environment? Whatever just put a reference to it in there, done!" It's so much easier when you can just drag + drop one object from the editor onto a script to give it a reference to it.

What would be the equivalent of this in code? Instantiating everything in the "main scope" and then passing it along like "objA->child->child->childThatNeedsObjB->referenceToObjB = &objB"?

Well thanks for the videos I'm going to watch them now :) Somehow I always have a feeling I'm missing something completely obvious/fundamental.

Advertisement
3 minutes ago, Horscht said:

Well thanks for the videos I'm going to watch them now  Somehow I always have a feeling I'm missing something completely obvious/fundamental.

Watch the second video I linked first. It's important xD I gave it to you in the wrong order ;)

Personally I'd recommend steering well clear of component-based systems until you are more confident with traditional systems.

1 minute ago, Kylotan said:

Personally I'd recommend steering well clear of component-based systems until you are more confident with traditional systems.

I would like to know the reasons for this :)

 

The Caves of Qud video was informative but the other one waaaaay too complicated, especially since it involves template metaprogramming which is super hardcore hard and I have no experience at all with that.

This topic is closed to new replies.

Advertisement