Threat Calculation
Started by WizWom, Sep 22 2006 08:35 PM
10 replies to this topic
#1
Posted 22 September 2006 - 08:35 PM
For My Tutu NPC, I've made a fairly sophisticated threat calculator, mainly for Mages.
generally, it decides how dangerous to th mage the nearest enemy closer than 8 (a distance which should take 2 seconds to cross) is and how dangerous the furthest spellcaster is (priority goes Mage, cleric, druid, bard, if I'm scripting right). It takes into account the mages resilience and the spellcaster's power. It then chooses between these two if both are present.
And since I keep the threat calculation, I can then have the script use different spells for differeing levels of danger - of course, I like putting out a magic missile or acid arrow to disrupt preferentially. Clerics, of course, should open with a disrupting insect swarm.
Anyway, it also can be extended to fighters, in that they can just choose to attack the target if they are ranging, or the nearest non-trivial if they are meleeing.
I'm basing it off the TAZQ series of scripts, but I'm ending up chopping stuff out because it will never be seen in tutu, and recoding almost all the tests :-)
generally, it decides how dangerous to th mage the nearest enemy closer than 8 (a distance which should take 2 seconds to cross) is and how dangerous the furthest spellcaster is (priority goes Mage, cleric, druid, bard, if I'm scripting right). It takes into account the mages resilience and the spellcaster's power. It then chooses between these two if both are present.
And since I keep the threat calculation, I can then have the script use different spells for differeing levels of danger - of course, I like putting out a magic missile or acid arrow to disrupt preferentially. Clerics, of course, should open with a disrupting insect swarm.
Anyway, it also can be extended to fighters, in that they can just choose to attack the target if they are ranging, or the nearest non-trivial if they are meleeing.
I'm basing it off the TAZQ series of scripts, but I'm ending up chopping stuff out because it will never be seen in tutu, and recoding almost all the tests :-)
#2
Posted 23 September 2006 - 05:30 AM
WizWorm,
Threat assessment is pretty tricky, cool that you've worked something out that is effective.
Ideally you would be able to have a 'global' threat level = the amount of trouble the whole part is in e.g.,
Red = 1 Tarasque or 2 summoned demons + 2 mages + 2 Fighters + 2 Clerics
Yellow = 5 Fire Giants or 8 10th+ lvl creatures
Green = 10 Kobolds or 3 Carrion Crawlers
And then have an individual threat level based on who/what is currently attacking a particular party memember.
Then you would figure out some way to mesh the two systems to react appropriately e.g., the mage realizing that he is in serious trouble runs off towards your fighters to get some help with the Iron Golem that is trying to maul him/her.
Care to post some snippets with an explanation or is the code proprietary?
Does your threat assessment scale well? Tutu vs. BG2?
TAZQ series of scripts? ...Never heard of this system
Thanks,
Threat assessment is pretty tricky, cool that you've worked something out that is effective.
Ideally you would be able to have a 'global' threat level = the amount of trouble the whole part is in e.g.,
Red = 1 Tarasque or 2 summoned demons + 2 mages + 2 Fighters + 2 Clerics
Yellow = 5 Fire Giants or 8 10th+ lvl creatures
Green = 10 Kobolds or 3 Carrion Crawlers
And then have an individual threat level based on who/what is currently attacking a particular party memember.
Then you would figure out some way to mesh the two systems to react appropriately e.g., the mage realizing that he is in serious trouble runs off towards your fighters to get some help with the Iron Golem that is trying to maul him/her.
Care to post some snippets with an explanation or is the code proprietary?
Does your threat assessment scale well? Tutu vs. BG2?
TAZQ series of scripts? ...Never heard of this system
Thanks,
Cirerrek
Be sure not to dive into the shallow end of your imagination - Grover
Be sure not to dive into the shallow end of your imagination - Grover
#3
Posted 23 September 2006 - 07:42 AM
Well, the whole point was to make a scaling threat assessment, for Tutu. since what's really dangerous as 1st level isn't going to phase you when you've make 5th or 6th. So, you need to use your magic/items to battle a wolf at first level, but you probably won't break a sweat fighting a Dire wolf at 4th.
The scripts were an extension on someone's q-series scripts, off of sorcerer's place.
BG2 aiscripts by Tapio Kivikkola <zap@mad.scientist.com>
It included upgraded summons AI & somewhat better
The scripts were an extension on someone's q-series scripts, off of sorcerer's place.
BG2 aiscripts by Tapio Kivikkola <zap@mad.scientist.com>
It included upgraded summons AI & somewhat better
Quote
Similiar to orginal Blucher's scripts, but usage of scrolls, some items and most of area spells are removed (in my game, however, Aerie still casts Fireball).
Also alchemy is removed.
Also alchemy is removed.
#4
Posted 23 September 2006 - 07:55 AM
As for the teamwork, have you looked at
http://www.citilink.com/~jch/bg/
He seems to have spent some time working on his scripts. I grabbed them, to see if he's got anything interesting in there.
http://www.citilink.com/~jch/bg/
He seems to have spent some time working on his scripts. I grabbed them, to see if he's got anything interesting in there.
#5
Posted 26 September 2006 - 07:54 AM
Just to chime in, I'm now testing my own threat level system in IWD2. My brief experience seems to indicate that at least the following factors should be considered:
That made it much more trivial to think appropriately for spell and item usage: I'll gladly cast Mirror Image (spell level 2) or drink a Potion of Aid (spell level 2) if my MaxSpellLevel is 2 or higher.
An added bonus is that as I refine the list of threat contributors above, I merely have to adjust the maximum spell level appropriately as I find the threat system too lenient or too strict, and all the items/spells I have coded will "take care of themselves".
My testing so far has been pretty limited, but I've been happy with the system. I will admit that IWD2's scripting engine -- and allocation of enemies -- actually makes threat assessment a little easier than the BG2 engine IMO, but that's small consolation for the multitude of bugs that are in the engine overall.
As a secondary note, the inclusion of character-specific modifiers to threat level (most notably personal health) meant that a global threat level seemed less appropriate than a personal one. In addition, I found that global threat calculation had to be handled very carefully (to ensure that everyone isn't constantly trying to adjust it), so I've abandoned global threat level for now.
- Number of non-disabled enemies
- Number of nearby allies
- Health (and status) of party
- Presence of enemy spellcasters
- Checks for (a few) particularly nasty enemy types
- and, very importantly, Personal health
That made it much more trivial to think appropriately for spell and item usage: I'll gladly cast Mirror Image (spell level 2) or drink a Potion of Aid (spell level 2) if my MaxSpellLevel is 2 or higher.
An added bonus is that as I refine the list of threat contributors above, I merely have to adjust the maximum spell level appropriately as I find the threat system too lenient or too strict, and all the items/spells I have coded will "take care of themselves".
My testing so far has been pretty limited, but I've been happy with the system. I will admit that IWD2's scripting engine -- and allocation of enemies -- actually makes threat assessment a little easier than the BG2 engine IMO, but that's small consolation for the multitude of bugs that are in the engine overall.
As a secondary note, the inclusion of character-specific modifiers to threat level (most notably personal health) meant that a global threat level seemed less appropriate than a personal one. In addition, I found that global threat calculation had to be handled very carefully (to ensure that everyone isn't constantly trying to adjust it), so I've abandoned global threat level for now.
#6
Posted 26 September 2006 - 11:04 AM
well, generally, my script starts with a "fix-up" section, which tests for low HP or poison and tries to remedy.
The, if I'm not in combat and see nothing threatening, I break.
Combat threat calculation is:
So, if I have no enemy with a WXJON_TARGET, then I know I am not threatened.
If I see an enemy with WXJON_TARGET, then I can decide whether it is a mage or a melee combatant, if it is a mage, I can use blocks like:
The "GBHalfAttack" bit is to let the next pass through the script use a ranged weapon, so I don't waste the rest of the round.
The, if I'm not in combat and see nothing threatening, I break.
Combat threat calculation is:
IF
True()
THEN
RESPONSE #100
SetGlobal("WxNearDanger","LOCALS",0)
SetGlobal("WxMageDanger","LOCALS",0)
Continue()
END
IF
Global("Debug","GLOBAL",1)
THEN
RESPONSE #100
PauseGame()
Continue()
END
IF
See(NearestEnemyOf(Myself))
Range(LastSeenBy(Myself),8)
THEN
RESPONSE #100
SetGlobal("WxNearDanger","LOCALS",3)
Continue()
END
IF
HPLT(LastSeenBy(Myself),10)
Range(LastSeenBy(Myself),8)
THEN
RESPONSE #100
IncrementGlobal("WxNearDanger","LOCALS",-1)
Continue()
END
IF
HPLT(LastSeenBy(Myself),5)
Range(LastSeenBy(Myself),8)
THEN
RESPONSE #100
IncrementGlobal("WxNearDanger","LOCALS",-1)
Continue()
END
IF
HPGT(LastSeenBy(Myself),20)
Range(LastSeenBy(Myself),8)
THEN
RESPONSE #100
IncrementGlobal("WxNearDanger","LOCALS",1)
Continue()
END
IF
HPGT(LastSeenBy(Myself),35)
Range(LastSeenBy(Myself),8)
THEN
RESPONSE #100
IncrementGlobal("WxNearDanger","LOCALS",1)
Continue()
END
IF
HPGT(LastSeenBy(Myself),50)
THEN
RESPONSE #100
IncrementGlobal("WxNearDanger","LOCALS",1)
Continue()
END
IF
HPGT(LastSeenBy(Myself),65)
THEN
RESPONSE #100
IncrementGlobal("WxNearDanger","LOCALS",1)
Continue()
END
IF
HPGT(Myself,40)
Range(LastSeenBy(Myself),8)
THEN
RESPONSE #100
IncrementGlobal("WxNearDanger","LOCALS",-1)
Continue()
END
IF
HPGT(Myself,30)
Range(LastSeenBy(Myself),8)
THEN
RESPONSE #100
IncrementGlobal("WxNearDanger","LOCALS",-1)
Continue()
END
IF
HPGT(Myself,15)
Range(LastSeenBy(Myself),8)
THEN
RESPONSE #100
IncrementGlobal("WxNearDanger","LOCALS",-1)
Continue()
END
IF
GlobalLT("WxNearDanger","LOCALS",0)
THEN
RESPONSE #100
SetGlobal("WxNearDanger","LOCALS",0)
ChangeSpecifics(NearestEnemyOf(Myself),WWXJON_TRIVIAL)
Continue()
END
IF
GlobalGT("WxNearDanger","LOCALS",3)
THEN
RESPONSE #100
Shout(124)
ChangeSpecifics(NearestEnemyOf(Myself),WXJON_TARGET)
Continue()
END
IF
OR(4)
See([ENEMY.0.0.CLERIC_ALL])
See([ENEMY.0.0.LONG_BOW])
See([ENEMY.0.0.BARD_ALL])
See([ENEMY.0.0.DRUID_ALL])
THEN
RESPONSE #100
SetGlobal("WxMageDanger","LOCALS",3)
Continue()
END
IF
GlobalGT("WxMagedanger","LOCALS",0)
LevelLT(LastSeenBy(Myself),3)
THEN
RESPONSE #100
IncrementGlobal("WxMageDanger","LOCALS",-1)
Continue()
END
IF
GlobalGT("WxMagedanger","LOCALS",0)
LevelLT(LastSeenBy(Myself),5)
THEN
RESPONSE #100
IncrementGlobal("WxMageDanger","LOCALS",-1)
Continue()
END
IF
GlobalGT("WxMagedanger","LOCALS",0)
LevelGT(LastSeenBy(Myself),6)
THEN
RESPONSE #100
IncrementGlobal("WxMageDanger","LOCALS",2)
Continue()
END
IF
GlobalGT("WxMagedanger","LOCALS",0)
LevelGT(LastSeenBy(Myself),8)
THEN
RESPONSE #100
IncrementGlobal("WxMageDanger","LOCALS",2)
Continue()
END
IF
GlobalGT("WxMagedanger","LOCALS",0)
CheckStatGT(Myself,10,SAVEVSSPELL)
THEN
RESPONSE #100
IncrementGlobal("WxMageDanger","LOCALS",1)
Continue()
END
IF
GlobalGT("WxMagedanger","LOCALS",0)
CheckStatGT(Myself,13,SAVEVSSPELL)
THEN
RESPONSE #100
IncrementGlobal("WxMageDanger","LOCALS",1)
Continue()
END
IF
GlobalGT("WxMagedanger","LOCALS",0)
CheckStatGT(Myself,16,SAVEVSSPELL)
THEN
RESPONSE #100
IncrementGlobal("WxMageDanger","LOCALS",1)
Continue()
END
IF
GlobalGT("WxMagedanger","LOCALS",0)
CheckStatLT(Myself,6,SAVEVSSPELL)
THEN
RESPONSE #100
IncrementGlobal("WxMageDanger","LOCALS",-1)
Continue()
END
IF
HPGT(Myself,40)
GlobalGT("WxMagedanger","LOCALS",0)
THEN
RESPONSE #100
IncrementGlobal("WxMageDanger","LOCALS",-1)
Continue()
END
IF
HPGT(Myself,30)
GlobalGT("WxMagedanger","LOCALS",0)
THEN
RESPONSE #100
IncrementGlobal("WxMageDanger","LOCALS",-1)
Continue()
END
IF
HPGT(Myself,15)
GlobalGT("WxMagedanger","LOCALS",0)
THEN
RESPONSE #100
IncrementGlobal("WxMageDanger","LOCALS",-1)
Continue()
END
IF
GlobalLT("WxMagedanger","LOCALS",0)
THEN
RESPONSE #100
SetGlobal("WxMageDanger","LOCALS",0)
ChangeSpecifics(LastSeenBy(Myself),WWXJON_TRIVIAL)
Continue()
END
IF
GlobalGT("WxMagedanger","LOCALS",0)
!See([0.0.0.0.WXJON_TARGET])
THEN
RESPONSE #100
ChangeSpecifics(LastSeenBy(Myself),WXJON_TARGET)
Continue()
END
IF
GlobalGT("WxMageDanger","LOCALS",0)
See([0.0.0.0.WXJON_TARGET])
OR(4)
See([ENEMY.0.0.CLERIC_ALL])
See([ENEMY.0.0.LONG_BOW])
See([ENEMY.0.0.BARD_ALL])
See([ENEMY.0.0.DRUID_ALL])
LocalsGT("WxMageDanger","WxNearDanger")
THEN
RESPONSE #100
ChangeSpecifics(LastSeenBy(Myself),WXJON_TARGET)
ChangeSpecifics(NearestEnemyOf(Myself),0)
Continue()
END
So, if I have no enemy with a WXJON_TARGET, then I know I am not threatened.
If I see an enemy with WXJON_TARGET, then I can decide whether it is a mage or a melee combatant, if it is a mage, I can use blocks like:
IF
LocalsGT("WxMageDanger","WxNearDanger")
See([0.0.0.0.WXJON_TARGET])
CheckStatLT(Myself,35,SPELLFAILUREMAGE)
CheckStatLT(LastSeenBy(Myself),50,RESISTMAGIC)
!HasBounceEffects(LastSeenBy(Myself))
!HasItemEquiped("mageamul",LastSeenBy(Myself)) // Necklace
!StateCheck(LastSeenBy(Myself),STATE_INVISIBLE)
!StateCheck(LastSeenBy(Myself),STATE_IMPROVEDINVISIBILITY)
CheckStatLT(LastSeenBy(Myself),25,RESISTACID)
HaveSpell(WIZARD_MELF_ACID_ARROW)
THEN
RESPONSE #100
SetInterrupt(FALSE)
SetGlobalTimer("GBHalfAttack","LOCALS",ONE_ROUND)
Spell(LastSeenBy(Myself),WIZARD_MELF_ACID_ARROW)
END
The "GBHalfAttack" bit is to let the next pass through the script use a ranged weapon, so I don't waste the rest of the round.
#7
Posted 26 September 2006 - 06:53 PM
Wizworm,
Not sure about BG1, but it BG2, you can break the game by changing specifics of a character. That is why I dropped the ChangeSpecifics targeting from the eSeries and went to using Detectable Spells (not that it doesn't have its issues).
Not sure about BG1, but it BG2, you can break the game by changing specifics of a character. That is why I dropped the ChangeSpecifics targeting from the eSeries and went to using Detectable Spells (not that it doesn't have its issues).
Cirerrek
Be sure not to dive into the shallow end of your imagination - Grover
Be sure not to dive into the shallow end of your imagination - Grover
#8
Posted 26 September 2006 - 07:12 PM
As far as it goes, I change specifics of NPC, not characters...
I'm running this under tutu, so the engine is BG2. I saw the note about multiplayer using specific; I would expect they use it to tell who controlls what sprites.
It's a shame, because othewise I can't really make a turing machine, as I have no real way to store data. It's a bit of a hack, but it was seeming to work.
I'm running this under tutu, so the engine is BG2. I saw the note about multiplayer using specific; I would expect they use it to tell who controlls what sprites.
It's a shame, because othewise I can't really make a turing machine, as I have no real way to store data. It's a bit of a hack, but it was seeming to work.
Edited by WizWom, 26 September 2006 - 07:15 PM.
#9
Posted 26 September 2006 - 08:27 PM
WizWom, on Sep 26 2006, 10:17 PM, said:
As far as it goes, I change specifics of NPC, not characters...
I'm running this under tutu, so the engine is BG2. I saw the note about multiplayer using specific; I would expect they use it to tell who controlls what sprites.
It's a shame, because othewise I can't really make a turing machine, as I have no real way to store data. It's a bit of a hack, but it was seeming to work.
I'm running this under tutu, so the engine is BG2. I saw the note about multiplayer using specific; I would expect they use it to tell who controlls what sprites.
It's a shame, because othewise I can't really make a turing machine, as I have no real way to store data. It's a bit of a hack, but it was seeming to work.
--ChangeSpecifics(NearestEnemyOf(Myself),WWXJON_TRIVIAL)
I meant NPCs, darn esoteric terminology...
Wizworm, ah, TuTu. Is there someway to search as see if any ingame scripts are checking for Specifics to move the plot along? If BG1 (albeit in the BG2 engine) isn't using Specifics to advance quests or the plot line along, then you would still be okay using it.
Seems like you are saying that multiplayer definitely does. In that case, it would probably be a bad idea to use the scripts for multiplayer games.
Cirerrek
Be sure not to dive into the shallow end of your imagination - Grover
Be sure not to dive into the shallow end of your imagination - Grover
#10
Posted 26 September 2006 - 08:48 PM
Well, BG2 uses specifics for certain NPCs, from what i can see. So, I'm not sure it's wise to do this, anyway.
Since I know whether to target the NearestEnemy() or the LastSeen of a mage class, then I suppose I'll have to have the targeting in the blocks :-(
Since I know whether to target the NearestEnemy() or the LastSeen of a mage class, then I suppose I'll have to have the targeting in the blocks :-(
Reply to this topic

1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users











