Game Development Community

getEnergyLevel giving different results on client/server [fixed]

by Jeff Yaskus · in Torque Game Engine · 04/09/2010 (11:58 am) · 1 replies

This is very odd and confusing ... and I can't help but think its a client/server/ghost issue. But it makes no sense.

First of all, when the player (client) connects ... The (server) spawns a number of rts units which are ghosted to the client. (i.e server side on client enter game spawns them)

The units are created properly and in the RTSUnitData::OnAdd() script, I set the the energyLevel equal to their maxEnergy ... and echo the value.

function RTSUnitData::onAdd(%this,%obj)
{
   ...
   // set the RTSUnitData stats
   %obj.setRechargeRate(%this.rechargeRate);
   %obj.setRepairRate(%this.repairRate);   
   %obj.setEnergyLevel(%this.maxEnergy);
   echo("RTSUnitData::onAdd - unit energy level =" @ %obj.getEnergyLevel() );

I put in echo output to verify its being set properly when the unit gets created;
RTSConnection::onClientEnterGame - creating unit # 7 at location 45 -4 250 for team # 0
 RTSConnection::createPlayer()-------------------------------------------
 this (client?) is (8956) unit type is (8)
RTSUnitData::onAdd - unit energy level =18
 Created new %player 9529 for Connection (8956) dataBlock = shamanBlockTeam=0
 scheduling this unit to scan - range=1
 RTSConnection::createPlayer ------------------------------------------

And in the units onAttack() function also added the same output ...
function shamanBlock::onAttack(%this, %attacker, %target)
{ 
   %RTStype = %attacker.getRTSUnitTypeName();        // warrior, orcTownCenter
   %objClassName = %attacker.getId().getClassName(); // RTSUnit, RTSBuilding
   %client = %attacker.getControllingClient();
   %energy = %attacker.getEnergyLevel();
   echo("shamanBlock::onAttack (" @ %RTStype @ ":" @ %objClassName @ ":" @ %energy @ ":" @ %client @ ")" );

which shows its set to the maxEnergy level (18) ...
shamanBlock::onAttack (shaman:RTSUnit:18:0)

ALL this (so far) seems OK ... and what I would expect.

Now, we get to the part where the server tells the client to do some animation on this unit.
This is in client side game.cs file ... getEnergyLevel() seems to return NULL or such.

As its never above (0) when its called ... so I added some hokey logic to "recharge" some energy each time its called.
function doClientAttackAnimation(%attacker, %target)
{
   trace(true);
   %RTStype = %attacker.getRTSUnitTypeName();        // warrior, orcTownCenter
   %objClassName = %attacker.getId().getClassName(); // RTSUnit, RTSBuilding
   %energy = %attacker.getEnergyLevel();
   %eMax=%attacker.getDatablock().maxEnergy;
   %rchg = %attacker.getDatablock().rechargeRate;
   // recharge some energy as it seems its not happening automatically ?!
   if (! (%energy > 0))
      {
         error("was below 0, set to rechargeRate");
         %attacker.setEnergyLevel( %rchg ); 
      }
   else
      {
         error("was below max += rechargeRate");
         %attacker.setEnergyLevel( %energy + %rchg ); 
      }
   
   %energy = %attacker.getEnergyLevel();
    
   echo("doClientAttackAnimation  (" @ %RTStype @ ":" @ %objClassName @ ":" @ %energy @ " energy) (" @ %attacker @ ":" @ %attacker.getGhostID() @ "," @ %target @ ":" @ %target.getGhostID() @ ")" );

Here is the output it generated ... on the first iteration.
was below 0, set to rechargeRate
   doClientAttackAnimation  (shaman:RTSUnit:0.5 energy) (9586:14,9580:15)
   Entering Player::playAttackAnimation(9586)
   Leaving Player::playAttackAnimation() - return

And I tried letting the unit "recharge" over time, but never happens ...

ANY ideas whats going on here ??? Why would the energy level not be "part of" these (ghosted?) units ??

NOTE: I am using TGE 1.5.2 version of the RTS Starter kit ... which at first made me consider that the energy level wasn't being "broadcast" on packet updates or something. BUT it appears to be calling the parent (Player?) functions which included this.

#1
04/09/2010 (1:40 pm)
found the issue ... its in the RTS starter code, they commented out the energy level stuff.

un-comment these in RTSunit.cc to fix it;

packUpdate()
// Ghost needs energy to predict reliably (but not in RTS -- BJG)
   stream->writeFloat(getEnergyLevel() / mDataBlock->maxEnergy,EnergyLevelBits);

unpackUpdate()
// Ghost needs energy to predict reliably (but not in RTS -- BJG)
   F32 energy = stream->readFloat(EnergyLevelBits) * mDataBlock->maxEnergy;
   setEnergyLevel(energy);