class_name WorldObject extends RefCounted ## A world object (static or dynamic) within a chunk. ## ## This is the runtime representation of a WorldObject from the chunk data ## format (see docs/architecture/world.md ยง3.3). It holds the object's ## identity, transform, properties, and moderation flags. ## Stable object ID, unique within the chunk. var id: String = "" ## Object type (e.g. "prop", "interactable", "spawn_point", "door"). var type: String = "" ## Reference to the object's mesh/glTF asset. var asset_id: String = "" ## World-space position. var position: Vector3 = Vector3.ZERO ## World-space rotation as a quaternion (x, y, z, w). var rotation: Vector4 = Vector4(0, 0, 0, 1) ## World-space scale. var scale: Vector3 = Vector3.ONE ## Type-specific key/value properties. var properties: Dictionary = {} ## Whether this is a spawnable dynamic entity (true) or static (false). var is_dynamic: bool = false ## Per-object content moderation flags. var flags: ChunkDataDecoder.ContentFlags = ChunkDataDecoder.ContentFlags.new() ## Whether this object has been modified locally. var is_dirty: bool = false func _init( p_id: String = "", p_type: String = "", p_asset_id: String = "", p_position: Vector3 = Vector3.ZERO, p_rotation: Vector4 = Vector4(0, 0, 0, 1), p_scale: Vector3 = Vector3.ONE, p_properties: Dictionary = {}, p_dynamic: bool = false, p_flags: ChunkDataDecoder.ContentFlags = null ) -> void: id = p_id type = p_type asset_id = p_asset_id position = p_position rotation = p_rotation scale = p_scale properties = p_properties is_dynamic = p_dynamic if p_flags != null: flags = p_flags ## Get a property value by key. func get_property(key: String) -> Variant: return properties.get(key) ## Set a property value. func set_property(key: String, value: Variant) -> void: properties[key] = value is_dirty = true ## Check if this object is walkable (based on properties). func is_walkable() -> bool: return properties.get("walkable", true) ## Check if this object is climbable (based on properties). func is_climbable() -> bool: return properties.get("climbable", false) ## Check if this object is interactable. func is_interactable() -> bool: return type == "interactable" or properties.get("interactable", false) ## Get the object's display name. func get_display_name() -> String: return properties.get("display_name", id) ## Serialize this object to a dictionary (for networking). func to_dict() -> Dictionary: return { "id": id, "type": type, "asset_id": asset_id, "position": [position.x, position.y, position.z], "rotation": [rotation.x, rotation.y, rotation.z, rotation.w], "scale": [scale.x, scale.y, scale.z], "properties": properties, "dynamic": is_dynamic, } ## Create a WorldObject from a dictionary (for networking). static func from_dict(d: Dictionary) -> WorldObject: var pos := Vector3( d.get("position", [0, 0, 0])[0], d.get("position", [0, 0, 0])[1], d.get("position", [0, 0, 0])[2] ) var rot := Vector4( d.get("rotation", [0, 0, 0, 1])[0], d.get("rotation", [0, 0, 0, 1])[1], d.get("rotation", [0, 0, 0, 1])[2], d.get("rotation", [0, 0, 0, 1])[3] ) var scl := Vector3( d.get("scale", [1, 1, 1])[0], d.get("scale", [1, 1, 1])[1], d.get("scale", [1, 1, 1])[2] ) return WorldObject.new( d.get("id", ""), d.get("type", ""), d.get("asset_id", ""), pos, rot, scl, d.get("properties", {}), d.get("dynamic", false), )