The worldserver
source code is full of Update
methods that take as input a diff
integer value:
How does it work?
And how is this linked to the "Update time diff" from the .server info
command?
To fully understand how this works, it's necessary to have a look at the main World run process.
File: src/server/worldserver/WorldThread/WorldRunnable.cpp
The method void WorldRunnable::run()
is the "Main heartbeat for the World". This method runs the whole world process.
Inside it, there is a while
loop that runs as long as the world is supposed to keep running:
void WorldRunnable::run()
{
uint32 realCurrTime = 0;
uint32 realPrevTime = getMSTime();
///- While we have not World::m_stopEvent, update the world
while (!World::IsStopped())
{
++World::m_worldLoopCounter;
realCurrTime = getMSTime();
uint32 diff = getMSTimeDiff(realPrevTime, realCurrTime);
sWorld->Update( diff );
realPrevTime = realCurrTime;
uint32 executionTimeDiff = getMSTimeDiff(realCurrTime, getMSTime());
devDiffTracker.Update(executionTimeDiff);
avgDiffTracker.Update(executionTimeDiff > WORLD_SLEEP_CONST ? executionTimeDiff : WORLD_SLEEP_CONST);
// ... some more code here
}
// at this point the world process is terminating
// ... some more code here
What this loop really does is basically:
1) calculate the elapsed time (in milliseconds) since the previous iteration, this will be the diff
2) call the sWorld->Update( diff );
function, that contains all the world process logic (see below) and passing the diff
to it
3) calculate how much time it took to run sWorld->Update( diff );
and update the devDiffTracker
and its average avgDiffTracker
. These values will be displayed by the .server info
command.
File: src/server/game/World/World.cpp
The World::Update(uint32 diff)
function gets constantly called by the main worldserver loop process and every time it takes in input the amount diff
of elapsed time since the last call.
This function is responsible for constantly updating the world, this is where all the magic happens.
There are a set of timers (defined in World.h that are being updated within the World::Update
function:
/// Timers for different object refresh rates
enum WorldTimers
{
WUPDATE_AUCTIONS,
WUPDATE_WEATHERS,
WUPDATE_UPTIME,
WUPDATE_CORPSES,
WUPDATE_EVENTS,
WUPDATE_CLEANDB,
WUPDATE_AUTOBROADCAST,
WUPDATE_MAILBOXQUEUE,
WUPDATE_PINGDB,
WUPDATE_5_SECS,
WUPDATE_COUNT
};
For example, WUPDATE_AUTOBROADCAST
is responsible for the period global messages defined in the acore_auth.autobroadcast table.
The World::Update
function also takes care of many timed-tasks, for example:
/// Handle daily quests reset time
if (m_gameTime > m_NextDailyQuestReset)
ResetDailyQuests();
In AzerothCore there are singleton classes called Managers (Mgr) that handle specific parts of the game. For example BattlegroundMgr
handles the Battlegrounds (BGs).
Those classes have their own Update(uint32 diff)
functions and they are called by World::Update
that passes down the diff
to them, for example:
sBattlegroundMgr->Update(diff);
sOutdoorPvPMgr->Update(diff);
sBattlefieldMgr->Update(diff);
/// ... there are more!
Last but not least, it calls sScriptMgr->OnWorldUpdate(diff);
.
This is part of the AzerothCore Module System, and defines a hook that can be used by third-part modules to attach custom logic to the World::Update
function.