extends Node3D # Backrooms на готовой модели. Сцена живёт в отдельном пакете (backrooms.pck) и качается # только при первом входе в портал. Коллизии строим по мешам модели при загрузке, # навмеш для камня запечён заранее (backrooms_nav.res) — в вебе запекать на лету долго. func _ready() -> void: Net.enter_map("backrooms") _build_colliders() _build_environment() _build_hum() func _build_colliders() -> void: for mi in $Map.find_children("*", "MeshInstance3D", true, false): mi.create_trimesh_collision() func _build_environment() -> void: var env := Environment.new() env.background_mode = Environment.BG_COLOR env.background_color = Color(0.06, 0.05, 0.03) env.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR env.ambient_light_color = Color(1.0, 0.95, 0.8) env.ambient_light_energy = 0.7 env.fog_enabled = true env.fog_light_color = Color(0.25, 0.2, 0.09) env.fog_density = 0.012 var we := WorldEnvironment.new() we.environment = env add_child(we) # Гул ламп: 2 секунды, частоты кратны 0.5 Гц — петля без щелчка func _build_hum() -> void: const RATE := 11025 var n := RATE * 2 var data := PackedByteArray() data.resize(n * 2) var rng := RandomNumberGenerator.new() rng.seed = 5 for i in n: var t := float(i) / RATE var s := 0.50 * sin(TAU * 60.0 * t) + 0.25 * sin(TAU * 120.0 * t) \ + 0.12 * sin(TAU * 180.0 * t) + 0.06 * sin(TAU * 240.0 * t) s += rng.randf_range(-1.0, 1.0) * 0.03 data.encode_s16(i * 2, int(clampf(s, -1.0, 1.0) * 12000.0)) var wav := AudioStreamWAV.new() wav.format = AudioStreamWAV.FORMAT_16_BITS wav.mix_rate = RATE wav.stereo = false wav.loop_mode = AudioStreamWAV.LOOP_FORWARD wav.loop_begin = 0 wav.loop_end = n wav.data = data var player := AudioStreamPlayer.new() player.stream = wav player.volume_db = -12.0 player.autoplay = true add_child(player)