Структура проекта: папки по назначению, карты самодостаточны, инструменты, 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:
2026-10-27 17:47:47 +05:00
co-authored by Claude Sonnet 5.5
parent 5ba6466113
commit fc0139dc05
158 changed files with 724 additions and 565 deletions
+66
View File
@@ -0,0 +1,66 @@
class_name Ghost
extends Node3D
# Чужой игрок: капсула, которая плавно догоняет последнее полученное состояние.
const SMOOTHING = 14.0
var target_pos := Vector3.ZERO
var target_yaw := 0.0
var flags := 0
var body: MeshInstance3D
var visor: MeshInstance3D
func setup(id: int, pos: Vector3) -> void:
name = "Ghost_%d" % id
position = pos
target_pos = pos
var color := Color.from_hsv(fmod(id * 0.618034, 1.0), 0.7, 1.0)
var mat := StandardMaterial3D.new()
mat.albedo_color = color
mat.emission_enabled = true
mat.emission = color
mat.emission_energy_multiplier = 0.6
var capsule := CapsuleMesh.new()
capsule.radius = 0.34
capsule.height = 2.3
body = MeshInstance3D.new()
body.mesh = capsule
body.material_override = mat
add_child(body)
# «Визор» показывает, куда смотрит игрок (-Z — вперёд)
var box := BoxMesh.new()
box.size = Vector3(0.5, 0.15, 0.3)
visor = MeshInstance3D.new()
visor.mesh = box
visor.position = Vector3(0, 0.9, -0.25)
add_child(visor)
var label := Label3D.new()
label.text = "Игрок %d" % (id % 1000)
label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
label.no_depth_test = true
label.position = Vector3(0, 1.6, 0)
label.pixel_size = 0.005
add_child(label)
func set_target(pos: Vector3, yaw: float, pitch: float, new_flags: int) -> void:
target_pos = pos
target_yaw = yaw
flags = new_flags
visor.rotation.x = pitch
func _process(delta: float) -> void:
var t := 1.0 - exp(-SMOOTHING * delta)
position = position.lerp(target_pos, t)
rotation.y = lerp_angle(rotation.y, target_yaw, t)
var sliding := (flags & Net.FLAG_SLIDING) != 0
var squash := 0.55 if sliding else 1.0
body.scale = body.scale.lerp(Vector3(1, squash, 1), t)
var roll := 0.0
if (flags & Net.FLAG_WALLRUN) != 0:
roll = 0.35
body.rotation.z = lerp(body.rotation.z, roll, t)