Стартовый хаб с порталами, песочница отдельным пакетом, присед
- World/Hub: маленькая стартовая комната (код, без ассетов) с порталами на карты; новые карты добавляются записью в PORTALS (влезает 6 порталов). - Песочница (main.tscn) вынесена в world.pck и качается при входе в портал; основной пакет игры вместо 19.7 МБ стал 2.1 МБ. Выходы из карт ведут в хаб. - Экспорт: три пресета (Web — движок и хаб, World, Backrooms). - Присед: удерживать C (на бегу Shift+C по-прежнему подкат), скорость 3.5. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -74,6 +74,8 @@ const SLIDE_COOLDOWN = 0.3
|
|||||||
const SLIDE_CAMERA_DROP = 0.6
|
const SLIDE_CAMERA_DROP = 0.6
|
||||||
const SLIDE_HEIGHT_FACTOR = 0.5
|
const SLIDE_HEIGHT_FACTOR = 0.5
|
||||||
const CROUCH_SPEED = 2.5 # Ползём, если над головой низкий потолок
|
const CROUCH_SPEED = 2.5 # Ползём, если над головой низкий потолок
|
||||||
|
const CROUCH_WALK_SPEED = 3.5 # Скорость в приседе (держим C; на бегу Shift+C — подкат)
|
||||||
|
const CROUCH_CAMERA_DROP = 0.6
|
||||||
const MIN_SLIDE_SPEED = 7.0 # Минимальная скорость для начала слайда
|
const MIN_SLIDE_SPEED = 7.0 # Минимальная скорость для начала слайда
|
||||||
|
|
||||||
# --- Ступеньки ---
|
# --- Ступеньки ---
|
||||||
@@ -123,6 +125,7 @@ var bob_time: float = 0.0
|
|||||||
|
|
||||||
# Состояние подката
|
# Состояние подката
|
||||||
var is_sliding: bool = false
|
var is_sliding: bool = false
|
||||||
|
var is_crouching: bool = false
|
||||||
var slide_cooldown_timer: float = 0.0
|
var slide_cooldown_timer: float = 0.0
|
||||||
var slide_dir: Vector3 = Vector3.ZERO
|
var slide_dir: Vector3 = Vector3.ZERO
|
||||||
var slide_speed: float = 0.0
|
var slide_speed: float = 0.0
|
||||||
@@ -248,7 +251,7 @@ func _unhandled_input(event: InputEvent) -> void:
|
|||||||
# Битовые флаги состояния для сетевой синхронизации (см. Net.FLAG_*)
|
# Битовые флаги состояния для сетевой синхронизации (см. Net.FLAG_*)
|
||||||
func get_net_flags() -> int:
|
func get_net_flags() -> int:
|
||||||
var flags := 0
|
var flags := 0
|
||||||
if is_sliding: flags |= Net.FLAG_SLIDING
|
if is_sliding or is_crouching: flags |= Net.FLAG_SLIDING # У призрака присед выглядит как сплюснутая капсула
|
||||||
if is_wallrunning: flags |= Net.FLAG_WALLRUN
|
if is_wallrunning: flags |= Net.FLAG_WALLRUN
|
||||||
if is_dashing: flags |= Net.FLAG_DASH
|
if is_dashing: flags |= Net.FLAG_DASH
|
||||||
if is_mantling: flags |= Net.FLAG_MANTLE
|
if is_mantling: flags |= Net.FLAG_MANTLE
|
||||||
@@ -277,6 +280,8 @@ func _physics_process(delta: float) -> void:
|
|||||||
|
|
||||||
var space_down := Input.is_key_pressed(KEY_SPACE)
|
var space_down := Input.is_key_pressed(KEY_SPACE)
|
||||||
|
|
||||||
|
_update_crouch()
|
||||||
|
|
||||||
# --- Таймеры прыжка (coyote time + jump buffer) ---
|
# --- Таймеры прыжка (coyote time + jump buffer) ---
|
||||||
if is_on_floor():
|
if is_on_floor():
|
||||||
coyote_timer = COYOTE_TIME
|
coyote_timer = COYOTE_TIME
|
||||||
@@ -338,7 +343,9 @@ func _physics_process(delta: float) -> void:
|
|||||||
if is_wallrunning:
|
if is_wallrunning:
|
||||||
_wall_jump(wall_normal)
|
_wall_jump(wall_normal)
|
||||||
elif coyote_timer > 0.0:
|
elif coyote_timer > 0.0:
|
||||||
if not is_sliding or _can_stand():
|
if (not is_sliding and not is_crouching) or _can_stand():
|
||||||
|
if is_crouching:
|
||||||
|
_end_crouch()
|
||||||
velocity.y = JUMP_VELOCITY
|
velocity.y = JUMP_VELOCITY
|
||||||
jump_buffer_timer = 0.0
|
jump_buffer_timer = 0.0
|
||||||
coyote_timer = 0.0
|
coyote_timer = 0.0
|
||||||
@@ -360,7 +367,9 @@ func _physics_process(delta: float) -> void:
|
|||||||
|
|
||||||
# 3. Скорость (Спринт)
|
# 3. Скорость (Спринт)
|
||||||
var current_speed := WALK_SPEED
|
var current_speed := WALK_SPEED
|
||||||
if Input.is_key_pressed(KEY_SHIFT):
|
if is_crouching:
|
||||||
|
current_speed = CROUCH_WALK_SPEED
|
||||||
|
elif Input.is_key_pressed(KEY_SHIFT):
|
||||||
current_speed = SPRINT_SPEED
|
current_speed = SPRINT_SPEED
|
||||||
|
|
||||||
# 4. Бег по стене
|
# 4. Бег по стене
|
||||||
@@ -714,6 +723,7 @@ func _try_start_slide() -> void:
|
|||||||
if horizontal.length() < MIN_SLIDE_SPEED:
|
if horizontal.length() < MIN_SLIDE_SPEED:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
is_crouching = false
|
||||||
is_sliding = true
|
is_sliding = true
|
||||||
slide_dir = horizontal.normalized()
|
slide_dir = horizontal.normalized()
|
||||||
slide_speed = clamp(max(horizontal.length() * SLIDE_START_MULT, SLIDE_START_SPEED), 0.0, MAX_SPEED)
|
slide_speed = clamp(max(horizontal.length() * SLIDE_START_MULT, SLIDE_START_SPEED), 0.0, MAX_SPEED)
|
||||||
@@ -744,6 +754,23 @@ func _process_slide(delta: float, direction: Vector3, horizontal: Vector3) -> Ve
|
|||||||
return direction * CROUCH_SPEED
|
return direction * CROUCH_SPEED
|
||||||
return horizontal.move_toward(Vector3.ZERO, CROUCH_SPEED)
|
return horizontal.move_toward(Vector3.ZERO, CROUCH_SPEED)
|
||||||
|
|
||||||
|
# --- ПРИСЕД ---
|
||||||
|
|
||||||
|
# Держим C на земле — приседаем. Встаём, когда отпустили, и над головой есть место
|
||||||
|
func _update_crouch() -> void:
|
||||||
|
var busy := is_sliding or is_dashing or is_wallrunning or is_mantling or not is_on_floor()
|
||||||
|
if not is_crouching:
|
||||||
|
if Input.is_key_pressed(KEY_C) and not busy:
|
||||||
|
is_crouching = true
|
||||||
|
_set_collider_crouched(true)
|
||||||
|
elif (busy or not Input.is_key_pressed(KEY_C)) and (is_sliding or _can_stand()):
|
||||||
|
_end_crouch()
|
||||||
|
|
||||||
|
func _end_crouch() -> void:
|
||||||
|
is_crouching = false
|
||||||
|
if not is_sliding:
|
||||||
|
_set_collider_crouched(false)
|
||||||
|
|
||||||
func _end_slide() -> void:
|
func _end_slide() -> void:
|
||||||
is_sliding = false
|
is_sliding = false
|
||||||
slide_cooldown_timer = SLIDE_COOLDOWN
|
slide_cooldown_timer = SLIDE_COOLDOWN
|
||||||
@@ -784,6 +811,8 @@ func _update_camera(delta: float, input_dir: Vector2) -> void:
|
|||||||
var target_offset := 0.0
|
var target_offset := 0.0
|
||||||
if is_sliding:
|
if is_sliding:
|
||||||
target_offset = -SLIDE_CAMERA_DROP
|
target_offset = -SLIDE_CAMERA_DROP
|
||||||
|
elif is_crouching:
|
||||||
|
target_offset = -CROUCH_CAMERA_DROP
|
||||||
elif is_mantling:
|
elif is_mantling:
|
||||||
target_offset = -0.25
|
target_offset = -0.25
|
||||||
head_offset_y = lerp(head_offset_y, target_offset, 12.0 * delta)
|
head_offset_y = lerp(head_offset_y, target_offset, 12.0 * delta)
|
||||||
@@ -879,6 +908,8 @@ func die() -> void:
|
|||||||
death_timer = DEATH_TIME
|
death_timer = DEATH_TIME
|
||||||
if is_sliding:
|
if is_sliding:
|
||||||
_end_slide()
|
_end_slide()
|
||||||
|
if is_crouching:
|
||||||
|
_end_crouch()
|
||||||
is_dashing = false
|
is_dashing = false
|
||||||
is_wallrunning = false
|
is_wallrunning = false
|
||||||
is_mantling = false
|
is_mantling = false
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ catch_height = 3.0
|
|||||||
sight_limited = true
|
sight_limited = true
|
||||||
|
|
||||||
[node name="Exit" type="Area3D" parent="." unique_id=1540431614]
|
[node name="Exit" type="Area3D" parent="." unique_id=1540431614]
|
||||||
transform = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, -72, -0.15, 9)
|
transform = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, -92.93203, -0.15, 10.390619)
|
||||||
script = ExtResource("5_portal")
|
script = ExtResource("5_portal")
|
||||||
target_map = "world"
|
target_map = "hub"
|
||||||
target_scene = "res://main.tscn"
|
target_scene = "res://World/Hub/hub.tscn"
|
||||||
title = "EXIT"
|
title = "EXIT"
|
||||||
color = Color(0.3, 1, 0.45, 1)
|
color = Color(0.3, 1, 0.45, 1)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
extends Node3D
|
||||||
|
# Стартовая комната: ничего тяжёлого, только пол, стены и порталы на карты. Сами карты качаются
|
||||||
|
# отдельными пакетами при входе в портал (World/map_loader.gd) — поэтому игра стартует быстро.
|
||||||
|
# Чтобы добавить карту — допиши запись в PORTALS: порталы встанут в ряд по центру (влезает 6).
|
||||||
|
|
||||||
|
const PORTALS := [
|
||||||
|
{"title": "SANDBOX", "map": "world", "scene": "res://main.tscn", "pack": "world.pck", "color": Color(0.2, 0.9, 1.0)},
|
||||||
|
{"title": "BACKROOMS", "map": "backrooms", "scene": "res://World/Backrooms/backrooms.tscn", "pack": "backrooms.pck", "color": Color(1.0, 0.85, 0.25)},
|
||||||
|
]
|
||||||
|
|
||||||
|
const ROOM_WIDTH := 28.0
|
||||||
|
const ROOM_DEPTH := 18.0
|
||||||
|
const ROOM_HEIGHT := 6.0
|
||||||
|
const WALL := 0.5
|
||||||
|
const PORTAL_SPACING := 4.5
|
||||||
|
|
||||||
|
const GRID_SHADER := """
|
||||||
|
shader_type spatial;
|
||||||
|
varying vec3 wpos;
|
||||||
|
void vertex() { wpos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; }
|
||||||
|
void fragment() {
|
||||||
|
vec2 cell = wpos.xz / 2.0;
|
||||||
|
vec2 g = abs(fract(cell - 0.5) - 0.5) / fwidth(cell);
|
||||||
|
float line = 1.0 - min(min(g.x, g.y), 1.0);
|
||||||
|
ALBEDO = mix(vec3(0.03, 0.04, 0.06), vec3(0.1, 0.65, 0.85), line * 0.8);
|
||||||
|
EMISSION = vec3(0.04, 0.3, 0.4) * line;
|
||||||
|
ROUGHNESS = 0.9;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
Net.enter_map("hub")
|
||||||
|
_build_room()
|
||||||
|
_build_portals()
|
||||||
|
_build_environment()
|
||||||
|
|
||||||
|
func _build_room() -> void:
|
||||||
|
var body := StaticBody3D.new()
|
||||||
|
body.name = "Room"
|
||||||
|
add_child(body)
|
||||||
|
|
||||||
|
var floor_mat := ShaderMaterial.new()
|
||||||
|
floor_mat.shader = Shader.new()
|
||||||
|
floor_mat.shader.code = GRID_SHADER
|
||||||
|
var wall_mat := StandardMaterial3D.new()
|
||||||
|
wall_mat.albedo_color = Color(0.09, 0.1, 0.14)
|
||||||
|
wall_mat.roughness = 1.0
|
||||||
|
var ceiling_mat := StandardMaterial3D.new()
|
||||||
|
ceiling_mat.albedo_color = Color(0.05, 0.055, 0.08)
|
||||||
|
|
||||||
|
var hw := ROOM_WIDTH * 0.5
|
||||||
|
var hd := ROOM_DEPTH * 0.5
|
||||||
|
_add_box(body, Vector3(ROOM_WIDTH + WALL * 2, 0.5, ROOM_DEPTH + WALL * 2), Vector3(0, -0.25, 0), floor_mat)
|
||||||
|
_add_box(body, Vector3(ROOM_WIDTH + WALL * 2, 0.5, ROOM_DEPTH + WALL * 2), Vector3(0, ROOM_HEIGHT + 0.25, 0), ceiling_mat)
|
||||||
|
_add_box(body, Vector3(ROOM_WIDTH + WALL * 2, ROOM_HEIGHT, WALL), Vector3(0, ROOM_HEIGHT * 0.5, -hd - WALL * 0.5), wall_mat)
|
||||||
|
_add_box(body, Vector3(ROOM_WIDTH + WALL * 2, ROOM_HEIGHT, WALL), Vector3(0, ROOM_HEIGHT * 0.5, hd + WALL * 0.5), wall_mat)
|
||||||
|
_add_box(body, Vector3(WALL, ROOM_HEIGHT, ROOM_DEPTH), Vector3(-hw - WALL * 0.5, ROOM_HEIGHT * 0.5, 0), wall_mat)
|
||||||
|
_add_box(body, Vector3(WALL, ROOM_HEIGHT, ROOM_DEPTH), Vector3(hw + WALL * 0.5, ROOM_HEIGHT * 0.5, 0), wall_mat)
|
||||||
|
|
||||||
|
func _add_box(body: StaticBody3D, size: Vector3, pos: Vector3, mat: Material) -> void:
|
||||||
|
var shape := BoxShape3D.new()
|
||||||
|
shape.size = size
|
||||||
|
var cs := CollisionShape3D.new()
|
||||||
|
cs.shape = shape
|
||||||
|
cs.position = pos
|
||||||
|
body.add_child(cs)
|
||||||
|
|
||||||
|
var mesh := BoxMesh.new()
|
||||||
|
mesh.size = size
|
||||||
|
mesh.material = mat
|
||||||
|
var mi := MeshInstance3D.new()
|
||||||
|
mi.mesh = mesh
|
||||||
|
mi.position = pos
|
||||||
|
mi.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
||||||
|
add_child(mi)
|
||||||
|
|
||||||
|
# Порталы вдоль северной стены лицом в комнату, по центру
|
||||||
|
func _build_portals() -> void:
|
||||||
|
var portal_script := load("res://World/portal.gd")
|
||||||
|
var z := -ROOM_DEPTH * 0.5 + 1.0
|
||||||
|
for i in PORTALS.size():
|
||||||
|
var info: Dictionary = PORTALS[i]
|
||||||
|
var portal := Area3D.new()
|
||||||
|
portal.set_script(portal_script)
|
||||||
|
portal.target_map = info.map
|
||||||
|
portal.target_scene = info.scene
|
||||||
|
portal.pack_name = info.pack
|
||||||
|
portal.title = info.title
|
||||||
|
portal.color = info.color
|
||||||
|
portal.position = Vector3((i - (PORTALS.size() - 1) * 0.5) * PORTAL_SPACING, 0.0, z)
|
||||||
|
add_child(portal)
|
||||||
|
|
||||||
|
var label := Label3D.new()
|
||||||
|
label.text = "CHOOSE A MAP"
|
||||||
|
label.pixel_size = 0.012
|
||||||
|
label.font_size = 64
|
||||||
|
label.outline_size = 12
|
||||||
|
label.modulate = Color(0.7, 0.9, 1.0)
|
||||||
|
label.position = Vector3(0, ROOM_HEIGHT - 0.35, -ROOM_DEPTH * 0.5 + 0.1)
|
||||||
|
add_child(label)
|
||||||
|
|
||||||
|
func _build_environment() -> void:
|
||||||
|
var env := Environment.new()
|
||||||
|
env.background_mode = Environment.BG_COLOR
|
||||||
|
env.background_color = Color(0.02, 0.025, 0.04)
|
||||||
|
env.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
|
||||||
|
env.ambient_light_color = Color(0.5, 0.58, 0.75)
|
||||||
|
env.ambient_light_energy = 0.55
|
||||||
|
var we := WorldEnvironment.new()
|
||||||
|
we.environment = env
|
||||||
|
add_child(we)
|
||||||
|
|
||||||
|
var lamp := OmniLight3D.new()
|
||||||
|
lamp.position = Vector3(0, ROOM_HEIGHT - 0.6, 2.0)
|
||||||
|
lamp.omni_range = 22.0
|
||||||
|
lamp.light_energy = 0.8
|
||||||
|
lamp.light_color = Color(0.8, 0.9, 1.0)
|
||||||
|
lamp.shadow_enabled = false
|
||||||
|
add_child(lamp)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dac7t22u2s6to
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[gd_scene format=3]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://World/Hub/hub.gd" id="1_hub"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://c3efk6k8xnf57" path="res://Player/Player.tscn" id="2_player"]
|
||||||
|
|
||||||
|
[node name="Hub" type="Node3D"]
|
||||||
|
script = ExtResource("1_hub")
|
||||||
|
|
||||||
|
[node name="Player" parent="." instance=ExtResource("2_player")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, 5)
|
||||||
+51
-1
@@ -10,7 +10,7 @@ dedicated_server=false
|
|||||||
custom_features=""
|
custom_features=""
|
||||||
export_filter="all_resources"
|
export_filter="all_resources"
|
||||||
include_filter=""
|
include_filter=""
|
||||||
exclude_filter="models/backrooms/*, World/Backrooms/*"
|
exclude_filter="models/backrooms/*, World/Backrooms/*, main.tscn, World/Floor/*, World/Sky/*, World/tron_01.ogg, World/forest.gd, World/birds.gd, World/levitate.gd, World/nav-bake.gd, models/building_02*, models/tower_01/*, models/house_02/*, models/cyber-office/*, models/obelisk_01/*, models/Tree_01/*, models/empire-state/*"
|
||||||
export_path="../grid-world/index.html"
|
export_path="../grid-world/index.html"
|
||||||
patches=PackedStringArray()
|
patches=PackedStringArray()
|
||||||
patch_delta_encoding=false
|
patch_delta_encoding=false
|
||||||
@@ -100,3 +100,53 @@ progressive_web_app/icon_512x512=""
|
|||||||
progressive_web_app/background_color=Color(0, 0, 0, 1)
|
progressive_web_app/background_color=Color(0, 0, 0, 1)
|
||||||
threads/emscripten_pool_size=8
|
threads/emscripten_pool_size=8
|
||||||
threads/godot_pool_size=4
|
threads/godot_pool_size=4
|
||||||
|
|
||||||
|
[preset.2]
|
||||||
|
|
||||||
|
name="World"
|
||||||
|
platform="Web"
|
||||||
|
dedicated_server=false
|
||||||
|
custom_features=""
|
||||||
|
export_filter="resources"
|
||||||
|
export_files=PackedStringArray("res://main.tscn")
|
||||||
|
include_filter=""
|
||||||
|
exclude_filter="Player/*, models/Bochi-Rock/*, World/portal.gd"
|
||||||
|
export_path="../grid-world/world.pck"
|
||||||
|
patches=PackedStringArray()
|
||||||
|
patch_delta_encoding=false
|
||||||
|
patch_delta_compression_level_zstd=19
|
||||||
|
patch_delta_min_reduction=0.1
|
||||||
|
patch_delta_include_filters="*"
|
||||||
|
patch_delta_exclude_filters=""
|
||||||
|
encryption_include_filters=""
|
||||||
|
encryption_exclude_filters=""
|
||||||
|
seed=0
|
||||||
|
encrypt_pck=false
|
||||||
|
encrypt_directory=false
|
||||||
|
script_export_mode=2
|
||||||
|
|
||||||
|
[preset.2.options]
|
||||||
|
|
||||||
|
custom_template/debug=""
|
||||||
|
custom_template/release=""
|
||||||
|
variant/extensions_support=true
|
||||||
|
variant/thread_support=false
|
||||||
|
vram_texture_compression/for_desktop=true
|
||||||
|
vram_texture_compression/for_mobile=false
|
||||||
|
html/export_icon=true
|
||||||
|
html/custom_html_shell=""
|
||||||
|
html/head_include=""
|
||||||
|
html/canvas_resize_policy=2
|
||||||
|
html/focus_canvas_on_start=true
|
||||||
|
html/experimental_virtual_keyboard=false
|
||||||
|
progressive_web_app/enabled=false
|
||||||
|
progressive_web_app/ensure_cross_origin_isolation_headers=true
|
||||||
|
progressive_web_app/offline_page=""
|
||||||
|
progressive_web_app/display=3
|
||||||
|
progressive_web_app/orientation=0
|
||||||
|
progressive_web_app/icon_144x144=""
|
||||||
|
progressive_web_app/icon_180x180=""
|
||||||
|
progressive_web_app/icon_512x512=""
|
||||||
|
progressive_web_app/background_color=Color(0, 0, 0, 1)
|
||||||
|
threads/emscripten_pool_size=8
|
||||||
|
threads/godot_pool_size=4
|
||||||
|
|||||||
@@ -135,7 +135,10 @@ transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 188.
|
|||||||
script = ExtResource("18_navbake")
|
script = ExtResource("18_navbake")
|
||||||
exclude = Array[NodePath]([NodePath("../Architecture/rock"), NodePath("../CharacterBody3D")])
|
exclude = Array[NodePath]([NodePath("../Architecture/rock"), NodePath("../CharacterBody3D")])
|
||||||
|
|
||||||
[node name="BackroomsPortal" type="Area3D" parent="." unique_id=982018721]
|
[node name="HubPortal" type="Area3D" parent="." unique_id=982018721]
|
||||||
transform = Transform3D(-0.49999985, 0, -0.8660255, 0, 1, 0, 0.8660255, 0, -0.49999985, -14.694777, 7.7547903, 22.85205)
|
transform = Transform3D(-0.49999985, 0, -0.8660255, 0, 1, 0, 0.8660255, 0, -0.49999985, -14.694777, 7.7547903, 22.85205)
|
||||||
script = ExtResource("19_portal")
|
script = ExtResource("19_portal")
|
||||||
pack_name = "backrooms.pck"
|
target_map = "hub"
|
||||||
|
target_scene = "res://World/Hub/hub.tscn"
|
||||||
|
title = "HUB"
|
||||||
|
color = Color(0.85, 0.9, 1, 1)
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ config_version=5
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="world2"
|
config/name="world2"
|
||||||
run/main_scene="uid://6vc0m7mc73f1"
|
run/main_scene="res://World/Hub/hub.tscn"
|
||||||
config/features=PackedStringArray("4.7", "GL Compatibility")
|
config/features=PackedStringArray("4.7", "GL Compatibility")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user