Implement production vertical slice foundation

This commit is contained in:
chindit committed 2026-10-02 15:27:48 +02:00
1 parent 9d4a89f355
commit a18e82eb44
104 files changed
+10595 -268

No files matched your search

+75
View File
@@ -0,0 +1,75 @@
class_name DiveTickRunner
extends RefCounted
const VehicleTelemetry = preload("res://game/application/dive/vehicle_telemetry.gd")
const DiveSession = preload("res://game/domain/dive/dive_session.gd")
const DiveTick = preload("res://game/domain/dive/dive_tick.gd")
const DiveTelemetrySample = preload("res://game/domain/dive/dive_telemetry_sample.gd")
const CollisionObservation = preload("res://game/domain/dive/collision_observation.gd")
const ToolPowerDemand = preload("res://game/domain/dive/tool_power_demand.gd")
const EjectionIntent = preload("res://game/domain/dive/ejection_intent.gd")
const ReturnRouteSample = preload("res://game/domain/dive/return_route_sample.gd")
const DiveStep = preload("res://game/domain/dive/dive_step.gd")
const DiveUpdate = preload("res://game/domain/dive/dive_update.gd")
var _session: DiveSession
var _next_sequence := 0
func _init(session: DiveSession) -> void:
_session = session
func next_sequence() -> int:
return _next_sequence
func initial_update() -> DiveUpdate:
return DiveUpdate.initial(_session.current_snapshot())
func advance(
telemetry: VehicleTelemetry,
elapsed_seconds: float,
collisions: Array[CollisionObservation] = [],
tool_power_demands: Array[ToolPowerDemand] = [],
ejection_intent: EjectionIntent = null,
return_route: ReturnRouteSample = null
) -> DiveUpdate:
if telemetry == null:
return DiveUpdate.rejected(
_next_sequence,
"vehicle telemetry is missing",
_session.current_snapshot()
)
var telemetry_error: String = telemetry.validation_error(
_session.session_id,
_next_sequence
)
if not telemetry_error.is_empty():
return DiveUpdate.rejected(
_next_sequence,
telemetry_error,
_session.current_snapshot()
)
var tick := DiveTick.new(_session.session_id, _next_sequence, elapsed_seconds)
var sample := DiveTelemetrySample.new(
telemetry.depth_m,
telemetry.longitudinal_effort,
telemetry.steering_effort,
telemetry.vertical_effort,
telemetry.high_thrust_active
)
var step := DiveStep.new(
tick,
sample,
collisions,
tool_power_demands,
ejection_intent,
return_route
)
var update: DiveUpdate = _session.advance(step)
if update.accepted:
_next_sequence += 1
return update
@@ -0,0 +1,74 @@
class_name VehicleTelemetry
extends RefCounted
var session_id: StringName
var sequence: int
var world_position_m: Vector3
var world_orientation: Quaternion
var world_linear_velocity_mps: Vector3
var local_angular_velocity_rps: Vector3
var depth_m: float
var longitudinal_effort: float
var steering_effort: float
var vertical_effort: float
var high_thrust_active: bool
func _init(
p_session_id: StringName,
p_sequence: int,
p_world_position_m: Vector3,
p_world_orientation: Quaternion,
p_world_linear_velocity_mps: Vector3,
p_local_angular_velocity_rps: Vector3,
p_depth_m: float,
p_longitudinal_effort: float,
p_steering_effort: float,
p_vertical_effort: float,
p_high_thrust_active: bool
) -> void:
session_id = p_session_id
sequence = p_sequence
world_position_m = p_world_position_m
world_orientation = p_world_orientation
world_linear_velocity_mps = p_world_linear_velocity_mps
local_angular_velocity_rps = p_local_angular_velocity_rps
depth_m = p_depth_m
longitudinal_effort = p_longitudinal_effort
steering_effort = p_steering_effort
vertical_effort = p_vertical_effort
high_thrust_active = p_high_thrust_active
func validation_error(expected_session_id: StringName, expected_sequence: int) -> String:
if session_id != expected_session_id:
return "telemetry session_id does not match"
if sequence != expected_sequence:
return "telemetry sequence does not match expected tick"
if not _vector_is_finite(world_position_m):
return "telemetry world position is not finite"
if not _quaternion_is_finite(world_orientation):
return "telemetry orientation is not finite"
if not _vector_is_finite(world_linear_velocity_mps):
return "telemetry linear velocity is not finite"
if not _vector_is_finite(local_angular_velocity_rps):
return "telemetry angular velocity is not finite"
if not is_finite(depth_m) or depth_m < 0.0:
return "telemetry depth must be finite and non-negative"
for effort: float in [longitudinal_effort, steering_effort, vertical_effort]:
if not is_finite(effort) or effort < -1.0 or effort > 1.0:
return "telemetry efforts must be between -1 and 1"
return ""
func _vector_is_finite(value: Vector3) -> bool:
return is_finite(value.x) and is_finite(value.y) and is_finite(value.z)
func _quaternion_is_finite(value: Quaternion) -> bool:
return (
is_finite(value.x)
and is_finite(value.y)
and is_finite(value.z)
and is_finite(value.w)
)
@@ -0,0 +1,12 @@
class_name InputBindingSnapshot
extends RefCounted
var action_id: StringName
var label: String
var binding_text: String
func _init(p_action_id: StringName, p_label: String, p_binding_text: String) -> void:
action_id = p_action_id
label = p_label
binding_text = p_binding_text
+22
View File
@@ -0,0 +1,22 @@
class_name RebindResult
extends RefCounted
var accepted: bool
var action_id: StringName
var binding_text: String
var conflicting_action_id: StringName
var message: String
func _init(
p_accepted: bool,
p_action_id: StringName,
p_binding_text: String = "",
p_conflicting_action_id: StringName = &"",
p_message: String = ""
) -> void:
accepted = p_accepted
action_id = p_action_id
binding_text = p_binding_text
conflicting_action_id = p_conflicting_action_id
message = p_message
@@ -0,0 +1,8 @@
class_name VehicleMotionPort
extends RefCounted
const VehicleCommand = preload("res://game/application/vehicle/vehicle_command.gd")
func apply_command(_command: VehicleCommand) -> void:
pass
@@ -0,0 +1,22 @@
class_name CameraLookCommand
extends RefCounted
var yaw_delta_radians: float
var pitch_delta_radians: float
var recenter_requested: bool
func _init(
p_yaw_delta_radians: float = 0.0,
p_pitch_delta_radians: float = 0.0,
p_recenter_requested: bool = false
) -> void:
yaw_delta_radians = p_yaw_delta_radians
pitch_delta_radians = p_pitch_delta_radians
recenter_requested = p_recenter_requested
func validation_error() -> String:
if not is_finite(yaw_delta_radians) or not is_finite(pitch_delta_radians):
return "camera look deltas must be finite"
return ""
@@ -0,0 +1,32 @@
class_name PilotUseCase
extends RefCounted
const VehicleCommand = preload("res://game/application/vehicle/vehicle_command.gd")
const VehicleCommandResult = preload(
"res://game/application/vehicle/vehicle_command_result.gd"
)
const VehicleMotionPort = preload("res://game/application/interfaces/vehicle_motion_port.gd")
var _motion_port: VehicleMotionPort
var _last_sequence := -1
func _init(motion_port: VehicleMotionPort) -> void:
_motion_port = motion_port
func execute(command: VehicleCommand) -> VehicleCommandResult:
if command == null:
return VehicleCommandResult.new(false, -1, "vehicle command is missing")
var error: String = command.validation_error()
if not error.is_empty():
return VehicleCommandResult.new(false, command.sequence, error)
if command.sequence != _last_sequence + 1:
return VehicleCommandResult.new(
false,
command.sequence,
"vehicle command sequence is not consecutive"
)
_motion_port.apply_command(command)
_last_sequence = command.sequence
return VehicleCommandResult.new(true, command.sequence)
@@ -0,0 +1,16 @@
class_name VehicleCollisionSample
extends RefCounted
var sample_id: StringName
var sequence: int
var normal_impact_speed_mps: float
func _init(
p_sample_id: StringName,
p_sequence: int,
p_normal_impact_speed_mps: float
) -> void:
sample_id = p_sample_id
sequence = p_sequence
normal_impact_speed_mps = p_normal_impact_speed_mps
@@ -0,0 +1,35 @@
class_name VehicleCommand
extends RefCounted
var sequence: int
var longitudinal: float
var steering: float
var vertical: float
var high_thrust_active: bool
func _init(
p_sequence: int,
p_longitudinal: float,
p_steering: float,
p_vertical: float,
p_high_thrust_active: bool
) -> void:
sequence = p_sequence
longitudinal = p_longitudinal
steering = p_steering
vertical = p_vertical
high_thrust_active = p_high_thrust_active
func validation_error() -> String:
if sequence < 0:
return "vehicle command sequence is negative"
for value: float in [longitudinal, steering, vertical]:
if not is_finite(value) or value < -1.0 or value > 1.0:
return "vehicle command axes must be finite and normalized"
return ""
static func neutral(p_sequence: int) -> VehicleCommand:
return new(p_sequence, 0.0, 0.0, 0.0, false)
@@ -0,0 +1,12 @@
class_name VehicleCommandResult
extends RefCounted
var accepted: bool
var sequence: int
var rejection_reason: String
func _init(p_accepted: bool, p_sequence: int, p_rejection_reason: String = "") -> void:
accepted = p_accepted
sequence = p_sequence
rejection_reason = p_rejection_reason