extends "res://tests/test_case.gd" const LocalInputTimeline = preload("res://scripts/local_input_timeline.gd") const ShipAction = preload("res://scripts/ship_action.gd") func _action(z: float) -> ShipAction: var result := ShipAction.new() result.thrust.z = z return result func test_attack_gap_is_materialized_as_repeat_last_actions() -> void: var timeline := LocalInputTimeline.new() timeline.configure_initial_delay(1) timeline.issue(1, _action(0.25)) timeline.issue(4, _action(0.75)) assert_eq(timeline.latest_issued_seq, 5, "attack advances the outgoing sequence by the requested lead delta") var packet := timeline.packet_actions(4) assert_eq(packet.size(), 4, "redundancy packet carries contiguous actions across the attack gap") assert_almost_eq(packet[0].thrust.z, 0.75, 0.001, "newest attack action is preserved") assert_almost_eq(packet[1].thrust.z, 0.25, 0.001, "gap is repeat-last, matching server consumption") assert_almost_eq(packet[3].thrust.z, 0.25, 0.001, "all attack-gap entries are materialized") func test_release_retransmits_immutable_sequence_and_carries_new_intent_forward() -> void: var timeline := LocalInputTimeline.new() timeline.configure_initial_delay(1) timeline.issue(1, _action(0.2)) timeline.issue(0, _action(0.9)) assert_eq(timeline.latest_issued_seq, 1, "release does not relabel an issued action") assert_almost_eq(timeline.packet_actions(4)[0].thrust.z, 0.2, 0.001, "release retransmits immutable issued data") timeline.issue(1, _action(0.9)) assert_almost_eq(timeline.packet_actions(4)[0].thrust.z, 0.9, 0.001, "new intent appears on the next unique sequence") func test_consumption_repeats_last_through_unissued_delay_slots() -> void: var timeline := LocalInputTimeline.new() timeline.configure_initial_delay(3) timeline.issue(1, _action(0.6)) assert_almost_eq(timeline.consume()["action"].thrust.z, 0.0, 0.001, "initial delay begins at neutral action") assert_almost_eq(timeline.consume()["action"].thrust.z, 0.0, 0.001, "delay repeats last action") assert_almost_eq(timeline.consume()["action"].thrust.z, 0.0, 0.001, "sequence zero remains neutral") assert_almost_eq(timeline.consume()["action"].thrust.z, 0.6, 0.001, "issued command applies at its scheduled sequence")