Game AI, Skills, Bosses?
Game AI, Skills, Bosses?
Hi!
I have a big problem, what's quite hard for me.
Its about the system of the bots.
I wanna make a TPS/RPG hybrid game, with online play.
So, i have a server, what controls the bots, and it gets the datas from database.
So, my problem is i could make a simple ai for bots, but it isnt fun if every bot just coming straight to me, and shooting/hitting when it can, and use all of they skills when cooldown ended...
thats quite ugly, isnt that?
so i wanna give "personality" to them.
for example a mob, what snipes, shooting from far, and if i go close, that should run away.
other one should always chase the player.
another one shoot from far away, if player comes cloes, then use skill, and start chase.
another one should use all of its skill, then shoot.
another one should shoot from far, if player comes close, then start attacking melee..
etc etc etc... so many personalities...
i had been said make this, but honestly, have no idea where to start.
maybe adding a data to every mob, a personality ID, and check it in every frame, what should it do next?
or just make an event handler, and if an event occured (onhit, and so on), check personality with a switch-case statement and give a command what to do until next command?
and in top of that, i need to make bosses too.
you know, in a good game boss fight isnt about that the boss has 1251254 life, but the same fight as normal bots.
every boss has to be different.
but i dont know all the boss personalities at present, i need to add more bosses later, so the system has to be flexible.
and the other one, the skill system.
in a fun game, mobs should have various skills, not just hit 20, hit 30, hit 40, heal 10, heal 20, heal 30, and thats all
i need buffer what attacks near players in every 5 second, suicide bomb, summoning other monsters, and various things.
so how should i start it?
give an id to every skill, and program all the variations in a switch case?
or giving a type, and one or more parameter?
and program all the types (and can add later too), and use them more than once, with different parameters?
sorry for bad english..
thanks for the help
EDIT: oh and so, every one could be done with script, right... but how do i input script to database? xD
or should i put them next to the server exe file?
and so, should i make an own script language, or use premade ones, like lua?
I have a big problem, what's quite hard for me.
Its about the system of the bots.
I wanna make a TPS/RPG hybrid game, with online play.
So, i have a server, what controls the bots, and it gets the datas from database.
So, my problem is i could make a simple ai for bots, but it isnt fun if every bot just coming straight to me, and shooting/hitting when it can, and use all of they skills when cooldown ended...
thats quite ugly, isnt that?
so i wanna give "personality" to them.
for example a mob, what snipes, shooting from far, and if i go close, that should run away.
other one should always chase the player.
another one shoot from far away, if player comes cloes, then use skill, and start chase.
another one should use all of its skill, then shoot.
another one should shoot from far, if player comes close, then start attacking melee..
etc etc etc... so many personalities...
i had been said make this, but honestly, have no idea where to start.
maybe adding a data to every mob, a personality ID, and check it in every frame, what should it do next?
or just make an event handler, and if an event occured (onhit, and so on), check personality with a switch-case statement and give a command what to do until next command?
and in top of that, i need to make bosses too.
you know, in a good game boss fight isnt about that the boss has 1251254 life, but the same fight as normal bots.
every boss has to be different.
but i dont know all the boss personalities at present, i need to add more bosses later, so the system has to be flexible.
and the other one, the skill system.
in a fun game, mobs should have various skills, not just hit 20, hit 30, hit 40, heal 10, heal 20, heal 30, and thats all
i need buffer what attacks near players in every 5 second, suicide bomb, summoning other monsters, and various things.
so how should i start it?
give an id to every skill, and program all the variations in a switch case?
or giving a type, and one or more parameter?
and program all the types (and can add later too), and use them more than once, with different parameters?
sorry for bad english..
thanks for the help
EDIT: oh and so, every one could be done with script, right... but how do i input script to database? xD
or should i put them next to the server exe file?
and so, should i make an own script language, or use premade ones, like lua?
-
- Posts: 1638
- Joined: Mon Apr 30, 2007 3:24 am
- Location: Montreal, CANADA
- Contact:
First start by checking the example of IRRai.
They provide examples to define certain NPC abilities. If you implement scripting, then you could easily define classes (and tweak them as you wish without rebuilding the engine)
You will have also to use a navigation meshes or navigation nodes so the bots are not only attacking you but are retreating. (IRRai even provide a simple editor to create thoses navigation nodes)
Check there:
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=25132
They provide examples to define certain NPC abilities. If you implement scripting, then you could easily define classes (and tweak them as you wish without rebuilding the engine)
You will have also to use a navigation meshes or navigation nodes so the bots are not only attacking you but are retreating. (IRRai even provide a simple editor to create thoses navigation nodes)
Check there:
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=25132
Here's something that might give you average to very high success considering your goals.
Start by coding the behaviours as low level as you can. This should not be in the script unless you see some good reason to (you can always open the door for additional low level behaviour scripted, if needs be). Make those like "Run to point A", "Run away from A", "Shoot A", "Use Skill A (On B)", "Go to point A slowly", etc. You probably want to make those a class, all inheriting from a common action base or something the like.
Then, on top of that, build higher level behaviours. Things like "Run Away from group", "Use Skills from stronger to weaker", "Attack while staying safe", etc. Any action that would have a subset of action should prioritize them and always go to the highest possible which conditions are met.
aka, attack while staying safe, you might have "Shoot A", "Run to point A", "Run away from A". As conditions for shooting, you might put "Haven't been in hit in the last X seconds", and "Run away from A" could be "If closer than X units" and "Has been hit in the last X seconds" and "Run to point A", could be "Hasn't been hit in the last X seconds".
Good, now you have a building block. But that itself is an action. So you can put "Attack while dodging" in another tree with it's own conditions. Now you have pretty big building blocks for huge sets of behaviours. You can use those in scripts to build the trees and define the variables. You keep whatever speed would be lost on that part of the script while having the flexibility of a very adabtable AI.
Finally, for special cases, you can create actions specifically for them. Always see if you can't subdivide, you never know what you could reuse later.
Ah, final thoughts. Put a flag in the actions and define which is interruptable and which isn't. Don't forget, both low and high level blocks are actions. You might not care for most actions to be interrupted to go to a higher level in the tree at a higher branch when its conditions are met, but it will happen you'll want actions to be fully carried out before looking for the best action (However, in 99% of the case, it's a sign your priority doesn't reflect the behaviour you intend or the conditions aren't well defined. Hint, you can reuse the same building block at different point in the hierarchy, even in the same branch)
Hope this will help, have a good day
Start by coding the behaviours as low level as you can. This should not be in the script unless you see some good reason to (you can always open the door for additional low level behaviour scripted, if needs be). Make those like "Run to point A", "Run away from A", "Shoot A", "Use Skill A (On B)", "Go to point A slowly", etc. You probably want to make those a class, all inheriting from a common action base or something the like.
Then, on top of that, build higher level behaviours. Things like "Run Away from group", "Use Skills from stronger to weaker", "Attack while staying safe", etc. Any action that would have a subset of action should prioritize them and always go to the highest possible which conditions are met.
aka, attack while staying safe, you might have "Shoot A", "Run to point A", "Run away from A". As conditions for shooting, you might put "Haven't been in hit in the last X seconds", and "Run away from A" could be "If closer than X units" and "Has been hit in the last X seconds" and "Run to point A", could be "Hasn't been hit in the last X seconds".
Good, now you have a building block. But that itself is an action. So you can put "Attack while dodging" in another tree with it's own conditions. Now you have pretty big building blocks for huge sets of behaviours. You can use those in scripts to build the trees and define the variables. You keep whatever speed would be lost on that part of the script while having the flexibility of a very adabtable AI.
Finally, for special cases, you can create actions specifically for them. Always see if you can't subdivide, you never know what you could reuse later.
Ah, final thoughts. Put a flag in the actions and define which is interruptable and which isn't. Don't forget, both low and high level blocks are actions. You might not care for most actions to be interrupted to go to a higher level in the tree at a higher branch when its conditions are met, but it will happen you'll want actions to be fully carried out before looking for the best action (However, in 99% of the case, it's a sign your priority doesn't reflect the behaviour you intend or the conditions aren't well defined. Hint, you can reuse the same building block at different point in the hierarchy, even in the same branch)
Hope this will help, have a good day
Again, make your tree deep enough with enough branches, and you only lose using random. You're probably thinking it will look more "realistic", as in, not part of a pattern. But that's exactly the problem. That's why it WILL look unrealistic. People follow patterns. And the better they get, the more patterns they have, one for each situation. The method I rapidly described here helps aleviate that problem. Pick a few books on AI or play in the field for a bit, you'll see that what might appear random in a complex game of skills usually isn't and is simply the result of multiple filters rapidly selecting and deselecting behaviours amongst a wide selection of choices.
thanks for the answers
i decided to use script.
i make functions (waitUntilTime(mobID, time)
goToPos(mobID, X, Z, speed)
goToPlayer(mobID, playerID, distance)
attackPlayerCount(mobID, playerID, count)
attackPlayerTime(mobID, playerID, end)
setTarget(mobID, playerID)
useSkillOnPlayer(mobID, playerID, skillID)
useSkillOnMob(mobID, targetmobID, skillID)
spawnMob(mobID, x, z)
destroyMob(mobID)
thats all until now xD), what i can call from script.
and i make events:
onSpawn - mobID
onSight - mobID, sightedID
onDamaged - attackerID, amount
onHit - attackedID, amount
onHeal - healerID, healedID
onBuff - buffcasterID, buffID
onKill - killedID
onDie - killerID
onTargetChange - lastTargetID, nextTargetID
onTick - tick
so, i can make scripts for every event.
and, i plan to make an action queue, in script i fill it.
like
go to point A -> attack -> go to point B -> use skill
and i give them a condition when to stop (for example for attack, a counter, what ends the after reaching a number, or after a certain time etc)
am i doing right?
i decided to use script.
i make functions (waitUntilTime(mobID, time)
goToPos(mobID, X, Z, speed)
goToPlayer(mobID, playerID, distance)
attackPlayerCount(mobID, playerID, count)
attackPlayerTime(mobID, playerID, end)
setTarget(mobID, playerID)
useSkillOnPlayer(mobID, playerID, skillID)
useSkillOnMob(mobID, targetmobID, skillID)
spawnMob(mobID, x, z)
destroyMob(mobID)
thats all until now xD), what i can call from script.
and i make events:
onSpawn - mobID
onSight - mobID, sightedID
onDamaged - attackerID, amount
onHit - attackedID, amount
onHeal - healerID, healedID
onBuff - buffcasterID, buffID
onKill - killedID
onDie - killerID
onTargetChange - lastTargetID, nextTargetID
onTick - tick
so, i can make scripts for every event.
and, i plan to make an action queue, in script i fill it.
like
go to point A -> attack -> go to point B -> use skill
and i give them a condition when to stop (for example for attack, a counter, what ends the after reaching a number, or after a certain time etc)
am i doing right?
I'd say it's a step in the right direction. But you're losing a huge chunk on adaptability if your script is too linear (of course, that depends if some of your conditions are show stopper that can cancel the current action and restart the action selection, in which case I'd say it's nothing more than a poor man's tree, since you basically make your branching from the start and need to double the work for very similar tactics with a small variation.
BTW, that's why a tree form is advantageous. You might want your mages to always have the same behaviour, but to leave the selection of the spell to a specific criteria (or snipers and gun or whatever.) Thing is, most unit will have a huge number of small variations if you want them to be good and look realistic, however, coding each of those branches from the root to the leaf is kind of useless. Also, it'll likely be a lot slower if you do make big tree. (4 branch selection of 10 branches beats 1 selection of 10000 branches any day ^^ ), unless, again, you imitate a tree in your condition organisation, in which case you'll have spaggethi code.
BTW, script is EXCELLENT for prototyping. It's also perfect for anything you'd like to leave up to the player to change. However, when most of your decisions are made, you should port the bulk of it to code and, if needs be, leave accesses to it in your script. It thus becomes faster, better integrated, easier to see mistakes and cleaner for the script interface, if you decide to keep it.
BTW, that's why a tree form is advantageous. You might want your mages to always have the same behaviour, but to leave the selection of the spell to a specific criteria (or snipers and gun or whatever.) Thing is, most unit will have a huge number of small variations if you want them to be good and look realistic, however, coding each of those branches from the root to the leaf is kind of useless. Also, it'll likely be a lot slower if you do make big tree. (4 branch selection of 10 branches beats 1 selection of 10000 branches any day ^^ ), unless, again, you imitate a tree in your condition organisation, in which case you'll have spaggethi code.
BTW, script is EXCELLENT for prototyping. It's also perfect for anything you'd like to leave up to the player to change. However, when most of your decisions are made, you should port the bulk of it to code and, if needs be, leave accesses to it in your script. It thus becomes faster, better integrated, easier to see mistakes and cleaner for the script interface, if you decide to keep it.
-
- Posts: 208
- Joined: Sun Apr 02, 2006 9:20 pm
I am currently working on an AI library and another thing you are going to have to take account of too are all of the lower level functions. The description of walk able areas or paths, the path finding, collision avoidance, the formation of groups or combative units, the determination of line of sight and selection of hidden or visible points.
These are quite tricky but there are plenty of articles to give you lots of good ideas and sample code. Its certainly a big task though and I would recommend having a good look around to see if there is an existing AI library out there that can fill your needs adequately.
These are quite tricky but there are plenty of articles to give you lots of good ideas and sample code. Its certainly a big task though and I would recommend having a good look around to see if there is an existing AI library out there that can fill your needs adequately.
I suppose you might be able to use IrrAI for the lower level stuff... It's got waypoint graphs (and an editor to create them) and pathfinding support so could probably be used to calculate where you're allowed to go and how to get there.
I dream of adding navmesh support to IrrAI at some point but the games industry isn't a job that lends well to working on personal projects! One day I'll get there....
So you could check out IrrAI and see if it would help but there may well be better solutions out there.
I dream of adding navmesh support to IrrAI at some point but the games industry isn't a job that lends well to working on personal projects! One day I'll get there....
So you could check out IrrAI and see if it would help but there may well be better solutions out there.
dorth: so, you mean, i make first low level functions (like go to point, attack while, or things what i wrote before), then use them in script, and if i make a high level script (attack while running, attacking while casting, escape from group, etc), and if that works, then i input them into c++ code, and from script i just have to call that function?
Frank Dodd: uhm yeah collision... i will have a big problem with that i think... xD but later
JP: yeah, i will use irrAi as reference, but i prefer making my own if i can.. of course if i fail, then ill use that
Frank Dodd: uhm yeah collision... i will have a big problem with that i think... xD but later
JP: yeah, i will use irrAi as reference, but i prefer making my own if i can.. of course if i fail, then ill use that
Don't think I do, but I have trouble understanding your meaning. Let's say you've got basic actions, like you mentioned. We'll call those actions, A. So we got a group of say, 5 basic actions. A1, A2, A3, A4 and A5.
Then, we have conditions. We can have as many as you like. For now, let's say all possible conditions will be Z1 to Z9, for simplicity sake.
Now, let's build higher level actions with those 2 things, which we will name B:
B1:
(Z2,Z4){A1}
(Z2,!Z5,!Z6){A3}
(!Z2){A2}
B2:
(Z2,Z5){A1}
(Z2,!Z4,Z5){A4}
(!Z2){A2}
And so on until B5.
(5 is an arbitrary quantity chosen for the sake of the example.)
NOW!
Let's build higher level action with those and call them C:
C1:
(Z1){B1}
(!Z1,Z2,Z4){B2}
(!Z1,!Z2){A2}
and so on...
You can do this as much as you need.
You can then build a complete AI behaviour by simply doing what you've been doing since earlier, meaning picking a few actions, may it be A, B, C, D or whatever and coupling it with one or more condition Z.
Whether you do it all in scripting or in code is irrelevant. This is a layout, not an execution. What I would recommend you do is build at least the basic actions and conditions in code (A and Z), then put hooks in your script to build the other layers (B, C, D, ...). You can also put hooks to extend the basic layer and conditions (A' and Z').
A further recommendation is that when you've finished working on one of those block and all those within, unless you want players to be able to change it, to then port it in the code. That way it will both run faster and make your API cleaner.
Good luck!
Then, we have conditions. We can have as many as you like. For now, let's say all possible conditions will be Z1 to Z9, for simplicity sake.
Now, let's build higher level actions with those 2 things, which we will name B:
B1:
(Z2,Z4){A1}
(Z2,!Z5,!Z6){A3}
(!Z2){A2}
B2:
(Z2,Z5){A1}
(Z2,!Z4,Z5){A4}
(!Z2){A2}
And so on until B5.
(5 is an arbitrary quantity chosen for the sake of the example.)
NOW!
Let's build higher level action with those and call them C:
C1:
(Z1){B1}
(!Z1,Z2,Z4){B2}
(!Z1,!Z2){A2}
and so on...
You can do this as much as you need.
You can then build a complete AI behaviour by simply doing what you've been doing since earlier, meaning picking a few actions, may it be A, B, C, D or whatever and coupling it with one or more condition Z.
Whether you do it all in scripting or in code is irrelevant. This is a layout, not an execution. What I would recommend you do is build at least the basic actions and conditions in code (A and Z), then put hooks in your script to build the other layers (B, C, D, ...). You can also put hooks to extend the basic layer and conditions (A' and Z').
A further recommendation is that when you've finished working on one of those block and all those within, unless you want players to be able to change it, to then port it in the code. That way it will both run faster and make your API cleaner.
Good luck!