Advertisement

How to structure things in an RTS for AIs

Started by August 02, 2011 09:27 PM
11 comments, last by ApochPiQ 13 years, 3 months ago
So I'm making a "game" where there is a ssuuppeerr simple RTS game, and you write an AI to play it for you. And challenge other people's AIs and such.

Now I have a super simple little RTS game up and running. And I'm taking a crack at how to write an AI against it. And one area I'm seeing a lot of question marks in, is how to structure the units (game objects) them selves in order to provide lots of useful information to AIs.

My current idea is to have two "event" queues:
1) Current
2) Previous

Each tick of the simulation, each unit will clear it's "Previous" queue, and then move it's "Current" queue into the previous queue. Then it will go on processing like normal, and what ever it is doing that tick (moving, attacking, harvesting resources, ect) will be added to the "Current" queue.

Then when the AIs get a chance to process for that tick, they can examine the queues of each Unit and see what they are doing, and what they were doing.

Is this a sane way of doing things? How do other games handle this?


Lastly, I have another issue to think about. I'm doing this in Javascript, so there really is no public/private in the traditional sense. So I don't want to give the AIs direct access to the Units, because they would have access to things like setPosition() which would allow for teleporting (aka cheating :P). So how do other games get around this? Do they usually just not care b/c AIs are generally trusted pieces of code?

The only thought I've had so far about this is to provide a Proxy object that the AI gets access to and only has "safe" methods which it proxies on through to the actual game object. But this is kinda clunky... requires an extra class for every Game Object.

Thanks in advance for the help :)
==============================
A Developers Blog | Dark Rock Studios - My Site
Why not let the AI implementations store their own history and states? If I were to write an AI in your game, I would want full control over my KR so I could build various strategies and heuristics into the decision making process. Being limited to current/previous tick would be painful to say the least.

As for preventing cheats such as teleporting: just don't give the AI any API for moving units on-demand. Give them an API for "I want to move to here" but that's it. Problem solved.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Advertisement
hhmmm ok point taken.

How about this then. Each Unit has a simple State Machine:
  • Idle
  • Moving
  • Stopped
  • Attacking
  • HarvestingAnd the AI can register listeners for each state transition. So you can registers a listener for the (Moving -> Stopped) transition, and then tell it to do something else. And based on these callbacks you can maintain state histories or what ever you want on your end.


    Second, the API idea, I guess you could just have a uniform API, say:
    Game::issueCommant( unitId, order )
    Game::getUnits() // Returns a list of IDs
    ...ect...

    This way the AI never has access to units, only their IDs which it can use to send and receive information? Something about that doesn't sit right with me...
==============================
A Developers Blog | Dark Rock Studios - My Site
Why can't the AI access units directly? Let it look at their HP, their current position in the world, etc. etc. and use that information in any way it sees fit. Just don't provide it any API for doing things you don't want it to do, like teleportation.

The state machine concept is an improvement, but I'd still find it painfully limiting. If I want to write an AI that isn't easily modeled as a finite state machine, then I have to go through ugly contortions to fit my model of AI with your model of AI, and that just strikes me as needlessly ugly.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

So you'd just want direct access to all the info about each Unit, and you'd sample it each tick and do what you want I guess huh?
==============================
A Developers Blog | Dark Rock Studios - My Site
That's how I'd do it, yeah.

Of course, that's because I know what kinds of AI I would try to write in such an environment. If you're not targeting AI programmers as your audience, it may make more design sense to limit them somewhat, just as a means of offering some guidance.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Advertisement
Right well I would certainly want to provide some guidance and libraries to get you up to speed fast, but provide the raw access for the more advanced people.

Thanks for your time :)
==============================
A Developers Blog | Dark Rock Studios - My Site

So I'm making a "game" where there is a ssuuppeerr simple RTS game, and you write an AI to play it for you. And challenge other people's AIs and such.

Now I have a super simple little RTS game up and running. And I'm taking a crack at how to write an AI against it. And one area I'm seeing a lot of question marks in, is how to structure the units (game objects) them selves in order to provide lots of useful information to AIs.

My current idea is to have two "event" queues:
1) Current
2) Previous

Each tick of the simulation, each unit will clear it's "Previous" queue, and then move it's "Current" queue into the previous queue. Then it will go on processing like normal, and what ever it is doing that tick (moving, attacking, harvesting resources, ect) will be added to the "Current" queue.

Then when the AIs get a chance to process for that tick, they can examine the queues of each Unit and see what they are doing, and what they were doing.

Is this a sane way of doing things? How do other games handle this?


Lastly, I have another issue to think about. I'm doing this in Javascript, so there really is no public/private in the traditional sense. So I don't want to give the AIs direct access to the Units, because they would have access to things like setPosition() which would allow for teleporting (aka cheating :P). So how do other games get around this? Do they usually just not care b/c AIs are generally trusted pieces of code?

The only thought I've had so far about this is to provide a Proxy object that the AI gets access to and only has "safe" methods which it proxies on through to the actual game object. But this is kinda clunky... requires an extra class for every Game Object.

Thanks in advance for the help :)




If you want to prevent the created AI from accessing all the data, then you make the program operate as a server-client pair where the client only gets the information
that the server sends it. If a unit moves and that player is supposed to see it move then that info would be sent to the client (and everything they shouldnt see is never sent).
Normally the visual output comes from that info and is displayed to a player and then the player issues commands as input that then goes back to the 'server' where the bookkeeping
of the game mechanics takes place.
The local scripted AI would run in the client and would have no way to access the servers info -- only the data the server sends to the client.

The server would filter the information available to each client by certain limitations (area or view blockage or fog of unexplored areas etc..) and everything else going on in the game
never gets sent. The basic info would then have to be analyzed/interpretted by the AI according to game mechanics to figure out what is going on and then to make the appropriate decisions as
to what commands to send. This is where most of the difficulty is (and the processing load) as you have to analyze everything that happens whether its significant or not
and decide which information IS significant and then assess the situation (which may include remembering past turns data/ information to spot progressive patterns and project the future).
Priorities are determined for different goals which are evaluated as to which are possible and likely to be achieved in near time and oppotunities exploited when something beneficial can be done immediately. Some solutions take a length of time to achieve (sequences of actions) and if they are interupted they can never get done so decisions must be based on the payoff against the cost of the actions to be taken.

If your simulation is 'super' simple you can use limitations of basic range (box area of a certain size) as to factors to consider (ie like picking possible targets) and decide which one is best (do you even have a view block mechanism for terrain features...) Nearest things go high in priority (sort by range) an the best will be chosen. If there are multiple unit factors that have to be considered
in state decisions (like preserving health/damage vs offensive actions to nullify enemies vs getting buffs, etc..) then you have to build functions that escalate priority the worse/more needy each factor gets which will adjust the importance of the different tactics/action goals.

If units cordinate between themselve (the AI is to issue orders to multiple unit to coordinate game actions and achieve goals) then the complexity increases a magnitude.
--------------------------------------------[size="1"]Ratings are Opinion, not Fact

Why can't the AI access units directly? Let it look at their HP, their current position in the world, etc. etc. and use that information in any way it sees fit. Just don't provide it any API for doing things you don't want it to do, like teleportation.

The state machine concept is an improvement, but I'd still find it painfully limiting. If I want to write an AI that isn't easily modeled as a finite state machine, then I have to go through ugly contortions to fit my model of AI with your model of AI, and that just strikes me as needlessly ugly.




If the game mechanics are based on units having to do sequences of diffenet actions with different phases (identify target, move to target, attack target) you usually have to use some kind of state machine for that. The decisions to start such a sequence is an ongoing evaluation of the game situation and thus the added state machine features of aborting a particular sequence (and possibly resuming it later) as well as retry limitations (deciding when to give up and try something else a different solution)
--------------------------------------------[size="1"]Ratings are Opinion, not Fact
What if I want to write my AI using behavior trees instead of flat state machines?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement