Drift now takes &T -> &T and is generic over the time axis. Untimed impls return elapsed=0. ConstantDrift impl covers all T via the Time trait. An additional variance_for_elapsed(i64) method on the trait serves callers that work with the pre-cached i64 elapsed count. Competitor.last_time moves from i64 with MIN sentinel to Option<T> with None sentinel. receive(&T) computes variance from last_time dynamically; receive_for_elapsed(i64) uses a pre-cached elapsed count (needed in convergence sweeps where last_time has already advanced). TimeSlice.time changes from i64 to T. compute_elapsed is now generic over T and takes Option<&T> for the last-seen time. new_forward_info uses receive_for_elapsed to preserve the cached elapsed during sweeps. History<D> becomes History<T, D>; HistoryBuilder<D> becomes HistoryBuilder<T, D>; Game<D> becomes Game<T, D>. Defaults keep existing call sites compiling with zero changes: T = i64, D = ConstantDrift. add_events / add_events_with_prior stay on impl History<i64, D> since times: Vec<i64> is i64-specific (Task 8 will generalise this). In !self.time mode the old i64::MAX sentinel guaranteed elapsed=1 for every slice transition regardless of time gaps. Replaced by advancing all previously-seen agents' last_time to Some(current_slice_time) at the end of each slice; this preserves elapsed=1 between adjacent slices in sequential-integer untimed mode. The time: bool field on History and .time(bool) on HistoryBuilder are NOT removed by this task — deferred to Task 8 so this commit is purely a type-level generification. Part of T2 of docs/superpowers/specs/2026-04-23-trueskill-engine-redesign-design.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1.4 KiB
1.4 KiB