diff --git a/src/config.h b/src/config.h index 93d477a4..db40fd91 100644 --- a/src/config.h +++ b/src/config.h @@ -28,12 +28,22 @@ #define IMAGE_PIXELS_PER_UNIT 256.0 -/* 64^2 = 4096 bins */ +/* How many ticks back in time should the user blend between? + * = * + * E.g: At 1.5, the user thread will render 75ms back in time if the sim runs at 50tps + */ +#define USER_INTERP_RATIO 1.5 +#define USER_INTERP_ENABLED 1 + + /* 64^2 = 4096 bins */ #define SPACE_CELL_BINS_SQRT (64) #define SPACE_CELL_SIZE 1.0f #define SIM_TICKS_PER_SECOND 50 #define SIM_TIMESCALE 1 +/* Like USER_INTERP_RATIO, but applies to snapshots received by the local sim from the + * master sim (how far back in time should the client render the server's state) */ +#define SIM_CLIENT_INTERP_RATIO 2.0 #define SIM_PHYSICS_SUBSTEPS 4 #define SIM_PHYSICS_ENABLE_WARM_STARTING 1 @@ -47,13 +57,6 @@ #define SIM_MAX_LINEAR_VELOCITY 500 #define SIM_MAX_ANGULAR_VELOCITY (TAU * 20) -/* How many ticks back in time should the user blend between? - * = * - * E.g: At 1.5, the user thread will render 75ms back in time if the sim runs at 50tps - */ -#define USER_INTERP_RATIO 1.5 -#define USER_INTERP_ENABLED 1 - #define COLLIDER_DEBUG 0 #define COLLIDER_DEBUG_DETAILED 0 #define COLLIDER_DEBUG_DETAILED_DRAW_MENKOWSKI 0 diff --git a/src/host.c b/src/host.c index e31179b3..b09067ed 100644 --- a/src/host.c +++ b/src/host.c @@ -631,7 +631,7 @@ i64 host_get_channel_last_rtt_ns(struct host *host, struct host_channel_id chann * Update * ========================== */ -INTERNAL struct host_event *alloc_event(struct arena *arena, struct host_event_list *list) +INTERNAL struct host_event *push_event(struct arena *arena, struct host_event_list *list) { struct host_event *event = arena_push_zero(arena, struct host_event); if (list->last) { @@ -721,7 +721,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host) /* We successfully connected to a foreign host and they are ready to receive messages */ if (channel->valid && !channel->connected) { logf_info("Host received connection from %F", FMT_STR(sock_string_from_address(scratch.arena, address))); - struct host_event *event = alloc_event(arena, &events); + struct host_event *event = push_event(arena, &events); event->kind = HOST_EVENT_KIND_CHANNEL_OPENED; event->channel_id = channel->id; channel->connected = true; @@ -733,7 +733,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host) /* A foreign host disconnected from us */ if (channel->valid) { logf_info("Host received disconnection from %F", FMT_STR(sock_string_from_address(scratch.arena, address))); - struct host_event *event = alloc_event(arena, &events); + struct host_event *event = push_event(arena, &events); event->kind = HOST_EVENT_KIND_CHANNEL_CLOSED; event->channel_id = channel->id; host_channel_release(channel); @@ -789,7 +789,7 @@ struct host_event_list host_update_begin(struct arena *arena, struct host *host) if (ma->num_chunks_received == chunk_count) { /* All chunks filled, message has finished assembling */ /* TODO: Message ordering */ - struct host_event *event = alloc_event(arena, &events); + struct host_event *event = push_event(arena, &events); struct string data = ZI; data.len = ((chunk_count - 1) * PACKET_MSG_CHUNK_MAX_LEN) + ma->last_chunk_len; data.text = arena_push_array(arena, u8, data.len); @@ -1014,7 +1014,7 @@ void host_update_end(struct host *host) } } - /* Process packets */ + /* Send packets */ /* TODO: Aggregate small packets */ { __profscope(host_update_send_packets); diff --git a/src/rand.h b/src/rand.h index eae7d642..1229884b 100644 --- a/src/rand.h +++ b/src/rand.h @@ -2,7 +2,7 @@ #define RAND_H struct rand_state { - /* If a state's seed = 0 upon a to a related function, it will be initialized using platform's true rng source */ + /* If a state's seed == 0 upon a call to a related function, it will be initialized using platform's true rng source */ u64 seed; u64 counter; }; diff --git a/src/sim.c b/src/sim.c index b5c50668..ba3b662f 100644 --- a/src/sim.c +++ b/src/sim.c @@ -599,7 +599,7 @@ struct sim_snapshot *sim_snapshot_alloc_from_lerp(struct sim_client *client, str * ========================== */ /* Syncs entity data between snapshots */ -void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss, struct sim_ent_id remote_client_ent) +void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss, struct sim_ent_id remote_client_ent, u32 sync_flags) { __prof; @@ -621,6 +621,9 @@ void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot * 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_is_nil(remote_client_ent); + if ((sync_flags & SIM_SYNC_FLAG_NOSYNC_PREDICTABLES) && sim_ent_id_eq(local_ent->predictor, local_ss->local_client_ent)) { + should_sync = false; + } if (should_sync) { struct sim_ent *remote_ent = sim_ent_from_id(remote_ss, local_ent->id); if (remote_ent->valid) { diff --git a/src/sim.h b/src/sim.h index 8de970e5..1b7d4055 100644 --- a/src/sim.h +++ b/src/sim.h @@ -73,7 +73,7 @@ struct sim_client { struct arena snapshots_arena; /* Round trip time of the client (if networked) */ - i64 rtt_ns; + i64 last_rtt_ns; struct host_channel_id channel_id; u64 channel_hash; @@ -129,15 +129,19 @@ struct sim_client *sim_client_from_handle(struct sim_client_store *store, struct * Snapshot * ========================== */ +enum sim_sync_flag { + SIM_SYNC_FLAG_NOSYNC_PREDICTABLES = 1 << 0 +}; + enum sim_control_flag { - SIM_CONTROL_FLAG_FIRE = 1 << 0, + SIM_CONTROL_FLAG_FIRE = 1 << 0, /* Testing */ - SIM_CONTROL_FLAG_DRAG = 1 << 1, - SIM_CONTROL_FLAG_CLEAR_ALL = 1 << 2, - SIM_CONTROL_FLAG_SPAWN_TEST = 1 << 3, - SIM_CONTROL_FLAG_PAUSE = 1 << 4, - SIM_CONTROL_FLAG_STEP = 1 << 5 + SIM_CONTROL_FLAG_DRAG = 1 << 1, + SIM_CONTROL_FLAG_CLEAR_ALL = 1 << 2, + SIM_CONTROL_FLAG_SPAWN_TEST = 1 << 3, + SIM_CONTROL_FLAG_PAUSE = 1 << 4, + SIM_CONTROL_FLAG_STEP = 1 << 5 }; struct sim_control { @@ -160,10 +164,6 @@ struct sim_snapshot { struct arena arena; - /* Program time of local snapshot publish to user thread (if relevant) */ - i64 publish_dt_ns; - i64 publish_time_ns; - /* Sim time (guaranteed to increase by sim_dt_ns each step) */ i64 sim_dt_ns; i64 sim_time_ns; @@ -212,7 +212,7 @@ struct sim_snapshot *sim_snapshot_from_closest_tick_gte(struct sim_client *clien struct sim_snapshot *sim_snapshot_alloc_from_lerp(struct sim_client *client, struct sim_snapshot *ss0, struct sim_snapshot *ss1, f64 blend); /* Sync */ -void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss, struct sim_ent_id remote_client_ent); +void sim_snapshot_sync_ents(struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss, struct sim_ent_id remote_client_ent, u32 sync_flags); /* Encode / decode */ void sim_snapshot_encode(struct bitbuff_writer *bw, struct sim_client *receiver, struct sim_snapshot *ss0, struct sim_snapshot *ss1); diff --git a/src/sim_step.c b/src/sim_step.c index 04d17053..1d989748 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -392,18 +392,16 @@ void sim_step(struct sim_step_ctx *ctx) /* Update rtt */ if (is_master && client_ent->valid) { - client_ent->client_last_rtt_ns = client->rtt_ns; - f64 avg = client_ent->client_average_rtt_seconds; - avg -= avg / 200; - avg += SECONDS_FROM_NS(client->rtt_ns) / 200; - client_ent->client_average_rtt_seconds = avg; + client_ent->client_last_rtt_ns = client->last_rtt_ns; + client_ent->client_average_rtt_seconds -= client_ent->client_average_rtt_seconds / 200; + client_ent->client_average_rtt_seconds += SECONDS_FROM_NS(client->last_rtt_ns) / 200; } /* Sync ents from client */ if (client_ent->valid) { struct sim_snapshot *src_ss = sim_snapshot_from_tick(client, world->tick); if (src_ss->valid) { - sim_snapshot_sync_ents(world, src_ss, client_ent->id); + sim_snapshot_sync_ents(world, src_ss, client_ent->id, 0); } } } @@ -993,6 +991,7 @@ void sim_step(struct sim_step_ctx *ctx) * Create motor joints from ground friction (gravity) * ========================== */ +#if 0 for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; @@ -1017,6 +1016,7 @@ void sim_step(struct sim_step_ctx *ctx) } } } +#endif /* ========================== * * Create mouse joints from client debug drag @@ -1275,7 +1275,7 @@ void sim_step(struct sim_step_ctx *ctx) 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); + sim_snapshot_sync_ents(pub_world, world, world_client->ent_id, 0); /* Mark all synced ents as both sync dsts & sync srcs */ for (u64 ent_index = 2; ent_index < pub_world->num_ents_reserved; ++ent_index) { diff --git a/src/user.c b/src/user.c index 72063d7c..50e61f65 100644 --- a/src/user.c +++ b/src/user.c @@ -95,11 +95,11 @@ GLOBAL struct { struct sys_mutex local_to_user_client_mutex; struct sim_client_store *local_to_user_client_store; struct sim_client *local_to_user_client; + i64 local_to_user_client_publish_dt_ns; + i64 local_to_user_client_publish_time_ns; /* Rolling window of local sim -> user publish time deltas */ i64 last_local_to_user_snapshot_published_at_ns; - i64 local_to_user_snapshot_publish_dts_ns[10]; - i64 local_to_user_snapshot_publish_dts_index; i64 average_local_to_user_snapshot_publish_dt_ns; i64 local_sim_predicted_time_ns; /* Calculated from +