Skip to main content
gamedev.net
🔒 Locked

A basic engineish design problem

Started by juuso 3 replies 1.4k views
Original Post
juuso
juuso
My problem is probably best explained with an example. Let's consider a hypothetical simple game with AI-controlled robots battling each other in an arena. There is a basic Game object that includes the arena Map object, and a list of Robot objects. What good options do I have for updating the actions of the Robots? The robots need to know what and where the other robots are doing. They also need to know about their surroundings for pathfinding. A relatively ugly solution that worked well in my latest project was to give each Robot a pointer to the base Game object, so they could access the Map and list of Robots at will. I don't really know why this feels wrong, but it does. The other options that I can come up with are having the Game object do all the AI updates, and not letting the Robots think for themselves. This makes code horrible, but has worked for me in small projects. The other option is to create a thorough messaging system, where the Game checks what each robot can see, and sends them messages. The Robots then know about the world only through second-hand information, and try to work with that. I usually try not to fix what isn't broken, but this time I'm yearning to make an exception. I hate the Game* pointer. Of course the Game/Map/Robot is just an abstraction of the general design principle problem. As sadly, not all my games have fighting Robots.
Illco
Illco
Essentially you are giving each Robot a pointer to the Game in order to obtain the Map. Why not give each Robot a pointer to the Map immediately (omitting the Game level)? This is more natural -- design wise it seems sound that each Robot knows about its environment through Map. You can then simulate more realistic (reactive) behaviour by limiting the extent of information used by each robot (for example a cut-off radius for events/sights/sounds received by the robot.

Furthermore, then the Game or the Map should know about the Robots it contains, in order to perform updating. This is only natural as the Robot is part of the Game or of the Map, depending on your general design.

I wonder what you think of this. Good luck in any case. Greetz,

Illco
Structural
Structural
The way I see it the "game" contains the "scene", which is made up from the map and the bots.

A method I can think of would be to have some sort of "AI manager"-like thingy. For example, if bot A's AI behaviour is calculated, the "AI manager" will hand bot A all "objects" that have an influence on his behaviour.
The idea behind this is that in order to make AI behaviour, the AI needs a "context" to calculate in. In an omniscient AI it will need the entire scene as context. In an AI that only depends on its direct surroundings, you only need a few objects for the AI calculation. You need some object that will provide the AI with the correct context, and I'd use somesort of AI-manager for that.

The manner in which the AI manager provides bot A with its context can be done in several ways. Simplest would be a distance calculation. Every object in a range of x would be included in the AI's behaviour. Other methods could involve the bot's "sensory input" such as what it sees through its eyes, or radar, whatever your plan is.
STOP THE PLANET!! I WANT TO GET OFF!!
juuso
juuso
Thanks for the replies, Illco and Structural!

Illco, the Robots also need to know about other Robots, so that's why I used the Game* pointer. Otherwise, the thing you suggested is basically what I have used so far. I guess it isn't such a bad method after all, if it's not just me who uses it.

Structural, I omitted the "scene" level for simplicity. Does the AI-manager system significantly differ from the message-system I described in the first post? It surely seems like the most hierachially elegant solution, as no child needs to know about their parents, or have any kind of hacky pointers for easy data access. Still, it seems like an awfully lot of unnecessary work. Basically, for the coder, it means replacing the easy pointer with a huge information collection-packaging-redistribution system. In its simplest form, it means replacing the Scene* pointer with a copy of the Scene object. Actually, one could think that the original Scene* pointer is the context message for the Robot. This is probably what you meant with the omniscient AI comment?

I guess I'll stick with the system I've been using so far, with a minor change. I'll keep the Scene more separated form the base Game object, because it feels a lot more tolerable to send information about the Scene to the Robots.

Thanks again for the replies.
marijnh
marijnh
If it looks like the AI code is doing lots of things that it should not be doing (iterating through a set of all game objects for example), it might help to have your Game object provide certain services that will be needed by the AI code - for example getting nearby object, checking whether there is a clear path between two points, etc. It might be a good idea to put this functionality into a different class that contains a pointer to the Game object, to prevent cluttering your Game class with this stuff.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.