Skip to content

Commit 9c66901

Browse files
committedDec 6, 2017
Add an active object step time budget #6721
This can be set via the active_object_interval option.
1 parent e049405 commit 9c66901

7 files changed

+68
-38
lines changed
 

Diff for: ‎builtin/settingtypes.txt

+3
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,9 @@ active_block_mgmt_interval (Active Block Management interval) float 2.0
10851085
# Length of time between ABM execution cycles
10861086
abm_interval (Active Block Modifier interval) float 1.0
10871087

1088+
# Length of time between active object step cycles
1089+
active_object_interval (Active Object interval) float 0.1
1090+
10881091
# Length of time between NodeTimer execution cycles
10891092
nodetimer_interval (NodeTimer interval) float 0.2
10901093

Diff for: ‎src/defaultsettings.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ void set_default_settings(Settings *settings)
345345
settings->setDefault("dedicated_server_step", "0.09");
346346
settings->setDefault("active_block_mgmt_interval", "2.0");
347347
settings->setDefault("abm_interval", "1.0");
348+
settings->setDefault("active_object_interval", "0.1");
348349
settings->setDefault("nodetimer_interval", "0.2");
349350
settings->setDefault("ignore_world_load_errors", "false");
350351
settings->setDefault("remote_media", "");

Diff for: ‎src/environment.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Environment::Environment(IGameDef *gamedef):
3636
m_cache_enable_shaders = g_settings->getBool("enable_shaders");
3737
m_cache_active_block_mgmt_interval = g_settings->getFloat("active_block_mgmt_interval");
3838
m_cache_abm_interval = g_settings->getFloat("abm_interval");
39+
m_cache_ao_interval = g_settings->getFloat("active_object_interval");
3940
m_cache_nodetimer_interval = g_settings->getFloat("nodetimer_interval");
4041

4142
m_time_of_day = g_settings->getU32("world_start_time");

Diff for: ‎src/environment.h

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ class Environment
136136
bool m_cache_enable_shaders;
137137
float m_cache_active_block_mgmt_interval;
138138
float m_cache_abm_interval;
139+
float m_cache_ao_interval;
139140
float m_cache_nodetimer_interval;
140141

141142
IGameDef *m_gamedef;

Diff for: ‎src/serverenvironment.cpp

+50-35
Original file line numberDiff line numberDiff line change
@@ -279,17 +279,17 @@ void LBMManager::applyLBMs(ServerEnvironment *env, MapBlock *block, u32 stamp)
279279

280280
void fillRadiusBlock(v3s16 p0, s16 r, std::set<v3s16> &list)
281281
{
282+
const s16 r2 = r * r;
282283
v3s16 p;
283-
for(p.X=p0.X-r; p.X<=p0.X+r; p.X++)
284-
for(p.Y=p0.Y-r; p.Y<=p0.Y+r; p.Y++)
285-
for(p.Z=p0.Z-r; p.Z<=p0.Z+r; p.Z++)
286-
{
287-
// limit to a sphere
288-
if (p.getDistanceFrom(p0) <= r) {
289-
// Set in list
290-
list.insert(p);
291-
}
292-
}
284+
for (p.X = p0.X - r; p.X <= p0.X + r; p.X++)
285+
for (p.Y = p0.Y - r; p.Y <= p0.Y + r; p.Y++)
286+
for (p.Z = p0.Z - r; p.Z <= p0.Z + r; p.Z++) {
287+
// limit to a sphere
288+
if (p.getDistanceFromSQ(p0) <= r2) {
289+
// Set in list
290+
list.insert(p);
291+
}
292+
}
293293
}
294294

295295
void fillViewConeBlock(v3s16 p0,
@@ -364,10 +364,7 @@ void ActiveBlockList::update(std::vector<PlayerSAO*> &active_players,
364364
/*
365365
Update m_list
366366
*/
367-
m_list.clear();
368-
for (v3s16 p : newlist) {
369-
m_list.insert(p);
370-
}
367+
m_list = newlist;
371368
}
372369

373370
/*
@@ -1230,14 +1227,16 @@ void ServerEnvironment::step(float dtime)
12301227
}
12311228
}
12321229

1230+
// placeholder for the "real" time passed
1231+
float elapsed_time;
1232+
12331233
/*
12341234
Mess around in active blocks
12351235
*/
1236-
if (m_active_blocks_nodemetadata_interval.step(dtime, m_cache_nodetimer_interval)) {
1236+
if (m_active_blocks_nodemetadata_interval.step(dtime, m_cache_nodetimer_interval,
1237+
&elapsed_time)) {
12371238
ScopeProfiler sp(g_profiler, "SEnv: mess in act. blocks avg per interval", SPT_AVG);
12381239

1239-
float dtime = m_cache_nodetimer_interval;
1240-
12411240
for (const v3s16 &p: m_active_blocks.m_list) {
12421241
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
12431242
if (!block)
@@ -1255,7 +1254,7 @@ void ServerEnvironment::step(float dtime)
12551254
MOD_REASON_BLOCK_EXPIRED);
12561255

12571256
// Run node timers
1258-
std::vector<NodeTimer> elapsed_timers = block->m_node_timers.step(dtime);
1257+
std::vector<NodeTimer> elapsed_timers = block->m_node_timers.step(elapsed_time);
12591258
if (!elapsed_timers.empty()) {
12601259
MapNode n;
12611260
v3s16 p2;
@@ -1271,18 +1270,14 @@ void ServerEnvironment::step(float dtime)
12711270
}
12721271
}
12731272

1274-
if (m_active_block_modifier_interval.step(dtime, m_cache_abm_interval))
1273+
if (m_active_block_modifier_interval.step(dtime,
1274+
m_cache_abm_interval * m_active_block_interval_overload_skip, &elapsed_time))
12751275
do { // breakable
1276-
if (m_active_block_interval_overload_skip > 0) {
1277-
ScopeProfiler sp(g_profiler, "SEnv: ABM overload skips");
1278-
m_active_block_interval_overload_skip--;
1279-
break;
1280-
}
12811276
ScopeProfiler sp(g_profiler, "SEnv: modify in blocks avg per interval", SPT_AVG);
12821277
TimeTaker timer("modify in active blocks per interval");
12831278

12841279
// Initialize handling of ActiveBlockModifiers
1285-
ABMHandler abmhandler(m_abms, m_cache_abm_interval, this, true);
1280+
ABMHandler abmhandler(m_abms, elapsed_time, this, true);
12861281

12871282
for (const v3s16 &p : m_active_blocks.m_abm_list) {
12881283
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
@@ -1296,13 +1291,16 @@ void ServerEnvironment::step(float dtime)
12961291
abmhandler.apply(block);
12971292
}
12981293

1299-
u32 time_ms = timer.stop(true);
1300-
u32 max_time_ms = 200;
1294+
const u32 time_ms = timer.stop(true);
1295+
// allow up to 10% of the budget interval
1296+
const u32 max_time_ms = m_cache_abm_interval * 1000.0f * 0.1f;
13011297
if (time_ms > max_time_ms) {
1302-
warningstream<<"active block modifiers took "
1303-
<<time_ms<<"ms (longer than "
1304-
<<max_time_ms<<"ms)"<<std::endl;
1305-
m_active_block_interval_overload_skip = (time_ms / max_time_ms) + 1;
1298+
warningstream << "active block modifiers took "
1299+
<< time_ms << "ms (longer than "
1300+
<< max_time_ms << "ms)" << std::endl;
1301+
m_active_block_interval_overload_skip = ((float)time_ms / max_time_ms);
1302+
} else {
1303+
m_active_block_interval_overload_skip = 1.0f;
13061304
}
13071305
}while(0);
13081306

@@ -1314,15 +1312,17 @@ void ServerEnvironment::step(float dtime)
13141312
/*
13151313
Step active objects
13161314
*/
1317-
{
1315+
if (m_active_object_interval.step(dtime,
1316+
m_cache_ao_interval * m_active_object_interval_overload_skip, &elapsed_time)) {
1317+
13181318
ScopeProfiler sp(g_profiler, "SEnv: step act. objs avg", SPT_AVG);
1319-
//TimeTaker timer("Step active objects");
1319+
TimeTaker timer("Step active objects");
13201320

13211321
g_profiler->avg("SEnv: num of objects", m_active_objects.size());
13221322

13231323
// This helps the objects to send data at the same time
13241324
bool send_recommended = false;
1325-
m_send_recommended_timer += dtime;
1325+
m_send_recommended_timer += elapsed_time;
13261326
if(m_send_recommended_timer > getSendRecommendedInterval())
13271327
{
13281328
m_send_recommended_timer -= getSendRecommendedInterval();
@@ -1335,13 +1335,28 @@ void ServerEnvironment::step(float dtime)
13351335
continue;
13361336

13371337
// Step object
1338-
obj->step(dtime, send_recommended);
1338+
obj->step(elapsed_time, send_recommended);
13391339
// Read messages from object
13401340
while (!obj->m_messages_out.empty()) {
13411341
m_active_object_messages.push(obj->m_messages_out.front());
13421342
obj->m_messages_out.pop();
13431343
}
13441344
}
1345+
1346+
// calculate a simple moving average
1347+
m_avg_ao_time = m_avg_ao_time * 0.9f + timer.stop(true) * 0.1f;
1348+
1349+
// allow up to 20% of the budget interval
1350+
const float max_time_ms = m_cache_ao_interval * 1000.0f * 0.2f;
1351+
if (m_avg_ao_time > max_time_ms) {
1352+
warningstream << "active objects took "
1353+
<< m_avg_ao_time << "ms (longer than "
1354+
<< max_time_ms << "ms)" << std::endl;
1355+
// skip a few steps
1356+
m_active_object_interval_overload_skip = m_avg_ao_time / max_time_ms;
1357+
} else {
1358+
m_active_object_interval_overload_skip = 1.0f;
1359+
}
13451360
}
13461361

13471362
/*

Diff for: ‎src/serverenvironment.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,11 @@ class ServerEnvironment : public Environment
422422
ActiveBlockList m_active_blocks;
423423
IntervalLimiter m_active_blocks_management_interval;
424424
IntervalLimiter m_active_block_modifier_interval;
425+
IntervalLimiter m_active_object_interval;
425426
IntervalLimiter m_active_blocks_nodemetadata_interval;
426-
int m_active_block_interval_overload_skip = 0;
427+
float m_active_block_interval_overload_skip = 1.0f;
428+
float m_active_object_interval_overload_skip = 1.0f;
429+
float m_avg_ao_time = 0.0f;
427430
// Time from the beginning of the game in seconds.
428431
// Incremented in step().
429432
u32 m_game_time = 0;

Diff for: ‎src/util/numeric.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ inline u32 calc_parity(u32 v)
230230
u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed);
231231

232232
bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
233-
f32 camera_fov, f32 range, f32 *distance_ptr=NULL);
233+
f32 camera_fov, f32 range, f32 *distance_ptr = NULL);
234234

235235
s16 adjustDist(s16 dist, float zoom_fov);
236236

@@ -291,18 +291,24 @@ class IntervalLimiter
291291
return value:
292292
true: action should be skipped
293293
false: action should be done
294+
if passed, the elapsed time since this method last returned true
295+
is written to elapsed_ptr
294296
*/
295-
bool step(float dtime, float wanted_interval)
297+
bool step(float dtime, float wanted_interval, float *elapsed_ptr = NULL)
296298
{
297299
m_accumulator += dtime;
300+
if (elapsed_ptr)
301+
*elapsed_ptr = m_accumulator - m_last_accumulator;
298302
if (m_accumulator < wanted_interval)
299303
return false;
300304
m_accumulator -= wanted_interval;
305+
m_last_accumulator = m_accumulator;
301306
return true;
302307
}
303308

304309
private:
305310
float m_accumulator = 0.0f;
311+
float m_last_accumulator = 0.0f;
306312
};
307313

308314

0 commit comments

Comments
 (0)
Please sign in to comment.