Wie entwerfe ich eine Game Engine in einer objektorientierten Sprache? [geschlossen]


26

Wann immer ich versuche, ein Spiel in einer objektorientierten Sprache zu schreiben, stelle ich immer als erstes Problem (nachdem ich darüber nachgedacht habe, welche Art von Spiel ich schreiben soll) das Design der Engine. Selbst wenn ich vorhandene Bibliotheken oder Frameworks wie SDL verwende, muss ich für jedes Spiel bestimmte Entscheidungen treffen, z.

Was ist ein gutes Design und wie würde es umgesetzt? Was sind einige Kompromisse, die gemacht werden müssen, und ihre Vor- / Nachteile?


12
Was ist falsch daran, spontan zu arbeiten und von dort aus zu refactoring, anstatt eine Analyse-Lähmung zu erleiden?
Die kommunistische Ente

7
@TheCommunistDuck Weil es der Ansatz ist, der in all meinen vorherigen Projekten verfolgt wurde, Impulse zu setzen - und jeder einzelne stößt nach ein paar Monaten an eine Wand, wenn ich feststelle, dass jedes neue Feature monumentalen Aufwand und Komplexität erfordert. Momentan verbringe ich mehr Zeit damit, meine Engines neu zu schreiben, als das Spiel selbst zu schreiben. Ich hoffe, dass ich mir mit ein wenig Voraussicht und Planung auf lange Sicht Zeit sparen kann.
Extropic-Engine

3
@chuzzum, guter Punkt. Eine Sache, die ich dann empfehlen würde, ist, die Architektur der C4-Engine zu überprüfen, das heißt; terathon.com/c4engine/images/architecture.png Es ist vielleicht ein viel höheres Level als Sie brauchen, aber es könnte Ihnen einige Ideen geben ;-)
Die kommunistische Ente


3
Auch diese Frage ist etwas vage. Nehmen Sie vielleicht eines Ihrer Beispiele und stellen Sie die eine oder andere Frage.
Tetrad

Antworten:


24

Ich bezweifle, dass jemand in der Lage sein wird zu sagen: "Du musst dies und das und das und diese Slots mit dem Muster X machen."

Einige nützliche Ressourcen:
Enginuity - eine Reihe von Artikeln zum Motorenbau auf Gamedev.net.
Game Coding Complete - Ich besitze dieses Buch und es geht auf jeden (fast) Aspekt der Spieleprogrammierung gut ein. Es hat auch einen Motor im ganzen Buch gebaut.
Game Engine Architecture - Dies ist ein weiteres großartiges Buch für das Engine-Design.
C4-Motorlayout - Aus meinem Kommentar entnommen, zeigt dies jedoch, wie jeder Teil des Motors auf höchstem Niveau zusammengefügt werden kann.

Das ist vielleicht etwas zu viel für das, was Sie brauchen, aber Sie können nicht zu viel über etwas wissen, und ich bin sicher, Sie werden von ihnen einen guten Plan erhalten.

EDIT: Ich habe vergessen, dass die Gamedev-Artikel seit der neuen Site archiviert wurden, behoben :)


The Enginuity link was broken, and googling the articles seemed to show that they are no longer on the web. (?) The books look like good resources though, and I'm always keeping an eye out for more programming books ;)
extropic-engine

Also, in regards to your first comment, I'm not expecting anyone to come up with a master plan that fits every game. I just noticed, over the course of developing a few games, that common patterns do tend to come up a lot, so I wondered what other people used in their games.
extropic-engine

1
Fixed the link.
The Communist Duck

+1 for enginuity. @chuzzum Just examine a couple of game engines, let them inspire you and derive the optimal architecture for yourself. Plus: It is often better to make your game engine component based than hierarchical, see cowboyprogramming.com/2007/01/05/evolve-your-heirachy
Dave O.

1
I wouldn't say that it's the engine that needs to be aggregated, more the entity framework part.
The Communist Duck

7

As an example, here's how my current roguelike project is structured (in Java). It is using a 2D graphics engine so a lot of the rendering code was already taken care of for me. Criticism is welcomed.

class Game
This class sets up the state machine that manages the current state of the game. (in a menu vs. starting a new game vs. playing a saved game)

interface State
Each State class contains two loops: a loop for updating the logic and a loop for rendering. They also contain code for calling the Game class and requesting a change to a different state.

class ResourceManager
Ein Singleton, der von der GameKlasse initialisiert wird, die alle benötigten Ressourcen lädt und den Zugriff darauf ermöglicht. Ich mag dieses Design nicht, weil es zum Beispiel schwierig ist, Ressourcen auf verschiedenen Ebenen zu laden / entladen. Ich würde das wahrscheinlich anders gestalten, wenn ich von vorne anfangen würde.

class Map
Eine Karte enthält eine Reihe von Kacheln und eine Liste aller Kreaturen und Gegenstände auf der Karte. Es ist eine ziemlich einfache Klasse.

class Creature
Kreaturen enthalten Informationen über sich selbst, einschließlich Bewegungsberechnungen (sie müssen wissen, auf welcher Karte sie sich befinden, und sie müssen diese abfragen können, um Hindernisse zu erkennen). Es ist etwas, mit dem ich zu kämpfen habe, um zu entscheiden, ob ich das mache oder ob ich mich um eine Art Manager-Klasse für alle Kreaturen kümmern soll.

interface AITask
Creatures can have a list of AITasks, which are executed every time the creature's logic loop is run. The AITask has its own logic loop that issues commands to the creature, and a termination condition that determines if the task was completed successfully or not.

interface UIElement
I implemented my own UI for this engine. Each UIElement has a rendering loop and a logic loop. They also have a loop for processing keyboard/mouse input. All elements can have a number of child elements, which are rendered after their parents, and take over the keyboard/mouse input. This lets you have menus with submenus, for example.


What exactly is going wrong with this? It seems perfectly fine to me.
The Communist Duck

@TheCommunistDuck It doesn't really come through in the examples I picked, but I do have a lot of problems with this code. The ResourceManager class is one of them, but I have with trouble with states too-- I end up with a huge proliferation of them, and copy a lot of code. Especially in an RPG, where the player has lots of choices at any one time, you can end up with really complex state graphs. Example: casting a spell. Goes from NormalState -> SelectSpellState -> SelectTargetState -> InvalidTargetState (if it failed) -> DoSpellAnimationState -> NormalState. And that's just one action.
extropic-engine

1
No. NO. NO. NOPE. Please no. Oh wait you said you don't like it.
Bartek Banachewicz

6

The first important point to make is that there is no one 'good' answer to this question.

The closest thing to a right answer would be something like: It very much depends on the type of game, target platform, constraints (time) etc.

That said there are some really good articles out there that will show you how other people have tried to answer this problem (as i have tried to find info on this in the past).
As The communist duck mentioned the enginuity article on game dev helped me understand some parts of game architecture.

My current design is a hybrid of Quake3/Doom3 and a little bit of the .NET class library :)

I have two libraries (static or dynamic depends on how you want to build/deliver) the Framework and the Library.

The Library contains all helper classes which are there to help with the production of game software but aren't limited to this kind of product. ie it has an implementation of a linked list which is optimized for game code but could be used by anything which needs the service of a linked list.

The Framework is the guts of the 'engine' if you want to call it that. A lot of this follows Quake3's design philosophies (just in a more object orientated way). It contains the CLI, timing management, OS specific code, and eventually networking layers etc.

These two are then linked against the actual app that is being produced. The Game if you like, which contains the game specific code. In much the same way Quake3 loads DLL's depending on which 'mod' is being played.

To give you an idea of structure here is a quick breakdown of folders and contents for each lib:


  • Framework
    • IO (Specialist file management classes, Text Printing classes (eg to the CLI), and logging etc.)
    • Network
      • Client (classes which represent what the Framework considers to be a 'person playing/connected to the game')
      • Server (classes to manage connection into the framework and manage the player(s))
    • Platform (Keyboard/mouse/controllers handling classes, OS specific routines like getTime())
    • System (very low level classes like an error class to aid printing of error messages, Timing classes, and the CLI itself.)
    • Renderer (self explanatory)
    • etc.

  • Library
    • Collections (classes which represent collections of data, linked lists/hashtables etc.)
    • Math (basic math helper classes like Vectors and matrices)
    • etc.

HTH! Should give you some pointers...


Alternate link to the Enginuity Series
Musaffa

-3

Things to consider

  • Object oriented languages have problems because they usually don't have first class functions or not all data is object (like integer or float in Java). Design patterns adress these problems with several patterns. It is generally faster to code and easier to mantain to use language which can do them (first class objects); for example Python (which also allows object oriented design), You will have slower speed thuough.
  • Event Calculus, to AI at least
  • Hoare logic, use preconditions and postconditions to at least test Your code
  • Agents, look at Quake entities
  • Relational Databases, powerful way to store data

Good design

  • make ER diagram
  • make it correct
  • create your database, objects or data strutures from it

Data is key to programming. If You desing Your data good, algorithm usually emerge from them (if You don't count some numerical algorithms, like computing determinant).


-1 since this answer is very vague and confusing. Relational databases have absolutely nothing to do with an OO-engine. I can understand that English is not your first language, but could you possibly explain what you mean in your first paragraph? It seems contradictory (OO languages have problems but it's easier to program in languages with design patterns..even though design patterns are nearly always OO structures).
The Communist Duck

@duck Contradictory? OO have problems which does not exist in other languages, DP solve them see c2.com/cgi/wiki?DesignPatternsInDynamicProgramming .
user712092

@Duck 1) You can use SQL in C++ 2) You can infer attributes of objects from ER (althought it is not recommended practice) 3) You can data structeres from relations (this is a list because I need to reorder the elemenents at willm this is a hash because I need fast lookup)
user712092

@Duck I apologize, I made mistake by reordering. I did not wanted to claim "DP are easier to XY" but "languages who can do first class are...". :)
user712092

Yes, there may be advantages to functional languages. However, even impartially, I feel an OO approach makes logical sense from a gamedev perspective. Also, there is no reason you need a relational database anywhere. Sure, they can be useful. It does not, however, become a needed component anywhere.
The Communist Duck
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.