Staredit Network > Forums > General StarCraft > Topic: Is reaver's behavior random in melee games?
Is reaver's behavior random in melee games?
Aug 13 2012, 6:57 pm
By: theleo_ua  
Polls
Reaver/scarab behavior is
Reaver/scarab behavior is
Answer Votes Percentage % Voters
random: some of the reaver/scarab glitches/stupidness cannot be predicted by progamer (and cannot be controlled by progamer) 1
 
50%
non-random: all reaver/scarab glitches/stupidness can be predicted by progamer, but cannot be controlled by progamer 1
 
50%
non-random: all reaver/scarab glitches/stupidness can be predicted by progamer, and even can be controlled by progamer 0
 
0%
None.
Please login to vote.
Poll has 2 votes. You can vote for at most 1 option(s).

Aug 13 2012, 6:57 pm theleo_ua Post #1



Hi SEN community

This topic will be updated to detailed description about this, but now I have some questions.

Please look to the next fragments of the vods:

Jangbi vs Fantasy: http://www.youtube.com/watch?v=OoPG9gwgFmQ&feature=player_detailpage#t=663s
(look at 11:03)

Perfectman vs Fantasy: http://www.youtube.com/watch?v=nekBzOGPg6U&feature=player_detailpage#t=948s
(look at 15:47)

Bisu vs Light: http://www.youtube.com/watch?list=UUAI86CUHDIkKXGA6YpVBhYg&v=Anr6gKLla7c&feature=player_detailpage#t=606s
(look at 10:06)


The list of main reaver "random" things are:

1) sometimes reaver dont want to shoot (even if you selected it and pressing right mouse button on the enemy unit)

2) sometimes scarab cannot reach the goal:

it "moving like junk yard dog" in enemy units
- it cannot bypass building (like in Jangbi vs Fantasy fragment)
- it just moving to non-correct place - even without reason

3) sometimes scarab exploding near goal object, but not dealing any damage to it (and scarab life-time are not ran out in this case)


Questions:

1) Are reavers and scarab behavior contain "random" function? Especially I want answer to this from BW Engine gosus like Heinermann

2) If not - why reavers sometimes stupid and sometimes not?

3) Is it possible by progamers - to predict all reaver "stupidnesses"?

4) If yes - is it possible by progamers to control reaver in way, that reaver will not be stupid all the time? This mean, that there is some micro techniques, which, for example, will allow Jangbi/Perfectman to make scarab deal damage to goal in VODS listed above.

Thanks

P.S. Of course, some of the reaver glitches can be predicted and even controlled by the progamer. But not all. So when I say "reaver/scarab is random" - I mean, that there are some situations, when progamer cannot predict, will reaver be "stupid" or not.

Post has been edited 1 time(s), last time on Aug 14 2012, 5:31 pm by theleo_ua.



None.

Aug 13 2012, 8:50 pm Lanthanide Post #2



Because SC is a computer program, it is therefore predictable if you have full understanding of all variables involved. It is unlikely any pro-gamer will ever have this full understanding however.



None.

Aug 13 2012, 9:14 pm IskatuMesk Post #3

Lord of the Locker Room

The scarab is a unit, and is subject to ground pathing, collision, and a variety of bugs and oddities that come as a result of these oddities. Quantifying these problems in a logical form as a player is going to be very difficult, because even as a modder for over a decade who spent much time working with the game on a level just above ASM, I still didn't really possess any manner of predicting what happens with stuff like the scarab. Starcraft is riddled in hardcoded goofiness, and Blizzard's programmers are some of the worst in the industry, leading to very strange behavior.

I believe, like Lanthanide said, you can certainly be in a position to predict everything the scarab will ever do. But you need to understand all of the code working with it at a very deep level.



Show them your butt, and when you do, slap it so it creates a sound akin to a chorus of screaming spider monkeys flogging a chime with cacti. Only then can you find your destiny at the tip of the shaft.

Aug 13 2012, 10:10 pm theleo_ua Post #4



Quote from Lanthanide
Because SC is a computer program, it is therefore predictable if you have full understanding of all variables involved

Example 1:

Code:

Step 1: get(current time.milliseconds) from bios
Step 2: if this value less than 500 - then move scarab to the left, if 500 or greater - then move scarab to the right.

Situation: player didnt know exact time, when BW launched, and player has only keyboard and mouse (player has not any devices like clock etc)

Question: how, in this example, player can predict, will scarab move to the left or to the right?



Example 2:

Player 1 has reaver and scarab.
Player 2 has 5 SCVs in range "5 cells from reaver" (lets call them SCVs A), 5 SCVs in range "4 cells from reaver" (lets call them SCVs B), 5 SCVs in range "3 cells from reaver" (lets call them SCVs C) etc

If player 1 will attack any SCV of SCVs B or C - scarab will not damage them, because of SCVs A will block his path.
But: If player 1 will attack any SCV of SCVs A - player 2 can order attacked SCV "move to minerals", so scarab will still cannot reach the attacked SCV because of another SCVs. So, in this case, the chance to damage SCV is depends on "which SCV player 2 will move to minerals".

So player 1 has next 2 outcomes:

1) Scarab damaged targetted SCV
2) Scarab not damaged targetted SCV

And this outcome does not depend on player skills - this depend only on his opponent's move. So "SC is a computer program" - did not help the player even in this case.


So I think, that "SC is a computer program" is not a panacea, and pro gamers cannot predict (and even control to prevent) all reaver's glitches even if they will read sources of BW and fully understood them.

Post has been edited 1 time(s), last time on Aug 13 2012, 10:30 pm by theleo_ua.



None.

Aug 13 2012, 10:12 pm Biophysicist Post #5



Quote from Lanthanide
if you have full understanding of all variables involved
Which our hypothetical gamer doesn't, so you two are agreeing.



None.

Aug 13 2012, 10:22 pm theleo_ua Post #6



Quote from IskatuMesk
The scarab is a unit, and is subject to ground pathing, collision, and a variety of bugs and oddities that come as a result of these oddities. Quantifying these problems in a logical form as a player is going to be very difficult, because even as a modder for over a decade who spent much time working with the game on a level just above ASM, I still didn't really possess any manner of predicting what happens with stuff like the scarab. Starcraft is riddled in hardcoded goofiness, and Blizzard's programmers are some of the worst in the industry, leading to very strange behavior.

I believe, like Lanthanide said, you can certainly be in a position to predict everything the scarab will ever do. But you need to understand all of the code working with it at a very deep level.

One of reaver's glitches is scarab movement, but another is "reaver dont want to shoot even if ordered to shoot".

For example, if you drop the reaver from shuttle near opponent's CC and SCVs, reaver sometimes will shoot to them automatically, sometimes will not shoot to them autimatically, and sometimes will not want to shoot even if you order him to do this.

My questions are next:

1) Is it possible to predict this simple thing?
2) Is it possible to drop a reaver, which will shoot a scarab with 100% chance?
3) Is it possible to force reaver shoot a scarab, if you pressing right mouse button on enemy unit, and reaver still dont want to shoot scarab, wihout loading reaver to shuttle ?

And if some of this possible - how to do this?

But this is only one (and most simple) of reaver/scarab glitches.



None.

Aug 13 2012, 10:46 pm Azrael Post #7



Looks like a job for Heinermann. I doubt anyone else can give you the kind of information you're looking for.




Aug 13 2012, 11:00 pm IskatuMesk Post #8

Lord of the Locker Room

Quote from theleo_ua
Quote from IskatuMesk
The scarab is a unit, and is subject to ground pathing, collision, and a variety of bugs and oddities that come as a result of these oddities. Quantifying these problems in a logical form as a player is going to be very difficult, because even as a modder for over a decade who spent much time working with the game on a level just above ASM, I still didn't really possess any manner of predicting what happens with stuff like the scarab. Starcraft is riddled in hardcoded goofiness, and Blizzard's programmers are some of the worst in the industry, leading to very strange behavior.

I believe, like Lanthanide said, you can certainly be in a position to predict everything the scarab will ever do. But you need to understand all of the code working with it at a very deep level.

One of reaver's glitches is scarab movement, but another is "reaver dont want to shoot even if ordered to shoot".

For example, if you drop the reaver from shuttle near opponent's CC and SCVs, reaver sometimes will shoot to them automatically, sometimes will not shoot to them autimatically, and sometimes will not want to shoot even if you order him to do this.

The problem that lies herein is a lot of this behavior is doubtlessly from buggy or ineffective code. It's very possible that because of the way the Reaver's orders and AI work, they may not always even fire correctly in this example you've provided. The circumstances can get very complex inside the code, and so predicting them as a player can become extremely hard. There are instances where, as a player, the code is very much working against you.

For example, when you micro wraiths, there are times when the wraith engine graphics do not appear. This is because there is a bug in the flingy.dat air code where it is possible to make a unit move without actually triggering the move header within iscript.bin (that controls the engine overlays and other animation-related events). This was most noticeable in a mod of mine that had a unit that depended on this walk script to "teleport". If the header was not activated, it would not move. There were instances, especially with very fast movement, where the header would not activate and thus the unit would not move. The reaver problem you describe can be even more complicated than this.

Quote
3) Is it possible to force reaver shoot a scarab, if you pressing right mouse button on enemy unit, and reaver still dont want to shoot scarab, wihout loading reaver to shuttle ?

I'm going to guess that resetting its orders, e.g. pressing stop, hold command, or telling it to move and then stopping, might reset its orders. But it's possible it already set itself on an internal cooldown or something equally silly. I'm not a programmer, so this is a bit beyond my expertise.



Show them your butt, and when you do, slap it so it creates a sound akin to a chorus of screaming spider monkeys flogging a chime with cacti. Only then can you find your destiny at the tip of the shaft.

Aug 16 2012, 11:30 pm Heinermann Post #9

SDE, BWAPI owner, hacker.

In the Unload function, if the unit being unloaded is a Reaver it sets its main order timer to 30.
For any other unit it sets their weapon cooldowns to their default weapon cooldowns and also sets their ability cooldown to 30.

There is no cooldown randomization here. The only randomization here is in the target acquisition code and pathing code.


Also I don't recommend you using Stop, since doing so will destroy any scarabs that belong to the reaver.




Aug 17 2012, 4:15 pm theleo_ua Post #10



Quote from Heinermann
The only randomization here is in the target acquisition code and pathing code

Could you please explain in details - what randomization is in the target acquisition code and pathing code?



None.

Aug 17 2012, 5:44 pm Heinermann Post #11

SDE, BWAPI owner, hacker.

The target acquisition code chooses one of X amount of closest same-priority targets randomly.
The pathing code provides some randomization when a scarab goes bonkers, which is why every shot is not exactly the same. (at least I thought so)

EDIT:
Here is most of the target acquisition code in a BW/BWAPI mashup format.
Code
//BW Attack priority tree:

#define MemZero(x) memset(x, 0, sizeof(x))

// Priority enum
namespace Priority
{
 enum Enum
 {
   Highest,
   Higher,
   High,
   Low,
   Lower,
   Lowest,
   MAX
 };
};

// Some globals, probably "static" in the Unit class
int g_AtkPriorityCount[Priority::MAX]
Unit *g_AtkPriorityList[Priority::MAX][16];

int g_MinWpnRange;
int g_MinAcqRange;

// functions
int Unit::getAttackPriorityFor(Unit *pTarget);
void Unit::setAttackPriority(int priority);
Unit *Unit::getNewAttackTarget(); // <---- START HERE
Unit *Unit::getRandomAttackTarget();  // <---- START HERE for alternative function (both are called under different circumstances)
Unit *Unit::getTargetFromPriorityList(int priority);
Unit *getRandomTargetFromPriorityList(int priority);
bool Unit::isTargetActive(Unit *pTarget);

bool __fastcall getStandardAttackTargetCallback(Unit *pTarget, Unit *pThis);

// Functions not listed are intended to be obvious, and I converted many to use BWAPI-style members
// let me know if anything needs clarification


// Returns 0 (highest priority) to 5 (lowest priority)
int Unit::getAttackPriorityFor(Unit *pTarget)
{
 Unit *targ = pTarget;
 
 // get target replacement or do instant returns if any
 switch ( pTarget->getType() )
 {
 case UnitTypes::Enum::Terran_Bunker:
   if ( !pTarget->getLoadedUnits().empty() )
     targ = pTarget->getLoadedUnits().front();
   break;
 case UnitTypes::Enum::Zerg_Larva:
 case UnitTypes::Enum::Zerg_Egg:
 case UnitTypes::Enum::Zerg_Cocoon:
 case UnitTypes::Enum::Zerg_Lurker_Egg:
   return Priority::Lowest;
 default:
   break;
 }
 
 int iPriority;
 UnitType targType = targ->getType();
 
 if ( targType.isWorker() )
   iPriority = Priority::High;
 else if ( targ->canAttack(this, true) )
   iPriority = Priority::Highest;
 else if ( targ->canAttack() )
   iPriority = Priority::High;
 else if ( targType.isBuilding() )
   iPriority = Priority::Low;
 else
   iPriority = Priority::Lower;

 // decrease the priority if the unit is incomplete or if the target is a loaded bunker
 if ( !targ->isCompleted() || targ != pTarget )
   ++iPriority;
 
 // Unknown, possibly a flag telling that another unit just recently attacked it?
 if ( iPriority == Priority::Highest && (targ->statusFlags & UNKNOWN1) )
   iPriority = Priority::Higher;
   
 return iPriority;
}

// Sets the attack priority
void Unit::setAttackPriority(int priority)
{
 int priorityIndex = g_AtkPriorityCount[priority];
 if ( priorityIndex < 16 )
 {
   g_AtkPriorityList[priority][priorityIndex] = this;
   g_AtkPriorityCount[priority]++;
 }
}

// Obtain the new attack target (base function)
Unit *Unit::getNewAttackTarget()
{
 // Reset global data
 MemZero(g_AtkPriorityCount);
 
 // obtain target acquisition range
 int targAcquisition = this->getTargetAcquisitionRange();
 if ( this->isInBunker() )
   targAcquisition += 2;
 else if ( this->isAI() && this->getType().sightRange() > targAcquisition )
   targAcquisition = this->getType().sightRange();
   
 // Set some globals
 g_MinAcqRange = targAcquisition*32;
 g_MinAtkRange = this->getMinAttackRange();
 
 // Iterate all units in a box and call whatever callback for each one
 int range = (targAcquisition + 2)*32;
 Position p( this->getPosition() );
 Broodwar->iterateUnitsInRectangle_1(  p.x - range,
                                       p.y - range,
                                       p.x + range,
                                       p.y + range,
                                       getStandardAttackTargetCallback, this);

 // Get the highest priority value with at least one target entry
 int priority = Priority::Highest;
 while ( g_AtkPriorityCount[priority] == 0 )
 {
   ++priority;
   if ( priority >= Priority::MAX )
     return nullptr;
 }
 
 return this->getTargetFromPriorityList(priority);
}

// ALTERNATIVE Obtain the new attack target
Unit *Unit::getRandomAttackTarget()
{
 // Reset global data
 MemZero(g_AtkPriorityCount);
 
 // Get target acquisition range
 int targAcquisition = this->getTargetAcquisitionRange();
 if ( this->isInBunker() )
   targAcquisition += 2;

 // Set some globals
 g_MinAcqRange = targAcquisition*32;
 g_MinAtkRange = 0;
 
 // Iterate all units in a box and call whatever callback for each one
 int range = (targAcquisition + 2)*32;
 Position p( this->getPosition() );
 Broodwar->iterateUnitsInRectangle_1(  p.x - range,
                                       p.y - range,
                                       p.x + range,
                                       p.y + range,
                                       getStandardAttackTargetCallback, this);
 
 // Get the highest priority value with at least one target entry
 int priority = Priority::Highest;
 while ( g_AtkPriorityCount[priority] == 0 )
 {
   ++priority;
   if ( priority >= Priority::MAX )
     return nullptr;
 }
 
 return getRandomTargetFromPriorityList(priority);
}

Unit *Unit::getTargetFromPriorityList(int priority)
{
 // Localize globals
 Unit **pList = g_AtkPriorityList[priority];
 int listCount = g_AtkPriorityCount[priority];
 
 // If there is only one element, there is nothing to compare to
 if ( listCount == 1 )
   return pList[0];
 
 // The "best" index
 int bestIndex = 0;
 
 // Special zerg scourge AI
 if ( this->isAI() && this->getType() == UnitTypes::Zerg_Scourge )
 {
   // Get the highest HP+Shields unit
   int bestHP = pList[0]->getHitPoints() + pList[0]->getShields();
   for ( int i = 1; i < listCount; ++i )
   {
     int newHP = pList[i]->getHitPoints() + pList[i]->getShields();
     if ( newHP > bestHP )
     {
       bestHP = newHP;
       bestIndex = i;
     }
   }
 }
 else  // anything else
 {
   // Get the closest unit
   int bestDist = this->getPosition().getDistance( pList[0]->getPosition() );
   for ( int i = 1; i < listCount; ++i )
   {
     int newDist = this->getPosition().getDistance( pList[0]->getPosition() );
     if ( newDist < bestDist )
     {
       bestDist = newDist;
       bestIndex = i;
     }
   }
 }
 return pList[bestIndex];
}

Unit *getRandomTargetFromPriorityList(int priority)
{
 // Localize globals
 Unit **pList = g_AtkPriorityList[priority];
 int listCount = g_AtkPriorityCount[priority];
 
 // If there is only one element, then we don't need any more calculation
 if ( listCount == 1 )
   return pList[0];
   
 return pList[ rand() % listCount ]; //pList[ Broodwar->getRand(RANDDBG::TARGET) % listCount ];
}

bool Unit::isTargetActive(Unit *pTarget)
{
 if (  this->getPlayer().getType() != PlayerTypes::Computer ||
       this->isInAir() ||
       this->isTargetInWeaponRange(pTarget) )
   return false;

 return (pTarget->statusFlags & UNKNOWN1) != 0;
}

bool __fastcall getStandardAttackTargetCallback(Unit *pTarget, Unit *pThis)
{
 if ( pTarget == pThis ) // exclude if both are the same
   return false;

 if ( !pTarget->isVisibleTo( pThis->getPlayer() ) )  // exclude if invisible
   return false;
 
 if ( !pThis->canAttack(pTarget, true) ) // exclude if not attackable
   return false;
 
 if ( !pTarget->isEnemyOf( pThis->getPlayer() ) )  // exclude if not an enemy
   return false;
   
 if ( g_MinWpnRange > 0 && pThis->isTargetInRange(g_MinWpnRange, pTarget) )  // exclude if within global min weapon range
   return false;
   
 if ( !pThis->isTargetInRange(g_MinAcqRange, pTarget) )  // exclude if not in global acquisition range
   return false;
 
 // Get the subunit, if none exists then just use pThis
 Unit *unit = pThis->getSubunit();
 if ( unit == nullptr )
   unit = pThis;
   
 // Not sure
 if ( !(unit->statusFlags & IsAUnit_Unknown) )
 {
   // Discard units outside of the attack angle
   if ( !unit->isTargetInAttackAngle(pTarget->getPosition(), unit->getType().groundWeapon()) )
     return false;
   unit = pThis;
 }

 // Set the global attack priority if target was not attacked??
 if ( !unit->isTargetActive(pTarget) )
   pTarget->setAttackPriority( unit->getAttackPriorityFor(pTarget) );

 return false;
}


Post has been edited 2 time(s), last time on Aug 17 2012, 6:17 pm by Heinermann.




Aug 17 2012, 10:58 pm theleo_ua Post #12



Thank you so much for answering and giving the code.

The only 2 questions left:

1) What do you think - is it possible by progamer to avoid these randomizations? For example by "forcing reaver to choose correct target by right mouse pressess etc" ?

2) What do you think about Jangbi vs Fantasy, Perfectman vs Fantasy and Bisu vs Light fragments listed above - do you think it is possible by progamers to predict these glitches? Do you think it is possible by progamers to control these glitches (I mean - to do special combinations of keyboard and mouse presses on units to avoid any of these glitches) ?

Thank you in advance



None.

Options
  Back to forum
Please log in to reply to this topic or to report it.
Members in this topic: None.
[04:40 pm]
Zoan -- never change, sen
[04:39 pm]
Zoan -- :wob:
[12:46 pm]
razorback9423 -- :wob: KANDA FOREVER!
[2019-9-20. : 2:41 pm]
razorback9423 -- NudeRaider
NudeRaider shouted: MTiger156 power over:wob:ing?
No, POWER UNDER :wob: ing!
[2019-9-20. : 12:53 pm]
NudeRaider -- MTiger156
MTiger156 shouted: Power over:wob:ing
power over:wob:ing?
[2019-9-20. : 12:27 pm]
MTiger156 -- crap...
[2019-9-20. : 12:27 pm]
MTiger156 -- Power over:wob:ing
[2019-9-20. : 11:50 am]
UEDCommander -- WARNING: Unit Unplaceable! (u) (69, 69)
[2019-9-20. : 9:26 am]
lil-Inferno -- :wob:
[2019-9-20. : 8:25 am]
Black_Overseer -- razorback9423
razorback9423 shouted: WARNING: Unit Unplaceable! (Aldaris) (1656,2996)
You have no power here, Gandalf the Grey.
Please log in to shout.


Members Online: Roy, MTiger156