class_name EntityPresentationSnapshot extends RefCounted ## Immutable renderer input for one session-local world entity visual. ## Gameplay authority, identity allocation and asset selection remain external. const CONTRACT_VERSION := 1 const SCRIPT_PATH := "res://src/render/entities/entity_presentation_snapshot.gd" const ENTITY_ID_SCRIPT := preload("res://src/domain/identity/entity_id.gd") const GODOT_WORLD_POSITION_SCRIPT := preload("res://src/domain/coordinates/godot_world_position.gd") var is_valid: bool: get: return _failure_code.is_empty() var failure_code: StringName: get: return _failure_code var entity_id: RefCounted: get: return _entity_id var world_position: RefCounted: get: return _world_position var visual_scene_path: String: get: return _visual_scene_path var yaw_radians: float: get: return _yaw_radians var uniform_scale: float: get: return _uniform_scale var is_visible: bool: get: return _is_visible var _failure_code: StringName var _entity_id: RefCounted var _world_position: RefCounted var _visual_scene_path: String var _yaw_radians: float var _uniform_scale: float var _is_visible: bool ## Creates a version-1 full visual snapshot. Invalid values remain inspectable and ## are rejected without scene mutation by the facade/presenter. static func create( entity_id_value: RefCounted, world_position_value: RefCounted, visual_scene_path_value: String, yaw_radians_value: float = 0.0, uniform_scale_value: float = 1.0, is_visible_value: bool = true ) -> RefCounted: return load(SCRIPT_PATH).new( entity_id_value, world_position_value, visual_scene_path_value, yaw_radians_value, uniform_scale_value, is_visible_value ) func _init( entity_id_value: RefCounted, world_position_value: RefCounted, visual_scene_path_value: String, yaw_radians_value: float, uniform_scale_value: float, is_visible_value: bool ) -> void: _entity_id = entity_id_value _world_position = world_position_value _visual_scene_path = visual_scene_path_value.strip_edges() _yaw_radians = yaw_radians_value _uniform_scale = uniform_scale_value _is_visible = is_visible_value _failure_code = _validate() func _validate() -> StringName: if _entity_id == null or _entity_id.get_script() != ENTITY_ID_SCRIPT or not bool(_entity_id.call("is_valid")): return &"entity_presentation_invalid_entity_id" if _world_position == null or _world_position.get_script() != GODOT_WORLD_POSITION_SCRIPT: return &"entity_presentation_invalid_world_position" for coordinate_name in [&"x_units", &"y_units", &"z_units"]: if not is_finite(float(_world_position.get(coordinate_name))): return &"entity_presentation_position_not_finite" if _visual_scene_path.is_empty(): return &"entity_presentation_visual_path_empty" if not is_finite(_yaw_radians): return &"entity_presentation_yaw_not_finite" if not is_finite(_uniform_scale) or _uniform_scale <= 0.0: return &"entity_presentation_scale_invalid" return &""