Структура проекта: папки по назначению, карты самодостаточны, инструменты, README
- Перенос: Net→net, Player→player, World/*→maps/{hub,sandbox,backrooms}, core, objects,
models/*→chasers/{rock,verity} и maps/*/models. Имена внутри папок с .glb не менялись
(рядом лежат извлечённые текстуры). Все пути, пресеты экспорта и автолоады обновлены.
- Преследователи: rock-follow.gd → chasers/chaser.gd; камень в песочнице теперь инстанс
chasers/rock/rock.tscn (как Верити).
- Удалён мусор: неиспользуемое небо sunflowers, Tree_01.glb, rock-path.gd, старая
модель Верити, unwrap_cache (теперь в .gitignore).
- Основной пакет игры 70 КБ (камень и Верити уехали в пакеты карт).
- tools/: export_all.sh, serve_web.py (nginx-подобный dev-сервер), deploy_server.sh,
test/ (боты, временный проект и сервер). Net: флаг --client для headless-клиента.
- deploy/: боевые nginx.conf и my-world.service, project.godot выделенного сервера.
- README переписан: что есть и чего нет, структура, карты, преследователи, сеть, пакеты,
деплой, грабли, дорожная карта (телефон).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
+119
@@ -0,0 +1,119 @@
|
||||
extends Node3D
|
||||
# Стартовая комната: ничего тяжёлого, только пол, стены и порталы на карты. Сами карты качаются
|
||||
# отдельными пакетами при входе в портал (World/map_loader.gd) — поэтому игра стартует быстро.
|
||||
# Чтобы добавить карту — допиши запись в PORTALS: порталы встанут в ряд по центру (влезает 6).
|
||||
|
||||
const PORTALS := [
|
||||
{"title": "SANDBOX", "map": "world", "scene": "res://maps/sandbox/sandbox.tscn", "pack": "world.pck", "color": Color(0.2, 0.9, 1.0)},
|
||||
{"title": "BACKROOMS", "map": "backrooms", "scene": "res://maps/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://objects/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://maps/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)
|
||||
Reference in New Issue
Block a user