diff --git a/src/app.c b/src/app.c index 7d60ea3f..c1bcd4ec 100644 --- a/src/app.c +++ b/src/app.c @@ -211,13 +211,16 @@ void app_entry_point(struct string args_str) struct temp_arena scratch = scratch_begin_no_conflict(); struct app_arg_list args = parse_args(scratch.arena, args_str); - struct string logfile_name = LIT("log.txt"); + struct string log_file_name = LIT("log.txt"); + struct string settings_file_name = LIT("settings.txt"); struct string connect_address = ZI; for (struct app_arg *arg = args.first; arg; arg = arg->next) { struct string key = arg->key; struct string value = arg->value; if (string_eq(key, LIT("log"))) { - logfile_name = value; + log_file_name = value; + } else if (string_eq(key, LIT("settings"))) { + settings_file_name = value; } else if (string_eq(key, LIT("connect"))) { connect_address = value; } @@ -261,7 +264,7 @@ void app_entry_point(struct string args_str) { struct temp_arena temp = arena_temp_begin(scratch.arena); - struct string logfile_path = logfile_path = app_write_path_cat(temp.arena, logfile_name); + struct string logfile_path = logfile_path = app_write_path_cat(temp.arena, log_file_name); struct log_startup_receipt log_sr = log_startup(logfile_path); (UNUSED)log_sr; @@ -281,7 +284,7 @@ void app_entry_point(struct string args_str) struct temp_arena temp = arena_temp_begin(scratch.arena); struct sys_window_settings window_settings = ZI; - struct string settings_path = app_write_path_cat(temp.arena, LIT(SETTINGS_FILENAME)); + struct string settings_path = app_write_path_cat(temp.arena, settings_file_name); logf_info("Looking for settings file \"%F\"", FMT_STR(settings_path)); if (sys_is_file(settings_path)) { logf_info("Settings file found"); @@ -375,7 +378,7 @@ void app_entry_point(struct string args_str) __profscope(app_write_to_settings_file); struct temp_arena temp = arena_temp_begin(scratch.arena); - struct string window_settings_path = app_write_path_cat(temp.arena, LIT(SETTINGS_FILENAME)); + struct string window_settings_path = app_write_path_cat(temp.arena, settings_file_name); struct sys_window_settings settings = sys_window_get_settings(&window); struct string str = settings_serialize(temp.arena, &settings); diff --git a/src/config.h b/src/config.h index 2fbb4e60..855f7654 100644 --- a/src/config.h +++ b/src/config.h @@ -1,7 +1,6 @@ /* Project-wide configurable constants */ #define WRITE_DIR "power_play" -#define SETTINGS_FILENAME "settings.txt" /* Window title */ #if RTC diff --git a/src/sim.c b/src/sim.c index 53fb5c8a..5ac59906 100644 --- a/src/sim.c +++ b/src/sim.c @@ -603,8 +603,10 @@ void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot * { __prof; - /* FIXME: Only sync cmds from non-master remote */ - /* FIXME: Only sync ents from correct owner */ + /* FIXME: Don't trust non-master clients: + * - Only sync cmd ents + * - Determine new UUIDs for newly created ents + */ struct sim_ent *local_root = sim_ent_from_id(local_ss, SIM_ENT_ROOT_ID); struct sim_ent *remote_root = sim_ent_from_id(remote_ss, SIM_ENT_ROOT_ID); @@ -614,8 +616,8 @@ void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot * sim_ent_sync_alloc_tree(local_root, remote_top, remote_client_ent); } - /* Sync ents with remote */ - for (u64 i = 0; i < local_ss->num_ents_reserved; ++i) { + /* Sync ents with remote, skipping index 0 (nil) & index 1 (root) */ + for (u64 i = 2; i < local_ss->num_ents_reserved; ++i) { struct sim_ent *local_ent = &local_ss->ents[i]; if (local_ent->valid && sim_ent_has_prop(local_ent, SIM_ENT_PROP_SYNC_DST)) { b32 should_sync = sim_ent_id_eq(local_ent->owner, remote_client_ent) || sim_ent_id_eq(remote_client_ent, SIM_ENT_NIL_ID); diff --git a/src/sim_ent.c b/src/sim_ent.c index 1bea9734..19480c30 100644 --- a/src/sim_ent.c +++ b/src/sim_ent.c @@ -626,8 +626,7 @@ void sim_ent_sync(struct sim_ent *local, struct sim_ent *remote) void sim_ent_encode(struct bitbuff_writer *bw, struct sim_ent *e0, struct sim_ent *e1) { struct sim_snapshot *ss = e1->ss; - /* FIXME: Things like xforms need to be retreived manually rather than memcopied. - * This will also be true for things like ent handles once uids are implemented. */ + /* FIXME: Things like xforms need to be retreived manually rather than memcopied. */ /* TODO: Granular delta encoding */ diff --git a/src/sim_ent.h b/src/sim_ent.h index 81591383..3f8e9612 100644 --- a/src/sim_ent.h +++ b/src/sim_ent.h @@ -386,16 +386,19 @@ INLINE b32 sim_ent_should_predict(struct sim_ent *ent) return sim_ent_id_eq(ent->predictor, ent->ss->local_client_ent); } +INLINE b32 sim_ent_is_owner(struct sim_ent *ent) +{ + return sim_ent_id_eq(ent->owner, ent->ss->local_client_ent); +} + INLINE b32 sim_ent_should_simulate(struct sim_ent *ent) { b32 res = false; if (sim_ent_is_valid_and_active(ent)) { res = true; if (sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST)) { - res = false; - if (sim_ent_should_predict(ent)) { - res = true; - } + struct sim_ent_id client_ent_id = ent->ss->local_client_ent; + res = sim_ent_id_eq(client_ent_id, ent->owner) || sim_ent_id_eq(client_ent_id, ent->predictor); } } return res; diff --git a/src/sim_step.c b/src/sim_step.c index 7d6354da..9b67e1b3 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -55,6 +55,7 @@ INTERNAL void spawn_test_entities(struct sim_step_ctx *ctx, struct v2 offset) { struct sim_snapshot *world = ctx->world; struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); + root->mass_unscaled = F32_INFINITY; root->inertia_unscaled = F32_INFINITY; @@ -357,6 +358,7 @@ void sim_step(struct sim_step_ctx *ctx) struct sprite_scope *sprite_frame_scope = sprite_scope_begin(); struct sim_ent *root = sim_ent_from_id(world, SIM_ENT_ROOT_ID); + root->owner = world->client->ent_id; /* ========================== * * Sync ents from cmd producing clients @@ -447,7 +449,7 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; if (!ent->valid) continue; - if (sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST) && !sim_ent_should_predict(ent)) continue; + if (sim_ent_has_prop(ent, SIM_ENT_PROP_SYNC_DST) && !sim_ent_is_owner(ent) && !sim_ent_should_predict(ent)) continue; if (!sim_ent_has_prop(ent, SIM_ENT_PROP_ACTIVE)) { u64 atick = ent->activation_tick; @@ -1267,8 +1269,19 @@ void sim_step(struct sim_step_ctx *ctx) if (publish_client->valid && world->tick > publish_client->last_tick) { struct sim_snapshot *prev_pub_world = sim_snapshot_from_tick(publish_client, publish_client->last_tick); struct sim_snapshot *pub_world = sim_snapshot_alloc(publish_client, prev_pub_world, world->tick); + /* Sync */ sim_snapshot_sync_ents(pub_world, world, world_client->ent_id); + + /* Mark all synced ents as both sync dsts & sync srcs */ + for (u64 ent_index = 2; ent_index < pub_world->num_ents_reserved; ++ent_index) { + struct sim_ent *ent = &pub_world->ents[ent_index]; + if (ent->valid) { + sim_ent_enable_prop(ent, SIM_ENT_PROP_SYNC_DST); + sim_ent_enable_prop(ent, SIM_ENT_PROP_SYNC_SRC); + } + } + pub_world->sim_dt_ns = world->sim_dt_ns; pub_world->sim_time_ns = world->sim_time_ns; pub_world->continuity_gen = world->continuity_gen; diff --git a/src/user.c b/src/user.c index 9b0b7acf..37110e61 100644 --- a/src/user.c +++ b/src/user.c @@ -2289,12 +2289,8 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) - - - - { - u64 cmds_ahead_on_master = master_client->ack - master_client->last_tick; + i64 cmds_ahead_on_master = (i64)master_client->ack - (i64)master_client->last_tick; if (math_abs_i64(cmds_ahead_on_master) > 50) { /* Cmds are too far from master time, snap step end tick */ i64 rtt_ns = master_client->rtt_ns; @@ -2302,7 +2298,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg) i64 num_predict_ticks = math_round_to_int64(rtt_tick_ratio) + 2; step_end_tick = step_base_tick + num_predict_ticks; compute_timescale = 1.1; - } else if (cmds_ahead_on_master > 3) { + } else if (cmds_ahead_on_master > 2) { /* Slow down simulation rate to bring sim time closer to master time */ compute_timescale = 0.9; } else if (cmds_ahead_on_master < 1) {