Hello,
noticed a huge lag when like 15-20 people uses spells or overall melee attacks in a same place, ping jumps even to a 1k and after checking dispatcher this is the log
I would say this is quite a large resource usage in CPU isnt it? How i know its spells or melee related? Because when it stoped attacking and casting spells on a creature lag disappeared completetly
this is all code parts that could be related
noticed a huge lag when like 15-20 people uses spells or overall melee attacks in a same place, ping jumps even to a 1k and after checking dispatcher this is the log
Code:
[21/11/2023 21:47:25]
Thread: 1 Cpu usage: 94.9291% Idle: 1.94614% Other: 3.12471% Players online: 165
Time (ms) Calls Rel usage % Real usage % Description
13408 2001327 47.08344% 44.69591% std::bind(&Game::checkCreatureAttack, &g_game, getID())
5736 1133 20.14303% 19.12160% std::bind(&Game::checkCreatures, this, (index + 1) % EVENT_CREATURECOUNT)
3938 126800 13.82834% 13.12713% std::bind(&Game::checkCreatureWalk, &g_game, getID())
1912 1458 6.71657% 6.37598% functor
1002 14507 3.52165% 3.34307% &Game::playerSay
600 115 2.10871% 2.00178% std::bind(&Game::checkDecay, this)
409 2913 1.43680% 1.36394% std::bind(&Spawn::scheduleSpawn, this, spawnId, sb, interval - 1400)
397 1381 1.39481% 1.32409% &Game::parsePlayerExtendedOpcode
274 7699 0.96220% 0.91341% std::bind(&ProtocolGame::parseNewWalk, getThis(), playerWalkId, predictiveWalkId, playerId, playerPosition, flags, path)
245 3212 0.86185% 0.81814% std::bind(&LuaEnvironment::executeTimerEvent, &g_luaEnvironment, lastTimerEventId)
230 779 0.80871% 0.76770% std::bind(&Game::executeDeath, &g_game, getID())
115 2276 0.40509% 0.38455% &Game::playerUseItem
33 4100 0.11704% 0.11111% &Game::playerTurn
32 1 0.11461% 0.10880% std::bind(&ProtocolGame::logout, getThis(), true, false)
this is all code parts that could be related
C++:
if (creature == attackedCreature || (creature == this && attackedCreature)) {
if (newPos.z != oldPos.z || !canSee(attackedCreature->getPosition())) {
onCreatureDisappear(attackedCreature, false);
} else {
if (hasExtraSwing()) {
//our target is moving lets see if we can get in hit
g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game, getID())));
}
if (newTile->getZone() != oldTile->getZone()) {
onAttackedCreatureChangeZone(attackedCreature->getZone());
}
}
}
}
C++:
void Game::checkCreatureAttack(uint32_t creatureId)
{
Creature* creature = getCreatureByID(creatureId);
if (creature && creature->getHealth() > 0) {
creature->onAttacking(0);
}
}
C++:
bool Monster::selectTarget(Creature* creature)
{
if (!isTarget(creature)) {
return false;
}
auto it = std::find(targetList.begin(), targetList.end(), creature);
if (it == targetList.end()) {
//Target not found in our target list.
return false;
}
Player* player = creature->getPlayer();
if (player)
if (!trySaga(player))
return false;
if (isHostile() || isSummon()) {
if (setAttackedCreature(creature) && !isSummon()) {
g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game, getID())));
}
}
return setFollowCreature(creature);
}
C++:
bool Player::setAttackedCreature(Creature* creature)
{
if (creature)
{
if (Player* p = creature->getPlayer())
{
if (isPartner(p))
{
sendCancelTarget();
return false;
}
}
}
if (!Creature::setAttackedCreature(creature)) {
sendCancelTarget();
return false;
}
if (chaseMode == CHASEMODE_FOLLOW && creature) {
if (followCreature != creature) {
//chase opponent
setFollowCreature(creature);
}
}
else if (followCreature) {
setFollowCreature(nullptr);
}
if (creature) {
g_dispatcher.addTask(createTask(std::bind(&Game::checkCreatureAttack, &g_game, getID())));
}
return true;
}
C++:
void Player::doAttacking(uint32_t)
{
if (lastAttack == 0) {
lastAttack = OTSYS_TIME() - getAttackSpeed() - 1;
}
if (hasCondition(CONDITION_PACIFIED)) {
return;
}
if ((OTSYS_TIME() - lastAttack) >= getAttackSpeed()) {
bool result = false;
Item* tool = getWeapon();
const Weapon* weapon = g_weapons->getWeapon(tool);
uint32_t delay = getAttackSpeed();
if (weapon) {
if (!weapon->interruptSwing()) {
result = weapon->useWeapon(this, tool, attackedCreature);
}
else if (!canDoAction()) {
delay = getNextActionTime();
}
else {
result = weapon->useWeapon(this, tool, attackedCreature);
}
}
else {
result = Weapon::useFist(this, attackedCreature);
}
/* There's not even the need to check if player is dual wielding: the variable is ignored otherwise. */
switchAttackHand();
SchedulerTask* task = createSchedulerTask(std::max<uint32_t>(SCHEDULER_MINTICKS, delay), std::bind(&Game::checkCreatureAttack, &g_game, getID()));
g_scheduler.addEvent(task);
if (result) {
lastAttack = OTSYS_TIME();
}
}
}