• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Cornstalks

What's your preferred way of letting objects affect the game?

20 posts in this topic

though i basically went for the same system you are using in my own engine, so i cant say for sure that it is better, but in retrospect i wish i had implemented it as a event driven system, where game objects can register callbacks for an event. that way the interface stays 'clean', and you have a clearly defined connection point, namely the event message dispatcher/processing. also, when done properly, you get the 'only update when necessary' for free. needless to say, this variant is usually very performance effective (of course it always depends)

 

however, like i said, i haven't actually done it, so there could be some serious pitfalls i cant think of just now, i'm just learning this stuff myself.

0

Share this post


Link to post
Share on other sites
I've been implementing a Entity Component System and have found it to be very clean and easy to control.

Entity's store data. Controllers are attached to entities and add or alter the entities data(usually after reading it) they also handle events. Observers act on data changes and fire events.

I currently have an explicit controller, that takes the user input and changes the entitys state.
An implicit controller that takes movement states and turns it into actual movement.

An observer that watches entity movement and fires collision events.
and an observer that watches entity positions and animations and sends updated data to the renderer.

Such a system can require some intermediate techniques to set up, but has many advantages. Controllers and observers each only have one task, and so are very simple. Game data is cleanly split from the renderer(and both can be moved to different threads much easier).
0

Share this post


Link to post
Share on other sites
Apoch has covered design nicely, but I think this is still worth calling out.

But games are complicated. Objects interact with each other and the entire game's state regularly throughout the game. Units collide, one unit attacks another, a building makes units, a unit can create projectiles, and those projectiles can affect a large number of other units, etc. In other words, when programming this, you need a way for one object to be able to affect another object (or the game state itself, possibly by creating other units or projectiles). But it's not just a one-time case; many different units have different affects and interactions, which can result in messy code when trying to make all these possible interactions and events possible.

The bold section, in particular the end, is key to this I feel; a single object in the game is not going to touch the whole game state. Not ever and certainly not directly. This is something you go on to basically say yourself with the list of interactions below and this is a key place to start when thinking about it - each object has a pre-defined interaction with the world. If you were going to make an RTS game, for example, your 'tank' super-object (super-object => collection of parts) isn't suddenly going to be marrying The Hulk any time soon ;)

If we take a closer look at one of the examples you gave, "a building makes units", as a typical factory in an RTS game.
While this might look complicated it isn't really, at the highest level the building does one thing 'creates a unit', at which point beyond throwing out a few notifications it is done.

Its output might simply be a message (in the generic sense, not a 'message system' sense) which says "I've made vehicle <type> at location <here> for <player>". Other systems would be listening for that event and respond accordingly; a player's unit collection might update and the unit spawner might create a new object so it can be rendered.

At which point the messages could ripple further afield (unit collection => UI to display message/icon; spawner to any AI and physics systems to insert it into their world view; and so on) but the key interaction is done.

As to how you expose this... well, there is the erstwhile mentioned 'message system' which you could route all the messages to - however this global routing might not be what you want. Your 'factory' super-object might contain a list of delegates/functions to call when certain events happen and systems 'subscribe' to them or you could abstract the whole thing and come up with a processing graph which represents spawning in data; this would require your super-class still outputs events but the hookup of those input and output pins becomes data driven and potentially modified per level.

The key thing, however, is that each unit has a predetermined level of interaction with the world so it can't mutate all the state itself nor does it have to deal with every possible thing that can happen. Even something as simple as 'collision' isn't really the units problem as it is a problem for the physics under the hood.
2

Share this post


Link to post
Share on other sites

i didn't mention this in my first post, but i've actually moved to something in between 'every object can affect everything else (within its class)' and an 'event system', im using a command queue of sorts.

 

all objects interacting with the world issue a command to the queue (most prominently spawning of stuff, but also game logic triggers and such), and the command queue handles dispatching data to other objects that need it. so its basically an event system, but i will not shoehorn my collision into there, that seems performant enough, since i got a broadphase covering all objects anyway.

 

a nice side effect of the queue was that i was easily able to prioritize and limit events per game loop iteration.

even though a lot still gets calculated inside the object class itself, i managed to move most of it to the queue.

 

deriving new objects from my game object class has become so clean and easy now, wish i had done it from day one (well actually i did, but limited to spawning at first)

 

EDIT: seems from the answers sofar that event systems are the way to go....

Edited by Tasche
0

Share this post


Link to post
Share on other sites

I think Apoch and phantom cover the bases well but phantom brings up the real problem: how to trigger event and apply effect.  No offense meant but phantoms "clarification" was unfortunately lacking in "how" it works.

 

It's all in the lists...

 

Games are "turn based", just really damned fast turns.  So, your object wants to create a projectile, you create the new projectile and send a message to the games main loop saying "add this to the world".  You send a message because you want the creation of a new projectile "NOT" to effect current turn processing, the creation is the result of this turn and will affect the world next turn, "not" this turn.  (This delayed reaction solves ungodly numbers of bugs, just do it, really.)

 

Given we solved how to produce a projectile, how do you apply damage?  Same basic deal, the projectile says "I hit" and posts a message for "do damage to xxx" because I hit it.  Next frame xxx figures out if it is still alive after getting hit.

 

Or, xxx could post a "I did x damage to area" to the world object and the message can be applied to all objects in the area.  Those objects can be told to die or removed, depends how you want to deal with the details here.

 

The key thing to remember is that even though the game is realtime the rules are basically turn based.  If you try to apply rules interactively in a single frame, you are asking for all sorts of problems.  OMG, he didn't die 1/60th of a second faster really isn't something a player will notice and not integrating everything every loop makes for a much more simplified coding problem.  Network and all that, gets more complicated but still basically the same other than when to apply messages.

0

Share this post


Link to post
Share on other sites
typedef unsigned long coord_t;
typedef unsigned char byte_t;
typedef signed short mobjtype_t;
 
typedef enum {
MOBJ_CREATE=0,
MOBJ_ACTIVE,
MOBJ_ATTACK,
MOBJ_PAIN,
MOBJ_DEATH,
maxmobjframes;
} mobjstates_e;
 
typedef struct {
mobjtype_t type;
frame_t* mobjframes[maxmobjframes];
coord_t mapx,mapy;
mobj_t* target;
} mobj_t;

?

mobj_t represents every possible object in the game world, including the player. mobj_t contains a list of pointers to a master "frame list" that defines things like what graphic should be displayed for this object at this frame, what the next and/or previous frames for the current one are, and a function pointer to describe what needs to be done by this object this frame. mobj_t frames only have access to certain functions in a master list which should, by convention, only interact with other mobj_t types, and what object that ends up being is dependent on mobj_t.target. Objects can do whatever the hell they want to each other after this point.

Edited by darkhaven3
0

Share this post


Link to post
Share on other sites

?
mobj_t represents every possible object in the game world, including the player. mobj_t contains a list of pointers to a master "frame list" that defines things like what graphic should be displayed for this object at this frame, what the next and/or previous frames for the current one are, and a function pointer to describe what needs to be done by this object this frame. mobj_t frames only have access to certain functions in a master list which should, by convention, only interact with other mobj_t types, and what object that ends up being is dependent on mobj_t.target. Objects can do whatever the hell they want to each other after this point.

I can see this being a legitimate approach if and only if your game logic is heavily data-driven and validated by external tools prior to loading into the engine.

If you're hard-coding a non-trivial game in this style, it's going to turn into a Big Ball of Mud sooner rather than later.

Of course, as I said before, for a certain class of games (and more accurately, for a certain degree of simulation simplicity) that's totally fine.

I'd hate to see an RTS built that way, though ;-)
1

Share this post


Link to post
Share on other sites

It's heavily implied by the design approach that I'm not going to just allow any frame to start calling functions designed to load a map or initialize SDL or anything, just by convention of how the function-pointer list that the frames reference works. I imagine it will work well enough for the sidescroller I intend to use it with where there's not a whole lot of elegance in object management required.

Example being: "Object A tries to move in the direction of object B. Do whatever the function to move this object says to do. I don't care to sanity-check the results; the function will resolve that on its own. The end."

Edited by darkhaven3
0

Share this post


Link to post
Share on other sites

?
I can see this being a legitimate approach if and only if your game logic is heavily data-driven and validated by external tools prior to loading into the engine.

Really? All I can see is the many hundreds of ways this can crash and burn in a series of amusing ways... more so when you consider the follow up reply about not sanity checking the results... dry.png
0

Share this post


Link to post
Share on other sites

No offense meant but phantoms "clarification" was unfortunately lacking in "how" it works.

heh, I was vague on purpose as I felt the general idea was more important than the precise details ;)

For the record I'd favour a hybrid of using scripts/graphs designed by a designer to drive things but allow that to push messages into the message system if needs be. (Such as wanting to kick a sound off and not want to directly tie the sound system into the scripting/graph system.)
0

Share this post


Link to post
Share on other sites

What's your preferred way of letting various objects (units)
affect the game (by creating other units, buildings, projectiles,
hurting/healing other units, etc.)?

 

Directly. I've started in with component based entities, and letting isolated single responsibility components work directly against references (while ignoring what those references are, or how they are provided) is totally awesome. No event storms to hunt through, no message queues to interpret or parse, no bundles of void* or object to cast about.

 

Dependency resolution is done in one isolated place, and otherwise components go about their business: exposing functionality for other things to use/consume.

0

Share this post


Link to post
Share on other sites

ApochPiQ, on 16 Feb 2013 - 19:25, said:
The key realization is that representing a "game" or "unit" or "building" might still be violating SRP.

Yes, on some level, those are "single" groups of responsibility. But they're really just God Classes of slightly more tame dimensions.

I'm curious about this. I understand what you're saying in terms of risk to SRP, but is a 'Game' class really necessarily a god class? If all of the components of 'Game' are properly abstracted it could be pretty simplistic, couldn't it?

You made the point that representing an RPG character with a single class is inappropriate. Are you saying that a character instance should be represented by more than one object, such as dividing character state between components that deal with the character or do you just mean that the attributes of the character should be further abstracted?
0

Share this post


Link to post
Share on other sites
I'm not sure I follow the question, honestly.

I think you should organize your code so that individual units of organization have a single, clearly defined area of responsibility. I also think that's extremely context-sensitive, as I said before, and what makes sense for a small design may utterly backfire in a larger one - and vice versa.

There are no 100% applicable rules that govern every single design situation. You have to learn how to solve the problem at hand.
0

Share this post


Link to post
Share on other sites
I'm just asking what you mean when you say classes like "game" or "unit" or "building" are mini-god classes.

My understanding of SRP is that a unit should do one thing and do it well. When I think of a 'Game' class I want to limit it to essentially being a container for the game's components that works like a composite for updating them. The Game class itself only holds the component system objects, of which there are few, and runs the main control loop, which simply updates the member objects in order. I consider this to be adhering to SRP. While it's true that nearly the entire program runs within the context of the Game class instance, the Game class itself is only performing one duty - playing host to the parts. What the parts themselves do I consider to be their own areas of responsibility, not that of 'Game'. Is this sensible?

Just interested in your point of view. Edited by Khatharr
0

Share this post


Link to post
Share on other sites

I was referring to the OP. Nothing grand or sweeping. I don't mean to imply that any class called "Game" or "Unit" or "Building" is inherently bad, although it seems that's what you inferred, for which I apologize for my lack of clarity.

 

If you read through the rest of my posts in this thread, it should (I hope!) be abundantly clear that composing such a class from SRP-adherent constituents is perfectly fine with me.

0

Share this post


Link to post
Share on other sites

In my recent game projects, I can relate my design to a company : game entitys (player, asteroids, aliens, laser beams,...) are under the care of a manager (PlayerManager, FlyingObjectsManager, BulletManager,etc...), that are under the care of the Main manager (Game)

 

Basically, the main manager tells the other managers to do their stuff or redraw their stuff when it's time, and the others manager tell their entity to update or redraw, and manages their group of entities (e.g. the flyingObjectManager spawns asteroids and bonus and recycle them when they go out of the screen).

 

When their should be an interaction between entities from different manager, it is carried by the main manager either procedurally (e.g. in my game loop retrieve a collection of flying objects/bullets from the corresponding manager, and ask the player manager if anything collides with a player), either event-driven (e.g., a player entity has collided with a bonus, the score must be updated and the bonus entity must be hidden).

 

Of course, my games are simple, so this level of details is adequate. For bigger projects, (e.g. an ARPG in an open world), their would be more levels of management, like in a big company.

Edited by Sporniket
0

Share this post


Link to post
Share on other sites


I can see this being a legitimate approach if and only if your game logic is heavily data-driven and validated by external tools prior to loading into the engine.

Really? All I can see is the many hundreds of ways this can crash and burn in a series of amusing ways... more so when you consider the follow up reply about not sanity checking the results... dry.png

 

Sure it can crash and burn if I care to introduce bad definitions in the frametable. Who cares? If the function called by a frame for a particular mobj_t says "You can't move here because I said so", then the mobj_t shouldn't give a damn. All that would happen is the mobj_t would stop moving in that direction, and possibly attempt to move in a different direction arbitrarily. It's not an mobj_t's responsibility to determine where it can move in this specific context; it's handled at a higher level. All an mobj_t is responsible for is itself, or being the target of another mobj_t in special cases (monster infighting, or the player being the target of a monster, mainly). And even in that case, mobj_t's typically don't care if they are targets of one another, and can't directly modify one another's target reference; they will attack one another until it is somehow resolved by other mechanics, typically by means of one mobj_t changing targets to the player or another monster, or entering its death state.

 

It seems simple and concise enough to be easy to debug and easy to implement, and it seems like it would be quite fast, especially in the context of a 2D sidescroller.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0