bdmn@Posted: Sat Sep 25, 2010 5:44 pm :
hi guys,

two questions:
does somebody know how to get the singleplayer ai stuff into multiplayer games? tether stuff that works on sp ends in multiplayer with monsters running into the walls.

2nd one needs a little example as intro:

i got 3 rooms, A - B - C

in A monsters spawn for team 0, in C monsters for team 1. in each room is a tether which will be targetted for the enemy team, to run accross the map to the enemy spawn. they meet in mid, the B room. they fight, but they dont fight till the end. as triggered they try to reach the tether in highest priority..

how to tell the ai, to finish the fight and run after it to the tether?

thx for help



The Happy Friar@Posted: Mon Sep 27, 2010 3:18 pm :
Needs to be done in the SDK. Some people did do it (I forget who). From what I've read, it's not as easy as adding a new #define or an include.



bdmn@Posted: Mon Sep 27, 2010 4:35 pm :
atm im trying to work around with some ai triggers. the result is fine for the sandbox, but i have to evaluate if the amount of triggers and threads will affect the performance.



AnthonyJa@Posted: Mon Sep 27, 2010 5:11 pm :
As the friar said, you're going to have to go SDK side if you need this to work in real multiplayer - ie, with multiple people connected to the server. Are you trying to do something that simply works like multiplayer mode, but will only actually be one player?



bdmn@Posted: Mon Sep 27, 2010 5:25 pm :
oh, yeah sure... tx. somebody got any experience, even on the doom sdk? they should be "very" similar.



The Happy Friar@Posted: Mon Sep 27, 2010 6:58 pm :
actually, Q4 is as far from D3 as you can almost get. :) lots of stuff was moved/cut/added/changed to make Q4.

I seem to remember a Q4 coop mod in dev once. Oneofthe8devilz released his coop code for D3, so that could be a start.

Any particular reason you're using Q4 vs D3 (I found Q4's AI to be pretty darn good myself).



AnthonyJa@Posted: Mon Sep 27, 2010 10:04 pm :
bdmn wrote:
how to tell the ai, to finish the fight and run after it to the tether?


That's going to need an SDK change too from what I can see. I've never looked closely at the tactical AI (maybe I should? might make bots more intelligent...), but it looks as if being on a tether disables some of the other tactical decisions like melee / follow, in idAI::FilterTactical:

Code:
   // No tether move if not tethered
   if ( !IsTethered ( ) ) {
:
   // When tethered disable actions that dont adhear to the tether.
   } else {
      availableTactical &= ~(AITACTICAL_MELEE_BIT | AITACTICAL_MOVE_FOLLOW_BIT | AITACTICAL_HIDE_BIT  | AITACTICAL_COVER_ADVANCE_BIT | AITACTICAL_COVER_FLANK_BIT | AITACTICAL_COVER_RETREAT_BIT | AITACTICAL_COVER_AMBUSH_BIT);
   }


Removing that else clause looks like it would probably allow a tethered rvAITactical to decide to melee instead of sticking to it's tether, but I've certainly not tried it (ofc, they might get very side-tracked by the fight which is I guess why Raven did that).



bdmn@Posted: Tue Sep 28, 2010 2:56 pm :
thanks for you answer. i tried it, but this seems the wrong point. they dont finish fight, they attack while moving and stop fight out of range. reaching the tether breaks the game.

the condition isTethered checks if the monster is already at a tether, and the else statement handles the true case. it looks like they reset all states when a monster reaches the tether to let some kind of manager or the monster himself decide which states are valid from now on (depending on tether conditions,etc)

i really need to figure out where the hell the decision is made that its better reaching the tether than fighting with enemies in range...

i tried an overkill script which logically should solve the problems with several threads watching lists and triggering ai_trigger_multiples etc. but if u have 3 monsters each side ai will start to get pretty delayed and buggy.



bdmn@Posted: Tue Sep 28, 2010 5:26 pm :
thanks again, i got it. all changes have been made in AI_States.cpp. thanks for pointing me in the right direction.

Code:
switch ( newTactical ) {
   case AITACTICAL_MOVE_TETHER:
      if(enemy.ent){
         result = MoveToAttack ( enemy.ent, animator.GetAnim ( "ranged_attack" ) );
         // Found nothing but still have a find going
         if ( !result && aasFind ) {
            // turn ranged back on for next update on next frame
            combat.tacticalMaskUpdate |= AITACTICAL_RANGED_BIT;
            return false;
         }
         break;
      }
      result = MoveToTether ( tether );
      break;




your codespot had to be changed too:

Code:
// No tether move if not tethered
if ( !IsTethered ( ) ) {
   availableTactical &= ~(AITACTICAL_MOVE_TETHER_BIT);
   // Filter out any tactical states that require a leader
   if ( !leader || (enemy.ent && IsEnemyVisible() && enemy.range < move.followRange[1] * 2.0f ) ) {
      availableTactical &= ~(AITACTICAL_MOVE_FOLLOW_BIT);
   } else if ( leader && !enemy.ent ) {
      availableTactical &= ~(AITACTICAL_COVER_BITS);
   }
        // When tethered disable actions that dont adhear to the tether.
} else {
   if(!enemy.ent){
      availableTactical &= ~(AITACTICAL_MELEE_BIT|AITACTICAL_MOVE_FOLLOW_BIT|AITACTICAL_HIDE_BIT|AITACTICAL_COVER_ADVANCE_BIT|AITACTICAL_COVER_FLANK_BIT|AITACTICAL_COVER_RETREAT_BIT|AITACTICAL_COVER_AMBUSH_BIT);
   }
}





Code:
// handle Auto break tethers
if ( IsTethered ( ) && tether->IsAutoBreak ( ) && IsWithinTether ( ) ) {
   tether = NULL;
}

// bdmn begin:
      if(IsTethered ( ) && IsWithinTether () ){
         tether = NULL;
      }
// bdmn end


Code:

case AITACTICAL_MOVE_TETHER:
   // If not moving we dont want to idle in the move state so skip it
   if ( !move.fl.moving ) {
      return AICTRESULT_SKIP;
   }
   // We are still heading towards our tether so dont reissue a move
   return AICTRESULT_OK;      



bdmn@Posted: Sat Sep 25, 2010 5:44 pm :
hi guys,

two questions:
does somebody know how to get the singleplayer ai stuff into multiplayer games? tether stuff that works on sp ends in multiplayer with monsters running into the walls.

2nd one needs a little example as intro:

i got 3 rooms, A - B - C

in A monsters spawn for team 0, in C monsters for team 1. in each room is a tether which will be targetted for the enemy team, to run accross the map to the enemy spawn. they meet in mid, the B room. they fight, but they dont fight till the end. as triggered they try to reach the tether in highest priority..

how to tell the ai, to finish the fight and run after it to the tether?

thx for help



The Happy Friar@Posted: Mon Sep 27, 2010 3:18 pm :
Needs to be done in the SDK. Some people did do it (I forget who). From what I've read, it's not as easy as adding a new #define or an include.



bdmn@Posted: Mon Sep 27, 2010 4:35 pm :
atm im trying to work around with some ai triggers. the result is fine for the sandbox, but i have to evaluate if the amount of triggers and threads will affect the performance.



AnthonyJa@Posted: Mon Sep 27, 2010 5:11 pm :
As the friar said, you're going to have to go SDK side if you need this to work in real multiplayer - ie, with multiple people connected to the server. Are you trying to do something that simply works like multiplayer mode, but will only actually be one player?



bdmn@Posted: Mon Sep 27, 2010 5:25 pm :
oh, yeah sure... tx. somebody got any experience, even on the doom sdk? they should be "very" similar.



The Happy Friar@Posted: Mon Sep 27, 2010 6:58 pm :
actually, Q4 is as far from D3 as you can almost get. :) lots of stuff was moved/cut/added/changed to make Q4.

I seem to remember a Q4 coop mod in dev once. Oneofthe8devilz released his coop code for D3, so that could be a start.

Any particular reason you're using Q4 vs D3 (I found Q4's AI to be pretty darn good myself).



AnthonyJa@Posted: Mon Sep 27, 2010 10:04 pm :
bdmn wrote:
how to tell the ai, to finish the fight and run after it to the tether?


That's going to need an SDK change too from what I can see. I've never looked closely at the tactical AI (maybe I should? might make bots more intelligent...), but it looks as if being on a tether disables some of the other tactical decisions like melee / follow, in idAI::FilterTactical:

Code:
   // No tether move if not tethered
   if ( !IsTethered ( ) ) {
:
   // When tethered disable actions that dont adhear to the tether.
   } else {
      availableTactical &= ~(AITACTICAL_MELEE_BIT | AITACTICAL_MOVE_FOLLOW_BIT | AITACTICAL_HIDE_BIT  | AITACTICAL_COVER_ADVANCE_BIT | AITACTICAL_COVER_FLANK_BIT | AITACTICAL_COVER_RETREAT_BIT | AITACTICAL_COVER_AMBUSH_BIT);
   }


Removing that else clause looks like it would probably allow a tethered rvAITactical to decide to melee instead of sticking to it's tether, but I've certainly not tried it (ofc, they might get very side-tracked by the fight which is I guess why Raven did that).



bdmn@Posted: Tue Sep 28, 2010 2:56 pm :
thanks for you answer. i tried it, but this seems the wrong point. they dont finish fight, they attack while moving and stop fight out of range. reaching the tether breaks the game.

the condition isTethered checks if the monster is already at a tether, and the else statement handles the true case. it looks like they reset all states when a monster reaches the tether to let some kind of manager or the monster himself decide which states are valid from now on (depending on tether conditions,etc)

i really need to figure out where the hell the decision is made that its better reaching the tether than fighting with enemies in range...

i tried an overkill script which logically should solve the problems with several threads watching lists and triggering ai_trigger_multiples etc. but if u have 3 monsters each side ai will start to get pretty delayed and buggy.



bdmn@Posted: Tue Sep 28, 2010 5:26 pm :
thanks again, i got it. all changes have been made in AI_States.cpp. thanks for pointing me in the right direction.

Code:
switch ( newTactical ) {
   case AITACTICAL_MOVE_TETHER:
      if(enemy.ent){
         result = MoveToAttack ( enemy.ent, animator.GetAnim ( "ranged_attack" ) );
         // Found nothing but still have a find going
         if ( !result && aasFind ) {
            // turn ranged back on for next update on next frame
            combat.tacticalMaskUpdate |= AITACTICAL_RANGED_BIT;
            return false;
         }
         break;
      }
      result = MoveToTether ( tether );
      break;




your codespot had to be changed too:

Code:
// No tether move if not tethered
if ( !IsTethered ( ) ) {
   availableTactical &= ~(AITACTICAL_MOVE_TETHER_BIT);
   // Filter out any tactical states that require a leader
   if ( !leader || (enemy.ent && IsEnemyVisible() && enemy.range < move.followRange[1] * 2.0f ) ) {
      availableTactical &= ~(AITACTICAL_MOVE_FOLLOW_BIT);
   } else if ( leader && !enemy.ent ) {
      availableTactical &= ~(AITACTICAL_COVER_BITS);
   }
        // When tethered disable actions that dont adhear to the tether.
} else {
   if(!enemy.ent){
      availableTactical &= ~(AITACTICAL_MELEE_BIT|AITACTICAL_MOVE_FOLLOW_BIT|AITACTICAL_HIDE_BIT|AITACTICAL_COVER_ADVANCE_BIT|AITACTICAL_COVER_FLANK_BIT|AITACTICAL_COVER_RETREAT_BIT|AITACTICAL_COVER_AMBUSH_BIT);
   }
}





Code:
// handle Auto break tethers
if ( IsTethered ( ) && tether->IsAutoBreak ( ) && IsWithinTether ( ) ) {
   tether = NULL;
}

// bdmn begin:
      if(IsTethered ( ) && IsWithinTether () ){
         tether = NULL;
      }
// bdmn end


Code:

case AITACTICAL_MOVE_TETHER:
   // If not moving we dont want to idle in the move state so skip it
   if ( !move.fl.moving ) {
      return AICTRESULT_SKIP;
   }
   // We are still heading towards our tether so dont reissue a move
   return AICTRESULT_OK;      



bdmn@Posted: Sat Sep 25, 2010 5:44 pm :
hi guys,

two questions:
does somebody know how to get the singleplayer ai stuff into multiplayer games? tether stuff that works on sp ends in multiplayer with monsters running into the walls.

2nd one needs a little example as intro:

i got 3 rooms, A - B - C

in A monsters spawn for team 0, in C monsters for team 1. in each room is a tether which will be targetted for the enemy team, to run accross the map to the enemy spawn. they meet in mid, the B room. they fight, but they dont fight till the end. as triggered they try to reach the tether in highest priority..

how to tell the ai, to finish the fight and run after it to the tether?

thx for help



The Happy Friar@Posted: Mon Sep 27, 2010 3:18 pm :
Needs to be done in the SDK. Some people did do it (I forget who). From what I've read, it's not as easy as adding a new #define or an include.



bdmn@Posted: Mon Sep 27, 2010 4:35 pm :
atm im trying to work around with some ai triggers. the result is fine for the sandbox, but i have to evaluate if the amount of triggers and threads will affect the performance.



AnthonyJa@Posted: Mon Sep 27, 2010 5:11 pm :
As the friar said, you're going to have to go SDK side if you need this to work in real multiplayer - ie, with multiple people connected to the server. Are you trying to do something that simply works like multiplayer mode, but will only actually be one player?



bdmn@Posted: Mon Sep 27, 2010 5:25 pm :
oh, yeah sure... tx. somebody got any experience, even on the doom sdk? they should be "very" similar.



The Happy Friar@Posted: Mon Sep 27, 2010 6:58 pm :
actually, Q4 is as far from D3 as you can almost get. :) lots of stuff was moved/cut/added/changed to make Q4.

I seem to remember a Q4 coop mod in dev once. Oneofthe8devilz released his coop code for D3, so that could be a start.

Any particular reason you're using Q4 vs D3 (I found Q4's AI to be pretty darn good myself).



AnthonyJa@Posted: Mon Sep 27, 2010 10:04 pm :
bdmn wrote:
how to tell the ai, to finish the fight and run after it to the tether?


That's going to need an SDK change too from what I can see. I've never looked closely at the tactical AI (maybe I should? might make bots more intelligent...), but it looks as if being on a tether disables some of the other tactical decisions like melee / follow, in idAI::FilterTactical:

Code:
   // No tether move if not tethered
   if ( !IsTethered ( ) ) {
:
   // When tethered disable actions that dont adhear to the tether.
   } else {
      availableTactical &= ~(AITACTICAL_MELEE_BIT | AITACTICAL_MOVE_FOLLOW_BIT | AITACTICAL_HIDE_BIT  | AITACTICAL_COVER_ADVANCE_BIT | AITACTICAL_COVER_FLANK_BIT | AITACTICAL_COVER_RETREAT_BIT | AITACTICAL_COVER_AMBUSH_BIT);
   }


Removing that else clause looks like it would probably allow a tethered rvAITactical to decide to melee instead of sticking to it's tether, but I've certainly not tried it (ofc, they might get very side-tracked by the fight which is I guess why Raven did that).



bdmn@Posted: Tue Sep 28, 2010 2:56 pm :
thanks for you answer. i tried it, but this seems the wrong point. they dont finish fight, they attack while moving and stop fight out of range. reaching the tether breaks the game.

the condition isTethered checks if the monster is already at a tether, and the else statement handles the true case. it looks like they reset all states when a monster reaches the tether to let some kind of manager or the monster himself decide which states are valid from now on (depending on tether conditions,etc)

i really need to figure out where the hell the decision is made that its better reaching the tether than fighting with enemies in range...

i tried an overkill script which logically should solve the problems with several threads watching lists and triggering ai_trigger_multiples etc. but if u have 3 monsters each side ai will start to get pretty delayed and buggy.



bdmn@Posted: Tue Sep 28, 2010 5:26 pm :
thanks again, i got it. all changes have been made in AI_States.cpp. thanks for pointing me in the right direction.

Code:
switch ( newTactical ) {
   case AITACTICAL_MOVE_TETHER:
      if(enemy.ent){
         result = MoveToAttack ( enemy.ent, animator.GetAnim ( "ranged_attack" ) );
         // Found nothing but still have a find going
         if ( !result && aasFind ) {
            // turn ranged back on for next update on next frame
            combat.tacticalMaskUpdate |= AITACTICAL_RANGED_BIT;
            return false;
         }
         break;
      }
      result = MoveToTether ( tether );
      break;




your codespot had to be changed too:

Code:
// No tether move if not tethered
if ( !IsTethered ( ) ) {
   availableTactical &= ~(AITACTICAL_MOVE_TETHER_BIT);
   // Filter out any tactical states that require a leader
   if ( !leader || (enemy.ent && IsEnemyVisible() && enemy.range < move.followRange[1] * 2.0f ) ) {
      availableTactical &= ~(AITACTICAL_MOVE_FOLLOW_BIT);
   } else if ( leader && !enemy.ent ) {
      availableTactical &= ~(AITACTICAL_COVER_BITS);
   }
        // When tethered disable actions that dont adhear to the tether.
} else {
   if(!enemy.ent){
      availableTactical &= ~(AITACTICAL_MELEE_BIT|AITACTICAL_MOVE_FOLLOW_BIT|AITACTICAL_HIDE_BIT|AITACTICAL_COVER_ADVANCE_BIT|AITACTICAL_COVER_FLANK_BIT|AITACTICAL_COVER_RETREAT_BIT|AITACTICAL_COVER_AMBUSH_BIT);
   }
}





Code:
// handle Auto break tethers
if ( IsTethered ( ) && tether->IsAutoBreak ( ) && IsWithinTether ( ) ) {
   tether = NULL;
}

// bdmn begin:
      if(IsTethered ( ) && IsWithinTether () ){
         tether = NULL;
      }
// bdmn end


Code:

case AITACTICAL_MOVE_TETHER:
   // If not moving we dont want to idle in the move state so skip it
   if ( !move.fl.moving ) {
      return AICTRESULT_SKIP;
   }
   // We are still heading towards our tether so dont reissue a move
   return AICTRESULT_OK;