diff --git a/.gitignore b/.gitignore index 0af181c..abe1163 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ # Godot 4+ specific ignores .godot/ /android/ + +# Кэш UV-разворачивания, создаётся при импорте +*.unwrap_cache diff --git a/README.md b/README.md index 4950edd..fa06709 100644 --- a/README.md +++ b/README.md @@ -1,68 +1,227 @@ # My World -Репо самого проекта Godot (все файлы проекта). Киберпанк-мир от первого лица с паркур-управлением -и простым мультиплеером: игроки, зашедшие на сайт, бегают вместе и видят друг друга. +Мультиплеерная игра от первого лица в браузере (Godot 4.7.2, Web). Игроки собираются в стартовой +комнате-хабе, заходят через порталы на разные карты и убегают там от преследователей — камня и Верити. +Паркур-управление: спринт, рывок, подкат, присед, бег по стенам, подтягивание на уступы. -- Движок: Godot **4.7.2**, рендерер **GL Compatibility** (нужен для Web), физика Jolt -- Платформа: Web (экспорт в WebAssembly), без потоков (`variant/thread_support=false`), - поэтому заголовки COOP/COEP браузеру не требуются, но на сервере они всё равно стоят -- Язык интерфейса и комментариев в коде: русский +- **Движок:** Godot **4.7.2**, рендерер **GL Compatibility** (нужен для Web), физика **Jolt** +- **Платформа:** Web (WebAssembly), без потоков (`thread_support=false`), без GDExtension (`extensions_support=false`) +- **Язык** комментариев в коде, интерфейса и документации: русский +- **Репозитории** (соседние папки в `/home/aibrash/Projects/My_World/`): + `my-world` — этот проект; `grid-world` — готовый веб-экспорт, который CI выкладывает на сайт; + `Blender models` — исходники моделей; `source-assets` — исходные файлы вне игры (например, видео, из которого сделан звук Верити) + +## Состояние: что есть и чего нет + +| | Что | +|---|---| +| ✅ | Хаб с порталами; карты **Песочница** и **Backrooms**; выход из карт обратно в хаб | +| ✅ | Карты качаются отдельными пакетами `.pck` при первом входе в портал (экран загрузки с прогрессом) | +| ✅ | Мультиплеер: выделенный сервер, игроки видят друг друга, **комнаты по картам** (в разных картах не пересекаются) | +| ✅ | Преследователи: **камень** и **Верити**; общие для всех игроков комнаты, ходят по навмешу, «видят» только вблизи или в поле зрения, могут потерять игрока | +| ✅ | Смерть при поимке и возрождение, красный экран «ПОЙМАЛ!» | +| ✅ | Паркур: спринт, рывок, подкат, **присед (C)**, бег по стенам, прыжок от стены, двойной прыжок, подтягивание на уступ, зум (ЛКМ) | +| ✅ | Управление **не зависит от раскладки** (русская и любая другая): действия `InputMap` на физические клавиши | +| ✅ | Деплой: CI из `grid-world` на сайт; скрипты экспорта, dev-сервера, тестов без окна, выкладки сервера | +| ⏳ | Телефон: **пока не поддерживается** (нет сенсорного управления, не проверена производительность) — план в разделе «Дорожная карта» | +| ❌ | Чата, ников, настроек (чувствительность мыши, громкость), меню паузы | +| ❌ | Серверных проверок (антиспуфинг позиций, античит): сервер только пересылает | +| ❌ | Сохранения прогресса, аккаунтов | +| ❌ | Автоматических тестов в CI (есть боты для ручного прогона, см. «Тесты без окна») | +| ❌ | Анимаций персонажа: чужой игрок — просто капсула (`net/ghost.gd`) | + +## Быстрый старт + +```bash +# запуск игры локально (стартует в хабе; без сервера — одиночная игра, клиент переподключается каждые 3 с) +godot --path . --windowed --resolution 960x540 + +# с локальным сервером (в другом терминале) +tools/test/make_test_server.sh /tmp/test-server && godot --headless --path /tmp/test-server +godot --path . # можно запустить несколько окон +``` + +Карты в редакторе запускаются отдельно (F6 на сцене карты): `maps/sandbox/sandbox.tscn`, +`maps/backrooms/backrooms.tscn`. В редакторе и при запуске с диска порталы ведут на сцены напрямую (пакеты не качаются). + +## Управление + +Клавиши привязаны к **физическому расположению** (так работает и на русской раскладке). Действия лежат в +`project.godot → [input]`: `move_forward/back/left/right`, `jump`, `sprint`, `crouch`, `dash`. + +| Клавиша | Действие | +|---|---| +| W A S D, стрелки | движение | +| Shift | спринт | +| Пробел | прыжок; держать у уступа в воздухе — подтянуться; у стены — прыжок от стены; в воздухе — двойной прыжок | +| C (держать) | **присед** (скорость 3,5, капсула вдвое ниже, пролезает под низкое) | +| Shift + C на бегу | **подкат** | +| Q | рывок | +| ЛКМ (зажать) | зум | +| Esc / клик | отпустить / захватить мышь | + +Бег по стене — в воздухе у стены с зажатым «вперёд» на скорости. Ctrl не используется: в браузере `Ctrl+W` закрывает вкладку. ## Структура проекта ``` -main.tscn главная сцена (мир, окружение, свет, постройки, лес, птицы, игрок) -Player/ игрок от первого лица (CharacterBody3D) и всё паркур-управление - character_body_3d.gd ~800 строк: бег, рывок, слайд, бег по стенам, прыжки, подтягивание -World/ мир: forest.gd (лес на MultiMesh), birds.gd, levitate.gd, пол, небо (HDR), музыка -models/ .glb-модели: здания, башня, обелиск, деревья, Эмпайр-стейт, кибер-офис, скала -Net/ мультиплеер (см. ниже) - net.gd автолоад "Net": и клиент, и сервер (один скрипт) - ghost.gd чужой игрок: капсула, ник, сглаженное движение - server.tscn пустая сцена для запуска сервера -deploy/ примеры nginx-конфига, systemd-юнита, инструкция -export_presets.cfg пресет «Web», экспорт в ../grid-world/index.html +project.godot, export_presets.cfg, icon.svg +net/ сеть. Net — автолоад: и клиент, и сервер (один скрипт) + net.gd состояние комнат, преследователей, RPC (см. «Сеть») + ghost.gd чужой игрок: капсула с цветом от id и ником + server.tscn пустая сцена для запуска выделенного сервера +core/ + map_loader.gd автолоад MapLoader: скачивает пакет карты и подключает его (см. «Загрузка карт») +player/ + player.tscn, player.gd игрок от первого лица: всё паркур-управление, смерть и возрождение +objects/ + portal.gd портал на другую карту (Area3D, рисуется кодом) +chasers/ + chaser.gd общий «мозг» преследователя: навмеш, зрение, погоня, блуждание, поимка, синхронизация + rock/ камень: rock.tscn, Rock.glb (+ извлечённая текстура), Guitar.ogg + verity/ Верити: verity.tscn, verity2.glb (+ текстура), verity.ogg (звук из видео) +maps/ у каждой карты своя папка — она самодостаточна и экспортируется отдельным пакетом + hub/ стартовая комната: hub.tscn, hub.gd (порталы строятся из списка PORTALS) + sandbox/ песочница: sandbox.tscn, forest.gd, birds.gd, levitate.gd, nav_bake.gd, + floor/ sky/ audio/ models/ (здания, башня, обелиск, деревья, Эмпайр-стейт…) + backrooms/ backrooms.tscn, backrooms.gd, backrooms_nav.res (запечённый навмеш), + model/ (готовая модель «Backrooms VR» + 27 извлечённых текстур + CREDITS.md) +deploy/ боевой конфиг nginx, systemd-юнит, project.godot выделенного сервера +tools/ export_all.sh, serve_web.py, deploy_server.sh, test/ (боты) ``` -Соседние папки на компьютере разработчика (`/home/aibrash/Projects/My_World/`): -`my-world` (этот проект), `grid-world` (репо с готовым Web-экспортом, см. деплой), `Blender models`. +**Правила, которые стоит соблюдать** -## Управление (в игре) +- **Папки и файлы — в `snake_case`.** Каждая карта — в `maps/<имя>/`. Всё, что нужно только ей, лежит внутри. + Общее (игрок, преследователи, порталы, сеть) — вне `maps/`: оно входит в основной пакет игры. +- **Файлы рядом с `.glb` не переименовывать и не удалять.** Это текстуры, которые Godot вынул из модели при импорте + (`gltf/embedded_image_handling=Extract`), их имена зависят от имени `.glb`. Переименуешь `.glb` — импорт создаст дубли. + Папки с моделями переносить целиком можно (я так и делал). +- **`.import` и `.uid` коммитятся** и переносятся вместе с файлом (`git mv`). Кэш `.godot/` не коммитится; после переноса + файлов вне редактора его удаляют и делают `godot --headless --import --path .`. +- Пути в сценах — через `res://`; ссылки на карты (`PORTALS` в `hub.gd`, `target_scene` у порталов) — строками. -WASD бег, Shift спринт, Пробел прыжок (держать у уступа — подтянуться), Q рывок, -C слайд (на бегу, вместе с Shift), ЛКМ (зажать) зум, Esc отпускает мышь, клик по окну захватывает. -Бег по стене — в воздухе у стены с зажатым W на скорости. +## Карты и порталы -## Мультиплеер +| Карта | Сцена | Пакет | Что там | +|---|---|---|---| +| Хаб | `maps/hub/hub.tscn` | в основном пакете | Комната 28×18 м, строится кодом (пол-грид, стены, свет). Порталы SANDBOX и BACKROOMS в ряд по центру, влезает 6. Безопасна, преследователей нет | +| Песочница | `maps/sandbox/sandbox.tscn` | `world.pck` | Киберпанк-мир: пол-шахматка, здания, 60 деревьев (MultiMesh), птицы, парящий обелиск, звук `tron_01`. Преследователи: **камень** и **Верити**. Портал «HUB» возвращает в хаб | +| Backrooms | `maps/backrooms/backrooms.tscn` | `backrooms.pck` | Модель «Backrooms VR» (×1,4). Преследователь: **Верити** (масштаб 0,5). Выход «EXIT» в дальнем конце ведёт в хаб. Гул ламп генерируется кодом | -**Архитектура:** выделенный сервер на Godot (WebSocket), клиенты подключаются как `WebSocketMultiplayerPeer`. -Сервер ничего не считает и не проверяет, только пересылает состояния игроков остальным. -Мир, физика и управление работают локально у каждого. Игроки друг с другом не сталкиваются. +**Добавить карту:** +1. Создай `maps/<имя>/<имя>.tscn`: корень Node3D, внутри игрок (`player/player.tscn`), портал обратно (`objects/portal.gd`, + `target_map="hub"`, `target_scene="res://maps/hub/hub.tscn"`), при необходимости преследователи. + В `_ready()` вызови `Net.enter_map("<имя>")` (идемпотентно; так сервер знает, в какой ты комнате). +2. Если нужны преследователи — навмеш: либо `NavigationRegion3D` + `maps/sandbox/nav_bake.gd` (запекание при старте, как в песочнице), + либо заранее запечённый `.res` (как у Backrooms: в вебе без потоков запекать на лету долго). +3. В `export_presets.cfg` добавь пресет-копию «World» (`export_filter="resources"`, `export_files=["res://maps/<имя>/<имя>.tscn"]`, + `exclude_filter="player/*, objects/*, chasers/chaser.gd"`, `export_path="../grid-world/<имя>.pck"`), + а в пресет «Web» — `maps/<имя>/*` в `exclude_filter`. Добавь вызов в `tools/export_all.sh`. +4. В `PORTALS` (`maps/hub/hub.gd`) допиши запись `{title, map, scene, pack, color}` — портал появится сам. -- `Net/net.gd` — автолоад `Net`. Если `DisplayServer.get_name() == "headless"` — это **сервер** - (порт **9080**, plain `ws://`), иначе **клиент**. Клиент переподключается каждые 3 с. -- Клиент шлёт 20 раз/с `submit_state(pos, yaw, pitch, flags)` (RPC на сервер, `unreliable_ordered`), - сервер пересылает остальным `recv_state(id, ...)`, при выходе — `recv_left(id)` (reliable). -- Флаги состояния (`Net.FLAG_*`): подкат, бег по стене, рывок, подтягивание. - Собираются в `Player/character_body_3d.gd` → `get_net_flags()`. Игрок находится в группе `local_player`. -- Клиент-призрак: `Net/ghost.gd` — капсула с цветом от id, «визор» показывает направление взгляда, ник «Игрок N». -- **Адрес сервера в клиенте:** в Web — из `window.location` (`wss://<домен>/ws` для https, `ws://<домен>/ws` для http); - на десктопе — `ws://127.0.0.1:9080` или аргумент `godot -- --server-url=wss://...`. -- **RPC требуют одинаковый путь узла и скрипт на сервере и клиенте.** Поэтому один скрипт `net.gd` в автолоаде. - Менять сетевые сообщения нужно синхронно: клиент (экспорт) + сервер (`/opt/my-world-server`), иначе игроки не увидят друг друга. +## Преследователи -### Запуск локально +`chasers/chaser.gd` — один скрипт для всех. Сцены (`rock.tscn`, `verity.tscn`) — это просто модель + звук + `NavigationAgent3D`. + +- **Поведение:** гонится за ближайшим живым игроком по навмешу, ловит на `catch_distance` (по горизонтали, не выше `catch_height`). + После поимки игрок умирает и возрождается через 2,5 с в стартовой точке; если преследователь рядом со стартом — уходит на свой старт. +- **Зрение** (`sight_limited = true`): замечает игрока, если он ближе `hearing_radius` (слышит даже за стеной) **или** в конусе `sight_fov` + до `sight_range` и луч до него не упирается в стену. Потерял из виду — идёт к последнему месту `lose_time` секунд, потом блуждает (`patrol_speed`, `wander_radius`). + Без `sight_limited` знает, где игрок, из любой точки. +- **Параметры** (экспорты узла): `chaser_id` (имя в сети), `speed`, `turn_speed`, `catch_distance`, `catch_height`, `sight_*`, `hearing_radius`, + `lose_time`, `patrol_speed`, `wander_radius`, `model_scale` (масштаб дочернего узла `Model`), `emission_energy` (чисто светящийся материал; у Верити 1,0). +- **Значения сейчас:** камень в песочнице — скорость 15, зрение 45 м / 130°, слух 8 м, лимит потери 5 с. Верити в песочнице — скорость 12, зрение 55 м / 110°, слух 10 м, потеря 6 с. + Верити в Backrooms — скорость 10, масштаб 0,5, зрение по умолчанию (30 м / 120° / слух 6 м / потеря 4 с). +- **Модели — плоские «карточки»** вдоль оси X; в сцене повёрнуты на 90° и подняты, чтобы стоять на полу. У `verity2` лицо нарисовано с одной стороны + (свечением), при погоне оно повёрнуто к игроку. +- **Добавить преследователя:** новая сцена по образцу `verity.tscn` (корень со скриптом `chaser.gd`, `chaser_id="имя"`, `NavigationAgent3D`), + инстанс в карту. Больше ничего: сеть синхронизирует всех по имени. + +## Сеть + +**Архитектура:** выделенный сервер на Godot (WebSocket, порт **9080**), клиенты — `WebSocketMultiplayerPeer`. Сервер **не знает про уровни** +и ничего не считает, только пересылает сообщения внутри «комнаты» (карты). Физика, управление, **преследователи** считаются на клиентах. + +- `net/net.gd` — автолоад `Net`. `DisplayServer.get_name() == "headless"` → **сервер**, иначе клиент; флаг `--client` делает клиентом и headless (боты). + Клиент переподключается каждые 3 с. Адрес в вебе берётся из `window.location` (`wss://<домен>/ws` или `ws://`), на десктопе — `ws://127.0.0.1:9080` или `-- --server-url=...`. +- **Комнаты по картам.** Клиент при входе на карту шлёт `submit_map(имя)`, сервер отвечает `recv_map_ack`. Пока подтверждения нет (`Net.map_ready == false`), + клиент игнорирует чужие сообщения — так при смене карты не просачиваются старые пакеты. Игроки разных карт друг друга не видят. +- **Владелец преследователей.** В каждой комнате один клиент (первый вошедший, затем наименьший `peer_id` из оставшихся) симулирует **всех** преследователей и + шлёт их позиции 20 раз/с; остальные клиенты плавно повторяют. Если владелец молчит `ROCK_TIMEOUT` = 3 с (вкладка в фоне, лаги) или вышел — сервер передаёт роль другому; + преследователь продолжает с того же места. Поимку «своего» игрока всегда решает его собственный клиент по тому, что он видит. +- **Смерть и возрождение** шлются отдельно (`submit_life`), чтобы владелец не гнался за мёртвыми и мог увести преследователя от точки возрождения. + +| RPC | Кто → кому | Что | +|---|---|---| +| `submit_map(map)` / `recv_map_ack(map)` | клиент → сервер / обратно | вход в комнату | +| `recv_rock_owner(id)` | сервер → клиенты | кто симулирует преследователей | +| `submit_state(pos, yaw, pitch, flags)` / `recv_state(id, …)` | клиент → сервер → остальные | состояние игрока, 20 Гц, `unreliable_ordered` | +| `submit_chasers(ids, positions, yaws)` / `recv_chasers(…)` | владелец → сервер → остальные | позиции всех преследователей, 20 Гц | +| `submit_life(dead, pos)` / `recv_life(id, dead, pos)` | клиент → сервер → остальные | смерть/возрождение, `reliable` | +| `recv_left(id)` | сервер → комната | игрок вышел | + +Флаги состояния (`Net.FLAG_*`): подкат, бег по стене, рывок, подтягивание. Присед передаётся как подкат (у призрака сплюснутая капсула). + +**RPC требуют одинаковые путь узла и скрипт на сервере и клиенте**, поэтому `net.gd` один. Любое изменение RPC — **клиент и сервер выкладываются вместе** +(старый клиент с новым сервером не работает). Имена вроде `rock_owner`/`recv_rock_owner` остались от времени, когда преследователь был один. + +## Загрузка карт пакетами (веб) + +Основной пакет игры (`index.pck`) — только хаб, игрок, сеть и порталы (около 70 КБ). Движок — `index.wasm` (39,5 МБ, ~10 МБ с gzip). +Карты — отдельные `.pck`: `world.pck` (13,6 МБ), `backrooms.pck` (21,3 МБ). Портал вызывает `MapLoader.enter(map, scene, pack, title)`: + +1. если сцена уже есть в проекте (редактор, десктоп, пакет уже скачан) — переход сразу; +2. иначе игра встаёт на паузу (преследователь не должен убить игрока на экране загрузки), показывается «Загрузка: <имя> N / M МБ»; +3. пакет качается `HTTPRequest` с `Cache-Control: no-cache` (браузер сверяет файл с сервером), записывается в `user://` и подключается через + `ProjectSettings.load_resource_pack(path, false)` (**`false`** — файлы основной игры в приоритете, устаревший пакет не затрёт код); +4. при ошибке на экране и в консоли пишется причина, портал можно повторить. + +**Грабли, на которые уже наступили:** +- `HTTPRequest` в браузере: **`accept_gzip = false`** обязательно. Браузер сам распаковывает gzip, а движок видит `Content-Encoding: gzip` и пытается распаковать ещё раз (ошибка 8). +- **`download_file` в вебе не создаёт файл** — тело берём в память и пишем в `user://` сами. +- Файлы-«не ресурсы» (`.mp4`, `.md`) не экспортируются; потому исходное видео Верити лежит вне проекта (`source-assets`). +- Предупреждения `invalid UID … using text path instead` при загрузке пакета безвредны. +- **Кэш зависимостей редактора** у недавно созданных/изменённых сцен может устареть, и экспорт пакета карты пропустит модели и звуки (пакет «слишком маленький»). + `tools/export_all.sh` делает `touch` сцен перед экспортом. Признак беды: размер пакета не вырос после добавления ресурсов. + +## Экспорт, тесты и деплой + +### Экспорт ```bash -# сервер -godot --headless --path . res://Net/server.tscn -# клиент (можно запустить несколько окон) -godot --path . --windowed --resolution 960x540 +tools/export_all.sh # веб-клиент + backrooms.pck + world.pck в ../grid-world ``` -Осторожность: `pkill -f` / `pgrep -f` с шаблоном `godot --headless` убивает и сам шелл, -потому что шаблон встречается в его командной строке. Находить процесс лучше через `ss -ltnp | grep 9080`. +Три пресета в `export_presets.cfg`: **Web** (хаб + общее; из него исключены `maps/sandbox`, `maps/backrooms`, `chasers/rock`, `chasers/verity`, `tools`), +**World** и **Backrooms** (`export_filter=resources` — сцена карты и всё, на что она ссылается, кроме общего из основного пакета). Шаблоны экспорта — +`~/.local/share/godot/export_templates/4.7.2.stable/` (есть только Web). Экспорт при выходе печатает безвредную ошибку `Parameter "singleton" is null`. -## Инфраструктура и деплой +### Проверка сборки как на сервере + +```bash +python3 tools/serve_web.py ../grid-world 8080 # nginx-подобно: COOP/COEP и gzip чанками +``` +Открыть `http://127.0.0.1:8080`. На десктопном `godot --main-pack` пакеты карт качаются плоским `python3 -m http.server` (без gzip) через `-- --pack-url=http://127.0.0.1:8777/`. + +### Тесты без окна (боты) + +Автотестов в CI нет; для проверок есть боты. `tools/test/make_test_project.sh /tmp/tp` делает временную копию проекта с автозагрузкой `tools/test/bot.gd` +(телепортирует игрока по расписанию и печатает состояние раз в секунду), `tools/test/make_test_server.sh /tmp/ts` — локальный сервер в боевой раскладке. + +```bash +godot --headless --path /tmp/ts & # сервер +godot --headless --path /tmp/tp res://maps/sandbox/sandbox.tscn -- --client --name=A & +godot --headless --path /tmp/tp res://maps/sandbox/sandbox.tscn -- --client --name=B +# цепочка карт на реальных пакетах (портал SANDBOX в хабе на (-2.25, -7.5), BACKROOMS на (2.25, -7.5)): +/tmp/tp/tools/export_all.sh /tmp/site && (cd /tmp/site && python3 -m http.server 8777 --bind 127.0.0.1 &) +godot --headless --main-pack /tmp/site/index.pck -- --client --name=T --pack-url=http://127.0.0.1:8777/ --tp=2:-2.25,1,-7.5 +``` +Для картинок: `godot --path . --resolution 1152x648 --fixed-fps 10 --write-movie /tmp/shots/a.png --quit-after 25 res://maps/hub/hub.tscn` (окно мелькнёт; кадры — `a00000020.png`). +В браузере: Chrome (flatpak `com.google.Chrome`) `--headless=new --enable-logging=stderr --v=0 http://127.0.0.1:8080` — вывод Godot виден в строках `CONSOLE`. + +**Осторожно:** `pkill -f`/`pgrep -f` с шаблоном, который есть и в твоей же командной строке, убивает собственный шелл; не используй `pkill chrome` — закроет браузер владельца. Останавливай по PID или по точному признаку. + +### Деплой ``` Браузер ──https/wss──▶ Nginx Proxy Manager (SSL, домен на duckdns) ──http──▶ контейнер 192.168.10.110 @@ -70,61 +229,75 @@ godot --path . --windowed --resolution 960x540 ├─ / → /opt/grid-world (статика игры) └─ /ws → 127.0.0.1:9080 (игровой сервер) ``` +**Сервер:** `root@192.168.10.110`, Debian 12, контейнер LXC в Proxmox, 1 ядро, 1 ГБ RAM, ssh по ключам. Нет `curl`, `rsync`, `ufw`; есть `python3`. +В Nginx Proxy Manager включено **Websockets Support** (без него `/ws` не работает). Боевой конфиг nginx: `deploy/nginx.conf` +(`/etc/nginx/sites-enabled/godot_game`); обязателен **gzip для `.wasm`/`.pck`** (иначе 39,5 + 21 МБ уходят как есть) и заголовки COOP/COEP. -**Сервер:** `root@192.168.10.110`, Debian 12, контейнер LXC в Proxmox, 1 ядро, 1 ГБ RAM. Ключи ssh настроены. -Нет `curl`, `rsync`, `ufw`; есть `python3`, `perl`. Домен и SSL на Nginx Proxy Manager выше по сети; в его proxy host -должна быть включена опция **Websockets Support** (иначе `/ws` не работает; сейчас работает, проверено в браузере). - -### Обновить клиент (изменился мир, модель, игровой код) +**Клиент:** `tools/export_all.sh`, затем коммит и пуш в `grid-world` (`main`). Gitea (`git.ibrash.duckdns.org`, `aibrash/grid-world`) по пушу запускает +`.gitea/workflows/deploy.yml`: ssh на сервер и `git pull` в `/opt/grid-world`. Пакеты карт выкладываются вместе с `index.*`. +**Сервер:** отдельный минимальный проект в `/opt/my-world-server/` (`project.godot` + `net/` + официальный бинарник Godot 4.7.2 linux x86_64 `godot`; бинарник из Fedora на Debian не подходит, +берётся из `github.com/godotengine/godot-builds`). Служба systemd `my-world.service` (`deploy/my-world.service`, DynamicUser, `Restart=always`). ```bash -cd ~/Projects/My_World/my-world -godot --headless --path . --export-release Web ../grid-world/index.html -cd ../grid-world && git add -A && git commit -m "..." && git push origin main +tools/deploy_server.sh root@192.168.10.110 # бэкап, копирование net/ и project.godot, пересборка кэша классов, перезапуск +ssh root@192.168.10.110 'journalctl -u my-world -f' # лог: «+ игрок …», «[карта] камень считает игрок …» ``` -Gitea (`git.ibrash.duckdns.org`, репо `aibrash/grid-world`) по пушу в `main` запускает workflow -`.gitea/workflows/deploy.yml`: заходит по ssh и делает `git pull` в `/opt/grid-world`. Экспорт при выходе -печатает безвредную ошибку `Parameter "singleton" is null`. - -### Обновить игровой сервер (изменился `Net/*`) - -Игровой сервер — отдельный минимальный проект в `/opt/my-world-server/` (`project.godot` + `Net/` + официальный -бинарник Godot 4.7.2 linux x86_64, файл `godot`). Бинарник из Fedora на Debian не подходит, взят официальный из -`github.com/godotengine/godot-builds` (релиз `4.7.2-stable`). Сервис systemd: `my-world.service` -(DynamicUser, `StateDirectory=my-world`, автозапуск, `Restart=always`). - -```bash -scp Net/net.gd Net/ghost.gd Net/server.tscn root@192.168.10.110:/opt/my-world-server/Net/ -ssh root@192.168.10.110 'systemctl restart my-world' -ssh root@192.168.10.110 'journalctl -u my-world -f' # лог: «+ игрок …» / «- игрок …» -``` -При правках модели/мира серверную часть трогать не нужно. Игровой сервер слушает порт 9080 на всех интерфейсах -контейнера (наружу не проброшен). Можно сузить до `127.0.0.1` через `create_server(port, "127.0.0.1")`. - -nginx контейнера: `/etc/nginx/sites-enabled/godot_game` (резервная копия до правок: `/root/godot_game.bak`); -в нём блок `location /ws` с заголовками `Upgrade`/`Connection`. +Трогать сервер нужно только при изменении `net/*`. **Порядок при изменении RPC:** сначала пуш `grid-world`, сразу следом `deploy_server.sh`; игрокам — Ctrl+F5. +Откат сервера: бэкап в `/opt/backup-my-world-server-<дата>/`. +> Сейчас на сервере ещё **старая раскладка** (`/opt/my-world-server/Net/`, заглавная). `deploy_server.sh` при следующем запуске переведёт её на `net/`. +> Код сети при этом по протоколу не изменился. ### Git -- Репо проекта: `git@git.ibrash.duckdns.org:aibrash/my-world.git`, ветка `master` (основная), используются - коммиты на русском с трейлером `Co-Authored-By`. Для экспериментов создаётся ветка `dev` (была слита и удалена). -- Пушить `master` и выкладывать на сайт — только по прямой просьбе владельца. +- Репо проекта: `git@git.ibrash.duckdns.org:aibrash/my-world.git`, основная ветка `master`; коммиты на русском с трейлером `Co-Authored-By`. +- **Пушить и выкладывать на сайт — только по прямой просьбе владельца.** Коммитить локально можно. -## Что выяснено по ходу работы (полезно не повторять) +## Что выяснено по ходу работы -- **Окружение (`main.tscn`):** в рендерере Compatibility **объёмный туман не работает** (ни кадр не меняется, ни память), поэтому он удалён. - **SSAO и glow работают**: glow даёт неоновое свечение, SSAO — затемнение в стыках; оба оставлены. Отключение всех трёх - экономило лишь около 4 МБ видеопамяти и убирало вид, поэтому это не причина высокой памяти. -- **Память:** вкладка в браузере показывала около **1,6 ГБ**, хотя на десктопе сцена занимает ~115 МБ (статика 83 МБ + видеопамять 30 МБ). - Причина не найдена. Нужны данные из Chrome (`Shift+Esc`: память / память GPU / JS-память и растёт ли цифра со временем). - Гипотезы: рост WASM-памяти и GPU-процесс Chrome, несжатые текстуры (для Web выключено `vram_texture_compression/for_mobile`), - HDR-небо 2k, звук `.ogg`, распаковываемый целиком, `dlink` (`extensions_support=true`, `index.side.wasm` 44 МБ). -- Пресет «Web» экспортирует в `../grid-world/index.html`. Шаблоны экспорта лежат в `~/.local/share/godot/export_templates/4.7.2.stable/` - (есть только Web; Linux-шаблонов нет, поэтому серверный бинарник — официальный редактор в режиме headless). +- **Окружение:** в рендерере Compatibility **объёмный туман не работает** (удалён из песочницы). SSAO и glow работают (неоновое свечение), оставлены. + В Backrooms включён обычный туман (`Environment.fog_*`), он работает. +- **Память:** вкладка в браузере показывала около **1,6 ГБ**, хотя на десктопе сцена занимает ~115 МБ. Причина не найдена (нужны данные Chrome: `Shift+Esc`). + Гипотезы: рост WASM-памяти, несжатые текстуры, HDR-небо 2k, `.ogg`, распаковываемый целиком. Измерения с тех пор не повторялись. +- **Материал Верити** — две поверхности: жёлтая основа и диск с лицом (текстура свечения на белой основе). Белая основа на ярком свету даёт бледность, + поэтому `emission_energy` делает материал чисто светящимся (чёрная основа). +- **Backrooms:** двери ~1,8 м, поэтому преследователь там масштабом 0,5 и навмеш запечён для агента радиусом 0,6 (иначе проход закрыт). Самый дальний зал за узкой дверью недостижим. +- **Ввод:** `Input.is_key_pressed(KEY_W)` проверяет символ, на русской раскладке это «Ц». Только действия `InputMap` на физические клавиши. +- **Пресеты:** при отключённом `extensions_support` — один `index.wasm`; включение даёт ещё `index.side.wasm` 44 МБ. -## Идеи на потом +## Дорожная карта -- Скрипт `deploy.sh`: экспорт + пуш клиента + при необходимости обновление сервера одной командой. -- Ники по выбору игрока, текстовый чат, анимации персонажа вместо капсулы. -- Серверные проверки (антиспуфинг позиций), комнаты, если игроков станет много. -- Разобраться с потреблением памяти в браузере (см. выше). +### Цель: играть с телефона + +Сейчас игра рассчитана на клавиатуру и мышь. Что нужно сделать, по порядку: + +1. **Сенсорное управление.** Основа уже есть: ввод игрока сведён к действиям `InputMap`, поэтому сенсорные кнопки просто вызывают + `Input.action_press/release("move_forward", strength)` и т. д. Нужна сцена `ui/touch_controls.tscn` (CanvasLayer): виртуальный стик слева (движение), + зона перетаскивания справа (обзор), кнопки прыжка, спринта (переключатель), приседа (удержание), рывка, зума. Показывать только на сенсорных устройствах + (`DisplayServer.is_touchscreen_available()` и feature-теги `web_android`/`web_ios`). В `player/player.gd` обзор сейчас считается из `InputEventMouseMotion` при захваченной мыши — + добавить обработку `InputEventScreenDrag`; зум по ЛКМ заменить действием `zoom`. +2. **Ориентация и экран:** принудительно альбомная (`display/window/handheld/orientation`), полноэкранный режим по первому касанию (браузеры требуют жест), + масштаб интерфейса (надписи «ПОЙМАЛ!», экран загрузки сейчас рассчитаны на десктоп), безопасные зоны. +3. **Звук:** браузер не стартует `AudioContext` без касания. Добавить экран «Нажми, чтобы начать» перед хабом (заодно решает и предупреждение на десктопе). +4. **Текстуры (главное узкое место):** мобильные GPU не поддерживают S3TC/BPTC, которыми сейчас сжаты текстуры (`vram_texture_compression/for_desktop=true`, `for_mobile=false`). + Нужно включить `for_mobile` (ETC2/ASTC) — это **удваивает размер пакетов**, если держать оба формата в одном `.pck`. Варианты: отдельные пакеты `*.mobile.pck`, + выбираемые по feature-тегу, и уменьшенные текстуры (27 текстур Backrooms по 2К — тяжёлые). +5. **Производительность и память:** на телефоне отключить SSAO/glow (в Compatibility они дорогие), уменьшить `Viewport.scaling_3d_scale` (0,6–0,75), + меньше деревьев и птиц, теней нет у деревьев уже сейчас. Мобильный Safari убивает вкладки около 1–1,5 ГБ, а на десктопе она уже занимала 1,6 ГБ — **сначала разобраться с памятью** + (см. выше). Проверить размер `.wasm` и распаковку (на сотовой сети 40 МБ чувствительны; `index.wasm` уже жмётся gzip). +6. **Сеть:** вкладка уходит в фон и замирает — владельца преследователей сервер уже передаёт другому через 3 с; клиенту при возвращении стоит + показывать «переподключение» и заново входить в комнату (`submit_map`), если соединение сброшено. +7. **Тестирование:** режим устройства в Chrome DevTools; на реальном телефоне — `tools/serve_web.py` по локальной сети (`http://:8080`, привязать сервер к `0.0.0.0`). + Минимальная планка: 30 FPS в хабе и песочнице на среднем Android. + +### Другое + +- Ники по выбору игрока, текстовый чат, анимации персонажа вместо капсулы, настройки (чувствительность, громкость), меню паузы. +- Серверные проверки (антиспуфинг позиций), если игроков станет много. +- Новые карты (добавляются по инструкции выше) и новые преследователи. +- Автоматизировать прогон ботов в CI и проверку «пакет не пустой» после экспорта. + +## Лицензии и авторство + +- Модель карты Backrooms — «Backrooms VR», автор VTX (https://sketchfab.com/VTX_car), **CC-BY 4.0** (`maps/backrooms/model/CREDITS.md`). + При публикации нужно указывать автора. +- Остальные модели и звуки — материалы владельца проекта. diff --git a/World/Sky/sunflowers_puresky_2k.hdr b/World/Sky/sunflowers_puresky_2k.hdr deleted file mode 100644 index 902a81e..0000000 Binary files a/World/Sky/sunflowers_puresky_2k.hdr and /dev/null differ diff --git a/World/Sky/sunflowers_puresky_2k.hdr.import b/World/Sky/sunflowers_puresky_2k.hdr.import deleted file mode 100644 index f4f218e..0000000 --- a/World/Sky/sunflowers_puresky_2k.hdr.import +++ /dev/null @@ -1,41 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bhoaea7w0r382" -path.bptc="res://.godot/imported/sunflowers_puresky_2k.hdr-e6836c1a1deabbee5439c7c137a6328a.bptc.ctex" -metadata={ -"imported_formats": ["s3tc_bptc"], -"vram_texture": true -} - -[deps] - -source_file="res://World/Sky/sunflowers_puresky_2k.hdr" -dest_files=["res://.godot/imported/sunflowers_puresky_2k.hdr-e6836c1a1deabbee5439c7c137a6328a.bptc.ctex"] - -[params] - -compress/mode=2 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=true -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=0 diff --git a/World/tron_01.ogg.import b/World/tron_01.ogg.import deleted file mode 100644 index ed9275e..0000000 --- a/World/tron_01.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://ddsynauqeoppw" -path="res://.godot/imported/tron_01.ogg-0e18fb85b15fd0798053a5bd0a4a9def.oggvorbisstr" - -[deps] - -source_file="res://World/tron_01.ogg" -dest_files=["res://.godot/imported/tron_01.ogg-0e18fb85b15fd0798053a5bd0a4a9def.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/models/Bochi-Rock/rock-follow.gd b/chasers/chaser.gd similarity index 94% rename from models/Bochi-Rock/rock-follow.gd rename to chasers/chaser.gd index 16d2f47..a60095a 100644 --- a/models/Bochi-Rock/rock-follow.gd +++ b/chasers/chaser.gd @@ -1,9 +1,9 @@ extends Node3D # Преследователь (камень, Верити…): гонится за ближайшим живым игроком, обходя препятствия по навмешу, и ловит его. -# С sight_limited он замечает игрока лишь вблизи или в поле зрения без стен между ними; +# С sight_limited замечает игрока лишь вблизи или в поле зрения без стен между ними; # потеряв из виду, идёт к последнему месту, где видел, и дальше бродит по карте. -# В сети камень считает один клиент (владелец, его назначает сервер), остальные -# плавно повторяют его позицию — поэтому у всех игроков камень один и тот же. +# В сети всех преследователей комнаты считает один клиент (владелец, его назначает сервер, см. net/net.gd), +# остальные плавно повторяют их позиции — поэтому у всех игроков преследователи одни и те же. @export var chaser_id := "rock" # Имя в сети: по нему владелец и остальные клиенты сопоставляют преследователей @export var model_scale := 1.0 # Масштаб узла Model (если он есть): уменьшаем в тесных картах @@ -13,7 +13,7 @@ extends Node3D @export var catch_distance := 3.0 # С какого расстояния (по горизонтали) ловит игрока @export var catch_height := 4.0 # Игрока выше этого над камнем не достать @export var repath_distance := 1.0 # Пересчитываем путь, когда игрок сместился на столько -@export var respawn_safe_radius := 25.0 # Игрок возродился ближе этого к камню — камень уходит на старт +@export var respawn_safe_radius := 25.0 # Игрок возродился ближе этого — преследователь уходит на свой старт @export var sync_smoothing := 12.0 # Плавность повтора чужого камня @export var snap_distance := 20.0 # Дальше этого чужой камень не едет, а прыгает (сброс на старт) diff --git a/models/Bochi-Rock/rock-follow.gd.uid b/chasers/chaser.gd.uid similarity index 100% rename from models/Bochi-Rock/rock-follow.gd.uid rename to chasers/chaser.gd.uid diff --git a/models/Bochi-Rock/Guitar.ogg b/chasers/rock/Guitar.ogg similarity index 100% rename from models/Bochi-Rock/Guitar.ogg rename to chasers/rock/Guitar.ogg diff --git a/chasers/rock/Guitar.ogg.import b/chasers/rock/Guitar.ogg.import new file mode 100644 index 0000000..70642a5 --- /dev/null +++ b/chasers/rock/Guitar.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://280pvcvxt2n2" +path="res://.godot/imported/Guitar.ogg-a9c649256b934e43412c17ea4e1fd302.oggvorbisstr" + +[deps] + +source_file="res://chasers/rock/Guitar.ogg" +dest_files=["res://.godot/imported/Guitar.ogg-a9c649256b934e43412c17ea4e1fd302.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/models/Bochi-Rock/Rock.glb b/chasers/rock/Rock.glb similarity index 100% rename from models/Bochi-Rock/Rock.glb rename to chasers/rock/Rock.glb diff --git a/models/Bochi-Rock/Rock.glb.import b/chasers/rock/Rock.glb.import similarity index 82% rename from models/Bochi-Rock/Rock.glb.import rename to chasers/rock/Rock.glb.import index 4552827..73e849e 100644 --- a/models/Bochi-Rock/Rock.glb.import +++ b/chasers/rock/Rock.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://cowp33ejxcfcl" -path="res://.godot/imported/Rock.glb-4f2376a14ce37861c14e06a47e678e34.scn" +path="res://.godot/imported/Rock.glb-d2a8f3a84a2ecdbbc2d73c9b22190137.scn" [deps] -source_file="res://models/Bochi-Rock/Rock.glb" -dest_files=["res://.godot/imported/Rock.glb-4f2376a14ce37861c14e06a47e678e34.scn"] +source_file="res://chasers/rock/Rock.glb" +dest_files=["res://.godot/imported/Rock.glb-d2a8f3a84a2ecdbbc2d73c9b22190137.scn"] [params] diff --git a/models/Bochi-Rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg b/chasers/rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg similarity index 100% rename from models/Bochi-Rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg rename to chasers/rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg diff --git a/models/Bochi-Rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg.import b/chasers/rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg.import similarity index 83% rename from models/Bochi-Rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg.import rename to chasers/rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg.import index d268ef9..a1f7870 100644 --- a/models/Bochi-Rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg.import +++ b/chasers/rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://bx6t5621iqw7f" -path.s3tc="res://.godot/imported/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg-fad3b4615e62f76758b5970cba2671a7.s3tc.ctex" +path.s3tc="res://.godot/imported/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg-4f14ab3f29d2ef2273e9da4765cef118.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/Bochi-Rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg" -dest_files=["res://.godot/imported/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg-fad3b4615e62f76758b5970cba2671a7.s3tc.ctex"] +source_file="res://chasers/rock/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg" +dest_files=["res://.godot/imported/Rock_22ee8cdbd4ccc631cd7c804ab4ebca15.jpg-4f14ab3f29d2ef2273e9da4765cef118.s3tc.ctex"] [params] diff --git a/models/Bochi-Rock/rock.tscn b/chasers/rock/rock.tscn similarity index 73% rename from models/Bochi-Rock/rock.tscn rename to chasers/rock/rock.tscn index 73434aa..5e5209d 100644 --- a/models/Bochi-Rock/rock.tscn +++ b/chasers/rock/rock.tscn @@ -1,8 +1,8 @@ [gd_scene format=3] -[ext_resource type="Script" path="res://models/Bochi-Rock/rock-follow.gd" id="1_script"] -[ext_resource type="PackedScene" uid="uid://cowp33ejxcfcl" path="res://models/Bochi-Rock/Rock.glb" id="2_model"] -[ext_resource type="AudioStream" uid="uid://280pvcvxt2n2" path="res://models/Bochi-Rock/Guitar.ogg" id="3_audio"] +[ext_resource type="Script" path="res://chasers/chaser.gd" id="1_script"] +[ext_resource type="PackedScene" uid="uid://cowp33ejxcfcl" path="res://chasers/rock/Rock.glb" id="2_model"] +[ext_resource type="AudioStream" uid="uid://280pvcvxt2n2" path="res://chasers/rock/Guitar.ogg" id="3_audio"] [node name="Rock" type="Node3D"] script = ExtResource("1_script") diff --git a/models/verity/verity.ogg b/chasers/verity/verity.ogg similarity index 100% rename from models/verity/verity.ogg rename to chasers/verity/verity.ogg diff --git a/chasers/verity/verity.ogg.import b/chasers/verity/verity.ogg.import new file mode 100644 index 0000000..3e04952 --- /dev/null +++ b/chasers/verity/verity.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://b7qmenkjh1wdk" +path="res://.godot/imported/verity.ogg-e0f71c02d742979c6aefd117ffe3f1b5.oggvorbisstr" + +[deps] + +source_file="res://chasers/verity/verity.ogg" +dest_files=["res://.godot/imported/verity.ogg-e0f71c02d742979c6aefd117ffe3f1b5.oggvorbisstr"] + +[params] + +loop=true +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/models/verity/verity.tscn b/chasers/verity/verity.tscn similarity index 69% rename from models/verity/verity.tscn rename to chasers/verity/verity.tscn index f65e4b0..cfb0783 100644 --- a/models/verity/verity.tscn +++ b/chasers/verity/verity.tscn @@ -1,8 +1,8 @@ [gd_scene format=3] -[ext_resource type="Script" path="res://models/Bochi-Rock/rock-follow.gd" id="1_script"] -[ext_resource type="PackedScene" path="res://models/verity/verity2.glb" id="2_model"] -[ext_resource type="AudioStream" path="res://models/verity/verity.ogg" id="3_audio"] +[ext_resource type="Script" path="res://chasers/chaser.gd" id="1_script"] +[ext_resource type="PackedScene" path="res://chasers/verity/verity2.glb" id="2_model"] +[ext_resource type="AudioStream" path="res://chasers/verity/verity.ogg" id="3_audio"] [node name="Verity" type="Node3D"] script = ExtResource("1_script") diff --git a/models/verity/verity2.glb b/chasers/verity/verity2.glb similarity index 100% rename from models/verity/verity2.glb rename to chasers/verity/verity2.glb diff --git a/models/verity/verity2.glb.import b/chasers/verity/verity2.glb.import similarity index 81% rename from models/verity/verity2.glb.import rename to chasers/verity/verity2.glb.import index c338da7..90b8b8f 100644 --- a/models/verity/verity2.glb.import +++ b/chasers/verity/verity2.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://wup5p3waumce" -path="res://.godot/imported/verity2.glb-74448d25644050663fdf5f7cb5b2b561.scn" +path="res://.godot/imported/verity2.glb-60af6cc5d69d9f8af83072155580b49b.scn" [deps] -source_file="res://models/verity/verity2.glb" -dest_files=["res://.godot/imported/verity2.glb-74448d25644050663fdf5f7cb5b2b561.scn"] +source_file="res://chasers/verity/verity2.glb" +dest_files=["res://.godot/imported/verity2.glb-60af6cc5d69d9f8af83072155580b49b.scn"] [params] diff --git a/models/verity/verity2_unnamed.webp b/chasers/verity/verity2_unnamed.webp similarity index 100% rename from models/verity/verity2_unnamed.webp rename to chasers/verity/verity2_unnamed.webp diff --git a/models/verity/verity2_unnamed.webp.import b/chasers/verity/verity2_unnamed.webp.import similarity index 76% rename from models/verity/verity2_unnamed.webp.import rename to chasers/verity/verity2_unnamed.webp.import index fdb8e8b..f5656ee 100644 --- a/models/verity/verity2_unnamed.webp.import +++ b/chasers/verity/verity2_unnamed.webp.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://c4fe3eo5c2w6g" -path.s3tc="res://.godot/imported/verity2_unnamed.webp-5857f5fcb0e2a440b744a4c083bfb79c.s3tc.ctex" +path.s3tc="res://.godot/imported/verity2_unnamed.webp-1aa0cf701c3ad8dae1575d20b6b42222.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/verity/verity2_unnamed.webp" -dest_files=["res://.godot/imported/verity2_unnamed.webp-5857f5fcb0e2a440b744a4c083bfb79c.s3tc.ctex"] +source_file="res://chasers/verity/verity2_unnamed.webp" +dest_files=["res://.godot/imported/verity2_unnamed.webp-1aa0cf701c3ad8dae1575d20b6b42222.s3tc.ctex"] [params] diff --git a/World/map_loader.gd b/core/map_loader.gd similarity index 100% rename from World/map_loader.gd rename to core/map_loader.gd diff --git a/World/map_loader.gd.uid b/core/map_loader.gd.uid similarity index 100% rename from World/map_loader.gd.uid rename to core/map_loader.gd.uid diff --git a/deploy/README.md b/deploy/README.md index 827389b..91f2c7c 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,17 +1 @@ -# Мультиплеер: деплой - -## Сервер игры -Выделенный сервер — тот же проект, запущенный headless (порт 9080, plain WebSocket): - - godot --headless --path /путь/к/my-world res://Net/server.tscn - -Пример systemd-юнита: `deploy/my-world.service`. - -## nginx (TLS + статика) -См. `deploy/nginx.conf`. Страница по https подключается к `wss://<домен>/ws`, -nginx проксирует `/ws` на `127.0.0.1:9080`. - -## Клиент -Web-экспорт (пресет «Web») кладётся в корень сайта. Адрес сервера берётся из -`window.location`, на десктопе — `ws://127.0.0.1:9080` или -`godot -- --server-url=wss://example.com/ws`. +Деплой описан в корневом [README.md](../README.md#деплой). diff --git a/deploy/my-world.service b/deploy/my-world.service index 15def89..863fc3b 100644 --- a/deploy/my-world.service +++ b/deploy/my-world.service @@ -3,9 +3,11 @@ Description=My World game server After=network.target [Service] -ExecStart=/usr/bin/godot --headless --path /opt/my-world res://Net/server.tscn +ExecStart=/opt/my-world-server/godot --headless --path /opt/my-world-server Restart=always -User=nobody +DynamicUser=yes +StateDirectory=my-world +Environment=HOME=/var/lib/my-world [Install] WantedBy=multi-user.target diff --git a/deploy/nginx.conf b/deploy/nginx.conf index d3e5617..8a246e3 100644 --- a/deploy/nginx.conf +++ b/deploy/nginx.conf @@ -1,11 +1,22 @@ +# Боевой конфиг сайта (/etc/nginx/sites-enabled/godot_game). +# Статику клиента кладёт CI (git pull в /opt/grid-world), /ws проксируется на игровой сервер. server { - listen 443 ssl; - server_name example.com; - # ssl_certificate / ssl_certificate_key — например, от certbot + listen 80; + server_name _; - root /var/www/my-world; # сюда экспорт Web (index.html, .wasm, .pck) + root /opt/grid-world/; index index.html; + # Нужны Godot web (SharedArrayBuffer/изоляция страницы) + add_header Cross-Origin-Opener-Policy "same-origin"; + add_header Cross-Origin-Embedder-Policy "require-corp"; + + # .wasm и .pck хорошо жмутся: 39,5 МБ -> ~10 МБ. Браузер распаковывает сам (см. core/map_loader.gd) + gzip on; + gzip_comp_level 6; + gzip_min_length 1024; + gzip_types application/wasm application/octet-stream application/javascript text/javascript text/css application/json image/svg+xml; + location /ws { proxy_pass http://127.0.0.1:9080; proxy_http_version 1.1; @@ -14,4 +25,8 @@ server { proxy_set_header Host $host; proxy_read_timeout 1h; } + + location / { + try_files $uri $uri/ =404; + } } diff --git a/deploy/server/project.godot b/deploy/server/project.godot new file mode 100644 index 0000000..391d257 --- /dev/null +++ b/deploy/server/project.godot @@ -0,0 +1,13 @@ +; Проект выделенного сервера (headless). Кладётся рядом с папкой net/ из репозитория. +; На сервере: /opt/my-world-server/{project.godot, net/, godot}. См. tools/deploy_server.sh +config_version=5 + +[application] + +config/name="world2-server" +run/main_scene="res://net/server.tscn" +config/features=PackedStringArray("4.7") + +[autoload] + +Net="*res://net/net.gd" diff --git a/export_presets.cfg b/export_presets.cfg index 7c058d7..242385a 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -10,7 +10,7 @@ dedicated_server=false custom_features="" export_filter="all_resources" include_filter="" -exclude_filter="models/verity/*, 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/*" +exclude_filter="tools/*, maps/sandbox/*, maps/backrooms/*, chasers/rock/*, chasers/verity/*" export_path="../grid-world/index.html" patches=PackedStringArray() patch_delta_encoding=false @@ -58,9 +58,9 @@ platform="Web" dedicated_server=false custom_features="" export_filter="resources" -export_files=PackedStringArray("res://World/Backrooms/backrooms.tscn") +export_files=PackedStringArray("res://maps/backrooms/backrooms.tscn") include_filter="" -exclude_filter="Player/*, models/Bochi-Rock/*, World/portal.gd" +exclude_filter="player/*, objects/*, chasers/chaser.gd" export_path="../grid-world/backrooms.pck" patches=PackedStringArray() patch_delta_encoding=false @@ -108,9 +108,9 @@ platform="Web" dedicated_server=false custom_features="" export_filter="resources" -export_files=PackedStringArray("res://main.tscn") +export_files=PackedStringArray("res://maps/sandbox/sandbox.tscn") include_filter="" -exclude_filter="Player/*, models/Bochi-Rock/*, World/portal.gd" +exclude_filter="player/*, objects/*, chasers/chaser.gd" export_path="../grid-world/world.pck" patches=PackedStringArray() patch_delta_encoding=false diff --git a/World/Backrooms/backrooms.gd b/maps/backrooms/backrooms.gd similarity index 100% rename from World/Backrooms/backrooms.gd rename to maps/backrooms/backrooms.gd diff --git a/World/Backrooms/backrooms.gd.uid b/maps/backrooms/backrooms.gd.uid similarity index 100% rename from World/Backrooms/backrooms.gd.uid rename to maps/backrooms/backrooms.gd.uid diff --git a/World/Backrooms/backrooms.tscn b/maps/backrooms/backrooms.tscn similarity index 76% rename from World/Backrooms/backrooms.tscn rename to maps/backrooms/backrooms.tscn index a23722f..604da50 100644 --- a/World/Backrooms/backrooms.tscn +++ b/maps/backrooms/backrooms.tscn @@ -1,11 +1,11 @@ [gd_scene format=3 uid="uid://djgkggvwiaaoy"] -[ext_resource type="Script" uid="uid://gmpkjl6m3415" path="res://World/Backrooms/backrooms.gd" id="1_level"] -[ext_resource type="PackedScene" uid="uid://b8ef3wy1pthgm" path="res://models/backrooms/backrooms_vr.glb" id="2_map"] -[ext_resource type="PackedScene" uid="uid://c3efk6k8xnf57" path="res://Player/Player.tscn" id="3_player"] -[ext_resource type="PackedScene" path="res://models/verity/verity.tscn" id="4_rock"] -[ext_resource type="Script" uid="uid://bu8v0ivhmnykt" path="res://World/portal.gd" id="5_portal"] -[ext_resource type="NavigationMesh" path="res://World/Backrooms/backrooms_nav.res" id="6_nav"] +[ext_resource type="Script" uid="uid://gmpkjl6m3415" path="res://maps/backrooms/backrooms.gd" id="1_level"] +[ext_resource type="PackedScene" uid="uid://b8ef3wy1pthgm" path="res://maps/backrooms/model/backrooms_vr.glb" id="2_map"] +[ext_resource type="PackedScene" uid="uid://c3efk6k8xnf57" path="res://player/player.tscn" id="3_player"] +[ext_resource type="PackedScene" path="res://chasers/verity/verity.tscn" id="4_rock"] +[ext_resource type="Script" uid="uid://bu8v0ivhmnykt" path="res://objects/portal.gd" id="5_portal"] +[ext_resource type="NavigationMesh" path="res://maps/backrooms/backrooms_nav.res" id="6_nav"] [node name="Backrooms" type="Node3D" unique_id=511186617] script = ExtResource("1_level") @@ -28,7 +28,7 @@ sight_limited = true transform = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, -92.93203, -0.15, 10.390619) script = ExtResource("5_portal") target_map = "hub" -target_scene = "res://World/Hub/hub.tscn" +target_scene = "res://maps/hub/hub.tscn" title = "EXIT" color = Color(0.3, 1, 0.45, 1) diff --git a/World/Backrooms/backrooms_nav.res b/maps/backrooms/backrooms_nav.res similarity index 100% rename from World/Backrooms/backrooms_nav.res rename to maps/backrooms/backrooms_nav.res diff --git a/models/backrooms/CREDITS.md b/maps/backrooms/model/CREDITS.md similarity index 100% rename from models/backrooms/CREDITS.md rename to maps/backrooms/model/CREDITS.md diff --git a/models/backrooms/backrooms_vr.glb b/maps/backrooms/model/backrooms_vr.glb similarity index 100% rename from models/backrooms/backrooms_vr.glb rename to maps/backrooms/model/backrooms_vr.glb diff --git a/models/backrooms/backrooms_vr.glb.import b/maps/backrooms/model/backrooms_vr.glb.import similarity index 80% rename from models/backrooms/backrooms_vr.glb.import rename to maps/backrooms/model/backrooms_vr.glb.import index 413dc24..dffb99f 100644 --- a/models/backrooms/backrooms_vr.glb.import +++ b/maps/backrooms/model/backrooms_vr.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://b8ef3wy1pthgm" -path="res://.godot/imported/backrooms_vr.glb-0d2b88698924672a51ea9e43fb3ac8a4.scn" +path="res://.godot/imported/backrooms_vr.glb-a44db63c437b581310f90765822ced16.scn" [deps] -source_file="res://models/backrooms/backrooms_vr.glb" -dest_files=["res://.godot/imported/backrooms_vr.glb-0d2b88698924672a51ea9e43fb3ac8a4.scn"] +source_file="res://maps/backrooms/model/backrooms_vr.glb" +dest_files=["res://.godot/imported/backrooms_vr.glb-a44db63c437b581310f90765822ced16.scn"] [params] diff --git a/models/backrooms/backrooms_vr_0.png b/maps/backrooms/model/backrooms_vr_0.png similarity index 100% rename from models/backrooms/backrooms_vr_0.png rename to maps/backrooms/model/backrooms_vr_0.png diff --git a/models/backrooms/backrooms_vr_0.png.import b/maps/backrooms/model/backrooms_vr_0.png.import similarity index 76% rename from models/backrooms/backrooms_vr_0.png.import rename to maps/backrooms/model/backrooms_vr_0.png.import index 4935975..e462ad6 100644 --- a/models/backrooms/backrooms_vr_0.png.import +++ b/maps/backrooms/model/backrooms_vr_0.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://b6weikavgdbap" -path.s3tc="res://.godot/imported/backrooms_vr_0.png-f4c02e53a6cca71b1adac7615326ab0e.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_0.png-2be6c844f99fa11d85c6f7f7ea9febaf.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_0.png" -dest_files=["res://.godot/imported/backrooms_vr_0.png-f4c02e53a6cca71b1adac7615326ab0e.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_0.png" +dest_files=["res://.godot/imported/backrooms_vr_0.png-2be6c844f99fa11d85c6f7f7ea9febaf.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_1.png b/maps/backrooms/model/backrooms_vr_1.png similarity index 100% rename from models/backrooms/backrooms_vr_1.png rename to maps/backrooms/model/backrooms_vr_1.png diff --git a/models/backrooms/backrooms_vr_1.png.import b/maps/backrooms/model/backrooms_vr_1.png.import similarity index 76% rename from models/backrooms/backrooms_vr_1.png.import rename to maps/backrooms/model/backrooms_vr_1.png.import index eb6d823..a2bfc95 100644 --- a/models/backrooms/backrooms_vr_1.png.import +++ b/maps/backrooms/model/backrooms_vr_1.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://dpud2naqkm4xs" -path.s3tc="res://.godot/imported/backrooms_vr_1.png-d716f61def983b3d40016ab77643deb5.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_1.png-58eff1a40efb7f44ec9e5051210a83fb.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_1.png" -dest_files=["res://.godot/imported/backrooms_vr_1.png-d716f61def983b3d40016ab77643deb5.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_1.png" +dest_files=["res://.godot/imported/backrooms_vr_1.png-58eff1a40efb7f44ec9e5051210a83fb.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_10.png b/maps/backrooms/model/backrooms_vr_10.png similarity index 100% rename from models/backrooms/backrooms_vr_10.png rename to maps/backrooms/model/backrooms_vr_10.png diff --git a/models/backrooms/backrooms_vr_10.png.import b/maps/backrooms/model/backrooms_vr_10.png.import similarity index 76% rename from models/backrooms/backrooms_vr_10.png.import rename to maps/backrooms/model/backrooms_vr_10.png.import index 2a81501..962e55f 100644 --- a/models/backrooms/backrooms_vr_10.png.import +++ b/maps/backrooms/model/backrooms_vr_10.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://b8nb23j42isps" -path.s3tc="res://.godot/imported/backrooms_vr_10.png-6693254cade6e5be230303d4e03a4118.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_10.png-66735878c6a889d3b78eb86dd9d140a6.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_10.png" -dest_files=["res://.godot/imported/backrooms_vr_10.png-6693254cade6e5be230303d4e03a4118.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_10.png" +dest_files=["res://.godot/imported/backrooms_vr_10.png-66735878c6a889d3b78eb86dd9d140a6.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_11.png b/maps/backrooms/model/backrooms_vr_11.png similarity index 100% rename from models/backrooms/backrooms_vr_11.png rename to maps/backrooms/model/backrooms_vr_11.png diff --git a/models/backrooms/backrooms_vr_11.png.import b/maps/backrooms/model/backrooms_vr_11.png.import similarity index 76% rename from models/backrooms/backrooms_vr_11.png.import rename to maps/backrooms/model/backrooms_vr_11.png.import index 7203eda..f482c59 100644 --- a/models/backrooms/backrooms_vr_11.png.import +++ b/maps/backrooms/model/backrooms_vr_11.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://djx5e3wiwgqex" -path.s3tc="res://.godot/imported/backrooms_vr_11.png-a17fa98ada75a88222940123fa22d2c4.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_11.png-1b4bc124dd509717784a19ff35407041.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_11.png" -dest_files=["res://.godot/imported/backrooms_vr_11.png-a17fa98ada75a88222940123fa22d2c4.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_11.png" +dest_files=["res://.godot/imported/backrooms_vr_11.png-1b4bc124dd509717784a19ff35407041.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_12.png b/maps/backrooms/model/backrooms_vr_12.png similarity index 100% rename from models/backrooms/backrooms_vr_12.png rename to maps/backrooms/model/backrooms_vr_12.png diff --git a/models/backrooms/backrooms_vr_12.png.import b/maps/backrooms/model/backrooms_vr_12.png.import similarity index 76% rename from models/backrooms/backrooms_vr_12.png.import rename to maps/backrooms/model/backrooms_vr_12.png.import index cf260e9..7296d86 100644 --- a/models/backrooms/backrooms_vr_12.png.import +++ b/maps/backrooms/model/backrooms_vr_12.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://djyh6v1wlujbx" -path.s3tc="res://.godot/imported/backrooms_vr_12.png-d78f07b6d7d3138c20741e40ee92edfa.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_12.png-4b9b409931a846aa266212c354316816.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_12.png" -dest_files=["res://.godot/imported/backrooms_vr_12.png-d78f07b6d7d3138c20741e40ee92edfa.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_12.png" +dest_files=["res://.godot/imported/backrooms_vr_12.png-4b9b409931a846aa266212c354316816.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_13.png b/maps/backrooms/model/backrooms_vr_13.png similarity index 100% rename from models/backrooms/backrooms_vr_13.png rename to maps/backrooms/model/backrooms_vr_13.png diff --git a/models/backrooms/backrooms_vr_13.png.import b/maps/backrooms/model/backrooms_vr_13.png.import similarity index 76% rename from models/backrooms/backrooms_vr_13.png.import rename to maps/backrooms/model/backrooms_vr_13.png.import index 4ce4c80..71d9c7a 100644 --- a/models/backrooms/backrooms_vr_13.png.import +++ b/maps/backrooms/model/backrooms_vr_13.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://dw68nfgta46bg" -path.s3tc="res://.godot/imported/backrooms_vr_13.png-5712190a97c0176b90edbead990dd794.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_13.png-0fc1704bbe3dc42d01705e5699474f84.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_13.png" -dest_files=["res://.godot/imported/backrooms_vr_13.png-5712190a97c0176b90edbead990dd794.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_13.png" +dest_files=["res://.godot/imported/backrooms_vr_13.png-0fc1704bbe3dc42d01705e5699474f84.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_14.png b/maps/backrooms/model/backrooms_vr_14.png similarity index 100% rename from models/backrooms/backrooms_vr_14.png rename to maps/backrooms/model/backrooms_vr_14.png diff --git a/models/backrooms/backrooms_vr_14.png.import b/maps/backrooms/model/backrooms_vr_14.png.import similarity index 76% rename from models/backrooms/backrooms_vr_14.png.import rename to maps/backrooms/model/backrooms_vr_14.png.import index 8158d15..19f76ec 100644 --- a/models/backrooms/backrooms_vr_14.png.import +++ b/maps/backrooms/model/backrooms_vr_14.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://cgx5ip8cpgxly" -path.s3tc="res://.godot/imported/backrooms_vr_14.png-bbec912f44ebcc9f8e50c98b8f9abaad.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_14.png-ef53db6b8d8b9de93738fb3214c4a754.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_14.png" -dest_files=["res://.godot/imported/backrooms_vr_14.png-bbec912f44ebcc9f8e50c98b8f9abaad.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_14.png" +dest_files=["res://.godot/imported/backrooms_vr_14.png-ef53db6b8d8b9de93738fb3214c4a754.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_15.png b/maps/backrooms/model/backrooms_vr_15.png similarity index 100% rename from models/backrooms/backrooms_vr_15.png rename to maps/backrooms/model/backrooms_vr_15.png diff --git a/models/backrooms/backrooms_vr_15.png.import b/maps/backrooms/model/backrooms_vr_15.png.import similarity index 76% rename from models/backrooms/backrooms_vr_15.png.import rename to maps/backrooms/model/backrooms_vr_15.png.import index 4533ecd..01e5b0f 100644 --- a/models/backrooms/backrooms_vr_15.png.import +++ b/maps/backrooms/model/backrooms_vr_15.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://dxvxjwfnpxqyb" -path.s3tc="res://.godot/imported/backrooms_vr_15.png-a20bd15c0b1b28d9456bc931978a218d.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_15.png-bdd518883610319d83796f212056da76.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_15.png" -dest_files=["res://.godot/imported/backrooms_vr_15.png-a20bd15c0b1b28d9456bc931978a218d.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_15.png" +dest_files=["res://.godot/imported/backrooms_vr_15.png-bdd518883610319d83796f212056da76.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_16.png b/maps/backrooms/model/backrooms_vr_16.png similarity index 100% rename from models/backrooms/backrooms_vr_16.png rename to maps/backrooms/model/backrooms_vr_16.png diff --git a/models/backrooms/backrooms_vr_16.png.import b/maps/backrooms/model/backrooms_vr_16.png.import similarity index 76% rename from models/backrooms/backrooms_vr_16.png.import rename to maps/backrooms/model/backrooms_vr_16.png.import index 4aa71c9..052bdc0 100644 --- a/models/backrooms/backrooms_vr_16.png.import +++ b/maps/backrooms/model/backrooms_vr_16.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://yjj1swxlp5le" -path.s3tc="res://.godot/imported/backrooms_vr_16.png-07a4cbc529fe565672c305dfd8e573d6.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_16.png-a9e77912985bd57ee651e6170a096b24.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_16.png" -dest_files=["res://.godot/imported/backrooms_vr_16.png-07a4cbc529fe565672c305dfd8e573d6.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_16.png" +dest_files=["res://.godot/imported/backrooms_vr_16.png-a9e77912985bd57ee651e6170a096b24.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_17.png b/maps/backrooms/model/backrooms_vr_17.png similarity index 100% rename from models/backrooms/backrooms_vr_17.png rename to maps/backrooms/model/backrooms_vr_17.png diff --git a/models/backrooms/backrooms_vr_17.png.import b/maps/backrooms/model/backrooms_vr_17.png.import similarity index 76% rename from models/backrooms/backrooms_vr_17.png.import rename to maps/backrooms/model/backrooms_vr_17.png.import index 8ec6fda..20a8e36 100644 --- a/models/backrooms/backrooms_vr_17.png.import +++ b/maps/backrooms/model/backrooms_vr_17.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://decg78uck2mqa" -path.s3tc="res://.godot/imported/backrooms_vr_17.png-5a591d4362230f749be443a19b09de4f.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_17.png-19b989596eb512a37eeb8e755657cf6c.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_17.png" -dest_files=["res://.godot/imported/backrooms_vr_17.png-5a591d4362230f749be443a19b09de4f.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_17.png" +dest_files=["res://.godot/imported/backrooms_vr_17.png-19b989596eb512a37eeb8e755657cf6c.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_18.png b/maps/backrooms/model/backrooms_vr_18.png similarity index 100% rename from models/backrooms/backrooms_vr_18.png rename to maps/backrooms/model/backrooms_vr_18.png diff --git a/models/backrooms/backrooms_vr_18.png.import b/maps/backrooms/model/backrooms_vr_18.png.import similarity index 76% rename from models/backrooms/backrooms_vr_18.png.import rename to maps/backrooms/model/backrooms_vr_18.png.import index dc70b0e..161a58f 100644 --- a/models/backrooms/backrooms_vr_18.png.import +++ b/maps/backrooms/model/backrooms_vr_18.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://brljydqpvgko0" -path.s3tc="res://.godot/imported/backrooms_vr_18.png-137b67a1864cee9569a91581bee56ca4.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_18.png-715bde8336c095d043c0cd3f1be4f502.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_18.png" -dest_files=["res://.godot/imported/backrooms_vr_18.png-137b67a1864cee9569a91581bee56ca4.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_18.png" +dest_files=["res://.godot/imported/backrooms_vr_18.png-715bde8336c095d043c0cd3f1be4f502.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_19.png b/maps/backrooms/model/backrooms_vr_19.png similarity index 100% rename from models/backrooms/backrooms_vr_19.png rename to maps/backrooms/model/backrooms_vr_19.png diff --git a/models/backrooms/backrooms_vr_19.png.import b/maps/backrooms/model/backrooms_vr_19.png.import similarity index 76% rename from models/backrooms/backrooms_vr_19.png.import rename to maps/backrooms/model/backrooms_vr_19.png.import index b082dc2..9dbb9f7 100644 --- a/models/backrooms/backrooms_vr_19.png.import +++ b/maps/backrooms/model/backrooms_vr_19.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://dciao7v0fkii1" -path.s3tc="res://.godot/imported/backrooms_vr_19.png-cdf77da915a8406d23a1f971a1d765fe.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_19.png-49227045cdea27d1b381e3b9a831ee24.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_19.png" -dest_files=["res://.godot/imported/backrooms_vr_19.png-cdf77da915a8406d23a1f971a1d765fe.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_19.png" +dest_files=["res://.godot/imported/backrooms_vr_19.png-49227045cdea27d1b381e3b9a831ee24.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_2.png b/maps/backrooms/model/backrooms_vr_2.png similarity index 100% rename from models/backrooms/backrooms_vr_2.png rename to maps/backrooms/model/backrooms_vr_2.png diff --git a/models/backrooms/backrooms_vr_2.png.import b/maps/backrooms/model/backrooms_vr_2.png.import similarity index 76% rename from models/backrooms/backrooms_vr_2.png.import rename to maps/backrooms/model/backrooms_vr_2.png.import index 13c9e3a..d5d4d01 100644 --- a/models/backrooms/backrooms_vr_2.png.import +++ b/maps/backrooms/model/backrooms_vr_2.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://eorb1lixjtbv" -path.s3tc="res://.godot/imported/backrooms_vr_2.png-4f70d8bd72d6cc50f9b317463f7076b9.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_2.png-f1a53db9b9d3fd8a5ada6b370f18b647.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_2.png" -dest_files=["res://.godot/imported/backrooms_vr_2.png-4f70d8bd72d6cc50f9b317463f7076b9.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_2.png" +dest_files=["res://.godot/imported/backrooms_vr_2.png-f1a53db9b9d3fd8a5ada6b370f18b647.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_20.png b/maps/backrooms/model/backrooms_vr_20.png similarity index 100% rename from models/backrooms/backrooms_vr_20.png rename to maps/backrooms/model/backrooms_vr_20.png diff --git a/models/backrooms/backrooms_vr_20.png.import b/maps/backrooms/model/backrooms_vr_20.png.import similarity index 76% rename from models/backrooms/backrooms_vr_20.png.import rename to maps/backrooms/model/backrooms_vr_20.png.import index 0348f66..231d692 100644 --- a/models/backrooms/backrooms_vr_20.png.import +++ b/maps/backrooms/model/backrooms_vr_20.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://xbcxlgw40igt" -path.s3tc="res://.godot/imported/backrooms_vr_20.png-4ac1f7f9258502dc9178e35c5602f20d.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_20.png-1d10fd330e1a8c0fc61d7486329ee063.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_20.png" -dest_files=["res://.godot/imported/backrooms_vr_20.png-4ac1f7f9258502dc9178e35c5602f20d.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_20.png" +dest_files=["res://.godot/imported/backrooms_vr_20.png-1d10fd330e1a8c0fc61d7486329ee063.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_21.png b/maps/backrooms/model/backrooms_vr_21.png similarity index 100% rename from models/backrooms/backrooms_vr_21.png rename to maps/backrooms/model/backrooms_vr_21.png diff --git a/models/backrooms/backrooms_vr_21.png.import b/maps/backrooms/model/backrooms_vr_21.png.import similarity index 76% rename from models/backrooms/backrooms_vr_21.png.import rename to maps/backrooms/model/backrooms_vr_21.png.import index e0c0f4e..58c7540 100644 --- a/models/backrooms/backrooms_vr_21.png.import +++ b/maps/backrooms/model/backrooms_vr_21.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://crx06wyll47ou" -path.s3tc="res://.godot/imported/backrooms_vr_21.png-99c9bdd476eb15db8a1993bf96f942b2.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_21.png-222e2c54fbdeedd6c0487b075650545f.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_21.png" -dest_files=["res://.godot/imported/backrooms_vr_21.png-99c9bdd476eb15db8a1993bf96f942b2.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_21.png" +dest_files=["res://.godot/imported/backrooms_vr_21.png-222e2c54fbdeedd6c0487b075650545f.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_22.png b/maps/backrooms/model/backrooms_vr_22.png similarity index 100% rename from models/backrooms/backrooms_vr_22.png rename to maps/backrooms/model/backrooms_vr_22.png diff --git a/models/backrooms/backrooms_vr_22.png.import b/maps/backrooms/model/backrooms_vr_22.png.import similarity index 76% rename from models/backrooms/backrooms_vr_22.png.import rename to maps/backrooms/model/backrooms_vr_22.png.import index ad0a362..702874b 100644 --- a/models/backrooms/backrooms_vr_22.png.import +++ b/maps/backrooms/model/backrooms_vr_22.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://cqareamgsajs" -path.s3tc="res://.godot/imported/backrooms_vr_22.png-a69fa573ac9737ff98f9e3a9cb90184f.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_22.png-b8965588f76146db08bcab06a453e84c.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_22.png" -dest_files=["res://.godot/imported/backrooms_vr_22.png-a69fa573ac9737ff98f9e3a9cb90184f.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_22.png" +dest_files=["res://.godot/imported/backrooms_vr_22.png-b8965588f76146db08bcab06a453e84c.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_23.png b/maps/backrooms/model/backrooms_vr_23.png similarity index 100% rename from models/backrooms/backrooms_vr_23.png rename to maps/backrooms/model/backrooms_vr_23.png diff --git a/models/backrooms/backrooms_vr_23.png.import b/maps/backrooms/model/backrooms_vr_23.png.import similarity index 76% rename from models/backrooms/backrooms_vr_23.png.import rename to maps/backrooms/model/backrooms_vr_23.png.import index ac3b10a..ce2d7aa 100644 --- a/models/backrooms/backrooms_vr_23.png.import +++ b/maps/backrooms/model/backrooms_vr_23.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://dy57qg8yhs4cx" -path.s3tc="res://.godot/imported/backrooms_vr_23.png-1d7ffb8aa29d441bde425ede0413250c.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_23.png-4090a5fff0cc06e162bacc68b3fd83ce.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_23.png" -dest_files=["res://.godot/imported/backrooms_vr_23.png-1d7ffb8aa29d441bde425ede0413250c.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_23.png" +dest_files=["res://.godot/imported/backrooms_vr_23.png-4090a5fff0cc06e162bacc68b3fd83ce.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_24.png b/maps/backrooms/model/backrooms_vr_24.png similarity index 100% rename from models/backrooms/backrooms_vr_24.png rename to maps/backrooms/model/backrooms_vr_24.png diff --git a/models/backrooms/backrooms_vr_24.png.import b/maps/backrooms/model/backrooms_vr_24.png.import similarity index 76% rename from models/backrooms/backrooms_vr_24.png.import rename to maps/backrooms/model/backrooms_vr_24.png.import index bad7a4d..2bb21fb 100644 --- a/models/backrooms/backrooms_vr_24.png.import +++ b/maps/backrooms/model/backrooms_vr_24.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://bt548bd7s4get" -path.s3tc="res://.godot/imported/backrooms_vr_24.png-584f508479d8bb3725096fabaf30673a.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_24.png-bf9b213fc302459f00c11b5b6a489a2d.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_24.png" -dest_files=["res://.godot/imported/backrooms_vr_24.png-584f508479d8bb3725096fabaf30673a.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_24.png" +dest_files=["res://.godot/imported/backrooms_vr_24.png-bf9b213fc302459f00c11b5b6a489a2d.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_25.png b/maps/backrooms/model/backrooms_vr_25.png similarity index 100% rename from models/backrooms/backrooms_vr_25.png rename to maps/backrooms/model/backrooms_vr_25.png diff --git a/models/backrooms/backrooms_vr_25.png.import b/maps/backrooms/model/backrooms_vr_25.png.import similarity index 76% rename from models/backrooms/backrooms_vr_25.png.import rename to maps/backrooms/model/backrooms_vr_25.png.import index fa0fb44..a365dab 100644 --- a/models/backrooms/backrooms_vr_25.png.import +++ b/maps/backrooms/model/backrooms_vr_25.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://doneeapv77gj1" -path.s3tc="res://.godot/imported/backrooms_vr_25.png-9c0c3ba7ed9c43115c11c01e6ca76972.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_25.png-7986d2b08dc2f459f7a7b7872e6a16e1.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_25.png" -dest_files=["res://.godot/imported/backrooms_vr_25.png-9c0c3ba7ed9c43115c11c01e6ca76972.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_25.png" +dest_files=["res://.godot/imported/backrooms_vr_25.png-7986d2b08dc2f459f7a7b7872e6a16e1.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_26.png b/maps/backrooms/model/backrooms_vr_26.png similarity index 100% rename from models/backrooms/backrooms_vr_26.png rename to maps/backrooms/model/backrooms_vr_26.png diff --git a/models/backrooms/backrooms_vr_26.png.import b/maps/backrooms/model/backrooms_vr_26.png.import similarity index 76% rename from models/backrooms/backrooms_vr_26.png.import rename to maps/backrooms/model/backrooms_vr_26.png.import index 9f9f246..236d90a 100644 --- a/models/backrooms/backrooms_vr_26.png.import +++ b/maps/backrooms/model/backrooms_vr_26.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://cg4knissk32f0" -path.s3tc="res://.godot/imported/backrooms_vr_26.png-d404be6f8ec663c23a65f332e8e41866.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_26.png-258a94dd265e35223b36b7a90dfee344.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_26.png" -dest_files=["res://.godot/imported/backrooms_vr_26.png-d404be6f8ec663c23a65f332e8e41866.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_26.png" +dest_files=["res://.godot/imported/backrooms_vr_26.png-258a94dd265e35223b36b7a90dfee344.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_3.png b/maps/backrooms/model/backrooms_vr_3.png similarity index 100% rename from models/backrooms/backrooms_vr_3.png rename to maps/backrooms/model/backrooms_vr_3.png diff --git a/models/backrooms/backrooms_vr_3.png.import b/maps/backrooms/model/backrooms_vr_3.png.import similarity index 76% rename from models/backrooms/backrooms_vr_3.png.import rename to maps/backrooms/model/backrooms_vr_3.png.import index 361c675..c6aed03 100644 --- a/models/backrooms/backrooms_vr_3.png.import +++ b/maps/backrooms/model/backrooms_vr_3.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://3gy68ac2rkdx" -path.s3tc="res://.godot/imported/backrooms_vr_3.png-afd56e334c7320959e31f3683f2ccc4f.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_3.png-4355c26a3df456240cd49a319f1cd5de.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_3.png" -dest_files=["res://.godot/imported/backrooms_vr_3.png-afd56e334c7320959e31f3683f2ccc4f.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_3.png" +dest_files=["res://.godot/imported/backrooms_vr_3.png-4355c26a3df456240cd49a319f1cd5de.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_4.png b/maps/backrooms/model/backrooms_vr_4.png similarity index 100% rename from models/backrooms/backrooms_vr_4.png rename to maps/backrooms/model/backrooms_vr_4.png diff --git a/models/backrooms/backrooms_vr_4.png.import b/maps/backrooms/model/backrooms_vr_4.png.import similarity index 76% rename from models/backrooms/backrooms_vr_4.png.import rename to maps/backrooms/model/backrooms_vr_4.png.import index 2cd7758..835eab1 100644 --- a/models/backrooms/backrooms_vr_4.png.import +++ b/maps/backrooms/model/backrooms_vr_4.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://d3verocm47dx8" -path.s3tc="res://.godot/imported/backrooms_vr_4.png-93a12f44d34aa99fbfe8479f9f95dda0.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_4.png-4a8967702e5eee6c2b19c6c5d1c0c555.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_4.png" -dest_files=["res://.godot/imported/backrooms_vr_4.png-93a12f44d34aa99fbfe8479f9f95dda0.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_4.png" +dest_files=["res://.godot/imported/backrooms_vr_4.png-4a8967702e5eee6c2b19c6c5d1c0c555.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_5.png b/maps/backrooms/model/backrooms_vr_5.png similarity index 100% rename from models/backrooms/backrooms_vr_5.png rename to maps/backrooms/model/backrooms_vr_5.png diff --git a/models/backrooms/backrooms_vr_5.png.import b/maps/backrooms/model/backrooms_vr_5.png.import similarity index 76% rename from models/backrooms/backrooms_vr_5.png.import rename to maps/backrooms/model/backrooms_vr_5.png.import index 28be6c8..54f2923 100644 --- a/models/backrooms/backrooms_vr_5.png.import +++ b/maps/backrooms/model/backrooms_vr_5.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://cnhk7o54biy8d" -path.s3tc="res://.godot/imported/backrooms_vr_5.png-5c53a0e2465ec929aaf203e355069c55.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_5.png-92bd0164b916a3cf31302520ddb50d1d.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_5.png" -dest_files=["res://.godot/imported/backrooms_vr_5.png-5c53a0e2465ec929aaf203e355069c55.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_5.png" +dest_files=["res://.godot/imported/backrooms_vr_5.png-92bd0164b916a3cf31302520ddb50d1d.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_6.png b/maps/backrooms/model/backrooms_vr_6.png similarity index 100% rename from models/backrooms/backrooms_vr_6.png rename to maps/backrooms/model/backrooms_vr_6.png diff --git a/models/backrooms/backrooms_vr_6.png.import b/maps/backrooms/model/backrooms_vr_6.png.import similarity index 76% rename from models/backrooms/backrooms_vr_6.png.import rename to maps/backrooms/model/backrooms_vr_6.png.import index d4cc40a..5d2d27a 100644 --- a/models/backrooms/backrooms_vr_6.png.import +++ b/maps/backrooms/model/backrooms_vr_6.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://cjglgsq24tgpr" -path.s3tc="res://.godot/imported/backrooms_vr_6.png-9ef6d8013d662a2fe026a614c10ff766.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_6.png-087f2ed0886aa3d81ebc9b5b30ba5bb4.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_6.png" -dest_files=["res://.godot/imported/backrooms_vr_6.png-9ef6d8013d662a2fe026a614c10ff766.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_6.png" +dest_files=["res://.godot/imported/backrooms_vr_6.png-087f2ed0886aa3d81ebc9b5b30ba5bb4.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_7.png b/maps/backrooms/model/backrooms_vr_7.png similarity index 100% rename from models/backrooms/backrooms_vr_7.png rename to maps/backrooms/model/backrooms_vr_7.png diff --git a/models/backrooms/backrooms_vr_7.png.import b/maps/backrooms/model/backrooms_vr_7.png.import similarity index 76% rename from models/backrooms/backrooms_vr_7.png.import rename to maps/backrooms/model/backrooms_vr_7.png.import index c7e3477..a0738b0 100644 --- a/models/backrooms/backrooms_vr_7.png.import +++ b/maps/backrooms/model/backrooms_vr_7.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://7ctu8yeskavl" -path.s3tc="res://.godot/imported/backrooms_vr_7.png-08770a42a1db34f7b66ca5ade29b3692.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_7.png-6349183f10a2172a16f16a287d42d208.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_7.png" -dest_files=["res://.godot/imported/backrooms_vr_7.png-08770a42a1db34f7b66ca5ade29b3692.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_7.png" +dest_files=["res://.godot/imported/backrooms_vr_7.png-6349183f10a2172a16f16a287d42d208.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_8.png b/maps/backrooms/model/backrooms_vr_8.png similarity index 100% rename from models/backrooms/backrooms_vr_8.png rename to maps/backrooms/model/backrooms_vr_8.png diff --git a/models/backrooms/backrooms_vr_8.png.import b/maps/backrooms/model/backrooms_vr_8.png.import similarity index 76% rename from models/backrooms/backrooms_vr_8.png.import rename to maps/backrooms/model/backrooms_vr_8.png.import index 2457453..291edba 100644 --- a/models/backrooms/backrooms_vr_8.png.import +++ b/maps/backrooms/model/backrooms_vr_8.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://dsjo2hg0a0tel" -path.s3tc="res://.godot/imported/backrooms_vr_8.png-d336a3b519d985285c5ac1f5b88e7302.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_8.png-8b4d0917952d2be94fc1f557297f0e1b.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_8.png" -dest_files=["res://.godot/imported/backrooms_vr_8.png-d336a3b519d985285c5ac1f5b88e7302.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_8.png" +dest_files=["res://.godot/imported/backrooms_vr_8.png-8b4d0917952d2be94fc1f557297f0e1b.s3tc.ctex"] [params] diff --git a/models/backrooms/backrooms_vr_9.png b/maps/backrooms/model/backrooms_vr_9.png similarity index 100% rename from models/backrooms/backrooms_vr_9.png rename to maps/backrooms/model/backrooms_vr_9.png diff --git a/models/backrooms/backrooms_vr_9.png.import b/maps/backrooms/model/backrooms_vr_9.png.import similarity index 76% rename from models/backrooms/backrooms_vr_9.png.import rename to maps/backrooms/model/backrooms_vr_9.png.import index 98ccc11..e944ecb 100644 --- a/models/backrooms/backrooms_vr_9.png.import +++ b/maps/backrooms/model/backrooms_vr_9.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://lg637sqtxhyx" -path.s3tc="res://.godot/imported/backrooms_vr_9.png-84b2fc2b5b2304a3aaac1bf9ef43ec9b.s3tc.ctex" +path.s3tc="res://.godot/imported/backrooms_vr_9.png-b548090fbf6542758b82625ab5195ef5.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/backrooms/backrooms_vr_9.png" -dest_files=["res://.godot/imported/backrooms_vr_9.png-84b2fc2b5b2304a3aaac1bf9ef43ec9b.s3tc.ctex"] +source_file="res://maps/backrooms/model/backrooms_vr_9.png" +dest_files=["res://.godot/imported/backrooms_vr_9.png-b548090fbf6542758b82625ab5195ef5.s3tc.ctex"] [params] diff --git a/World/Hub/hub.gd b/maps/hub/hub.gd similarity index 92% rename from World/Hub/hub.gd rename to maps/hub/hub.gd index ab50ee7..4d8ec76 100644 --- a/World/Hub/hub.gd +++ b/maps/hub/hub.gd @@ -4,8 +4,8 @@ extends Node3D # Чтобы добавить карту — допиши запись в 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)}, + {"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 @@ -76,7 +76,7 @@ func _add_box(body: StaticBody3D, size: Vector3, pos: Vector3, mat: Material) -> # Порталы вдоль северной стены лицом в комнату, по центру func _build_portals() -> void: - var portal_script := load("res://World/portal.gd") + 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] diff --git a/World/Hub/hub.gd.uid b/maps/hub/hub.gd.uid similarity index 100% rename from World/Hub/hub.gd.uid rename to maps/hub/hub.gd.uid diff --git a/World/Hub/hub.tscn b/maps/hub/hub.tscn similarity index 71% rename from World/Hub/hub.tscn rename to maps/hub/hub.tscn index 9da40b4..e4390ca 100644 --- a/World/Hub/hub.tscn +++ b/maps/hub/hub.tscn @@ -1,7 +1,7 @@ [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"] +[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") diff --git a/World/tron_01.ogg b/maps/sandbox/audio/tron_01.ogg similarity index 100% rename from World/tron_01.ogg rename to maps/sandbox/audio/tron_01.ogg diff --git a/maps/sandbox/audio/tron_01.ogg.import b/maps/sandbox/audio/tron_01.ogg.import new file mode 100644 index 0000000..9450c01 --- /dev/null +++ b/maps/sandbox/audio/tron_01.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://ddsynauqeoppw" +path="res://.godot/imported/tron_01.ogg-e0fa4b053d4048643e525d26032ad38e.oggvorbisstr" + +[deps] + +source_file="res://maps/sandbox/audio/tron_01.ogg" +dest_files=["res://.godot/imported/tron_01.ogg-e0fa4b053d4048643e525d26032ad38e.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/World/birds.gd b/maps/sandbox/birds.gd similarity index 100% rename from World/birds.gd rename to maps/sandbox/birds.gd diff --git a/World/birds.gd.uid b/maps/sandbox/birds.gd.uid similarity index 100% rename from World/birds.gd.uid rename to maps/sandbox/birds.gd.uid diff --git a/World/Floor/main_floor/Floor.glb b/maps/sandbox/floor/Floor.glb similarity index 100% rename from World/Floor/main_floor/Floor.glb rename to maps/sandbox/floor/Floor.glb diff --git a/World/Floor/main_floor/Floor.glb.import b/maps/sandbox/floor/Floor.glb.import similarity index 81% rename from World/Floor/main_floor/Floor.glb.import rename to maps/sandbox/floor/Floor.glb.import index 5b2edb9..846444f 100644 --- a/World/Floor/main_floor/Floor.glb.import +++ b/maps/sandbox/floor/Floor.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://cvrj2ay2fq4x8" -path="res://.godot/imported/Floor.glb-40cfa4cba9194cac4f12dba26232903b.scn" +path="res://.godot/imported/Floor.glb-4d6193c3b6fd9b68511a715ce5a0aefb.scn" [deps] -source_file="res://World/Floor/main_floor/Floor.glb" -dest_files=["res://.godot/imported/Floor.glb-40cfa4cba9194cac4f12dba26232903b.scn"] +source_file="res://maps/sandbox/floor/Floor.glb" +dest_files=["res://.godot/imported/Floor.glb-4d6193c3b6fd9b68511a715ce5a0aefb.scn"] [params] diff --git a/World/Floor/main_floor/Floor_Вставленное изображение.png b/maps/sandbox/floor/Floor_Вставленное изображение.png similarity index 100% rename from World/Floor/main_floor/Floor_Вставленное изображение.png rename to maps/sandbox/floor/Floor_Вставленное изображение.png diff --git a/World/Floor/main_floor/Floor_Вставленное изображение.png.import b/maps/sandbox/floor/Floor_Вставленное изображение.png.import similarity index 81% rename from World/Floor/main_floor/Floor_Вставленное изображение.png.import rename to maps/sandbox/floor/Floor_Вставленное изображение.png.import index 11751ed..b8c6d3b 100644 --- a/World/Floor/main_floor/Floor_Вставленное изображение.png.import +++ b/maps/sandbox/floor/Floor_Вставленное изображение.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://b882qi7w2eavh" -path.s3tc="res://.godot/imported/Floor_Вставленное изображение.png-ff0a799dad6a9da0f6663bac92570f5c.s3tc.ctex" +path.s3tc="res://.godot/imported/Floor_Вставленное изображение.png-91526e6b18f388bd08e95ab0add9fc52.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://World/Floor/main_floor/Floor_Вставленное изображение.png" -dest_files=["res://.godot/imported/Floor_Вставленное изображение.png-ff0a799dad6a9da0f6663bac92570f5c.s3tc.ctex"] +source_file="res://maps/sandbox/floor/Floor_Вставленное изображение.png" +dest_files=["res://.godot/imported/Floor_Вставленное изображение.png-91526e6b18f388bd08e95ab0add9fc52.s3tc.ctex"] [params] diff --git a/World/forest.gd b/maps/sandbox/forest.gd similarity index 100% rename from World/forest.gd rename to maps/sandbox/forest.gd diff --git a/World/forest.gd.uid b/maps/sandbox/forest.gd.uid similarity index 100% rename from World/forest.gd.uid rename to maps/sandbox/forest.gd.uid diff --git a/World/levitate.gd b/maps/sandbox/levitate.gd similarity index 100% rename from World/levitate.gd rename to maps/sandbox/levitate.gd diff --git a/World/levitate.gd.uid b/maps/sandbox/levitate.gd.uid similarity index 100% rename from World/levitate.gd.uid rename to maps/sandbox/levitate.gd.uid diff --git a/models/building_02.glb b/maps/sandbox/models/building_02.glb similarity index 100% rename from models/building_02.glb rename to maps/sandbox/models/building_02.glb diff --git a/models/building_02.glb.import b/maps/sandbox/models/building_02.glb.import similarity index 80% rename from models/building_02.glb.import rename to maps/sandbox/models/building_02.glb.import index 224dcce..44e7704 100644 --- a/models/building_02.glb.import +++ b/maps/sandbox/models/building_02.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://d4evo4b0wv23h" -path="res://.godot/imported/building_02.glb-cb716a43bf2c47a83086e2a15b4e29f9.scn" +path="res://.godot/imported/building_02.glb-7683ad03a325df125ca30c299b7738c4.scn" [deps] -source_file="res://models/building_02.glb" -dest_files=["res://.godot/imported/building_02.glb-cb716a43bf2c47a83086e2a15b4e29f9.scn"] +source_file="res://maps/sandbox/models/building_02.glb" +dest_files=["res://.godot/imported/building_02.glb-7683ad03a325df125ca30c299b7738c4.scn"] [params] diff --git a/models/cyber-office/cyber_office.glb b/maps/sandbox/models/cyber_office/cyber_office.glb similarity index 100% rename from models/cyber-office/cyber_office.glb rename to maps/sandbox/models/cyber_office/cyber_office.glb diff --git a/models/cyber-office/cyber_office.glb.import b/maps/sandbox/models/cyber_office/cyber_office.glb.import similarity index 79% rename from models/cyber-office/cyber_office.glb.import rename to maps/sandbox/models/cyber_office/cyber_office.glb.import index 57c86ae..eb9f7f7 100644 --- a/models/cyber-office/cyber_office.glb.import +++ b/maps/sandbox/models/cyber_office/cyber_office.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://c7tg5v5vpe77k" -path="res://.godot/imported/cyber_office.glb-8c2f33dee32abaffbec5545a7a896ce8.scn" +path="res://.godot/imported/cyber_office.glb-4e9e397c287323dff6881877bf6113c5.scn" [deps] -source_file="res://models/cyber-office/cyber_office.glb" -dest_files=["res://.godot/imported/cyber_office.glb-8c2f33dee32abaffbec5545a7a896ce8.scn"] +source_file="res://maps/sandbox/models/cyber_office/cyber_office.glb" +dest_files=["res://.godot/imported/cyber_office.glb-4e9e397c287323dff6881877bf6113c5.scn"] [params] diff --git a/models/empire-state/Empire-State.glb b/maps/sandbox/models/empire_state/Empire-State.glb similarity index 100% rename from models/empire-state/Empire-State.glb rename to maps/sandbox/models/empire_state/Empire-State.glb diff --git a/models/empire-state/Empire-State.glb.import b/maps/sandbox/models/empire_state/Empire-State.glb.import similarity index 79% rename from models/empire-state/Empire-State.glb.import rename to maps/sandbox/models/empire_state/Empire-State.glb.import index 9d57c6d..8c3aa43 100644 --- a/models/empire-state/Empire-State.glb.import +++ b/maps/sandbox/models/empire_state/Empire-State.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://bmprcwbt78ghq" -path="res://.godot/imported/Empire-State.glb-002ffdecb6a5de08ece052f50b8646a7.scn" +path="res://.godot/imported/Empire-State.glb-1ba5256795481fde942d050aee006b20.scn" [deps] -source_file="res://models/empire-state/Empire-State.glb" -dest_files=["res://.godot/imported/Empire-State.glb-002ffdecb6a5de08ece052f50b8646a7.scn"] +source_file="res://maps/sandbox/models/empire_state/Empire-State.glb" +dest_files=["res://.godot/imported/Empire-State.glb-1ba5256795481fde942d050aee006b20.scn"] [params] diff --git a/models/house_02/house_02-col.glb b/maps/sandbox/models/house_02/house_02-col.glb similarity index 100% rename from models/house_02/house_02-col.glb rename to maps/sandbox/models/house_02/house_02-col.glb diff --git a/models/house_02/house_02-col.glb.import b/maps/sandbox/models/house_02/house_02-col.glb.import similarity index 79% rename from models/house_02/house_02-col.glb.import rename to maps/sandbox/models/house_02/house_02-col.glb.import index d0785d0..d01fdb7 100644 --- a/models/house_02/house_02-col.glb.import +++ b/maps/sandbox/models/house_02/house_02-col.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://dr2udwp3pu8g1" -path="res://.godot/imported/house_02-col.glb-17408b57ee4b7d0e0d0a0da0d4e0dd93.scn" +path="res://.godot/imported/house_02-col.glb-2730eb4dc06c6be90d365a835430b326.scn" [deps] -source_file="res://models/house_02/house_02-col.glb" -dest_files=["res://.godot/imported/house_02-col.glb-17408b57ee4b7d0e0d0a0da0d4e0dd93.scn"] +source_file="res://maps/sandbox/models/house_02/house_02-col.glb" +dest_files=["res://.godot/imported/house_02-col.glb-2730eb4dc06c6be90d365a835430b326.scn"] [params] diff --git a/models/house_02/house_02-col_бревно.webp b/maps/sandbox/models/house_02/house_02-col_бревно.webp similarity index 100% rename from models/house_02/house_02-col_бревно.webp rename to maps/sandbox/models/house_02/house_02-col_бревно.webp diff --git a/models/house_02/house_02-col_бревно.webp.import b/maps/sandbox/models/house_02/house_02-col_бревно.webp.import similarity index 84% rename from models/house_02/house_02-col_бревно.webp.import rename to maps/sandbox/models/house_02/house_02-col_бревно.webp.import index efb716b..fc101c5 100644 --- a/models/house_02/house_02-col_бревно.webp.import +++ b/maps/sandbox/models/house_02/house_02-col_бревно.webp.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://rwgorah4jgx1" -path.s3tc="res://.godot/imported/house_02-col_бревно.webp-e8a6b0a715c9a02ca83340de3c6ce4b6.s3tc.ctex" +path.s3tc="res://.godot/imported/house_02-col_бревно.webp-0af3ef7ea172ac797ba1d04b51a2b9d0.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/house_02/house_02-col_бревно.webp" -dest_files=["res://.godot/imported/house_02-col_бревно.webp-e8a6b0a715c9a02ca83340de3c6ce4b6.s3tc.ctex"] +source_file="res://maps/sandbox/models/house_02/house_02-col_бревно.webp" +dest_files=["res://.godot/imported/house_02-col_бревно.webp-0af3ef7ea172ac797ba1d04b51a2b9d0.s3tc.ctex"] [params] diff --git a/models/house_02/house_02-col_булыжник.jpg b/maps/sandbox/models/house_02/house_02-col_булыжник.jpg similarity index 100% rename from models/house_02/house_02-col_булыжник.jpg rename to maps/sandbox/models/house_02/house_02-col_булыжник.jpg diff --git a/models/house_02/house_02-col_булыжник.jpg.import b/maps/sandbox/models/house_02/house_02-col_булыжник.jpg.import similarity index 84% rename from models/house_02/house_02-col_булыжник.jpg.import rename to maps/sandbox/models/house_02/house_02-col_булыжник.jpg.import index 4fd71b4..fece47c 100644 --- a/models/house_02/house_02-col_булыжник.jpg.import +++ b/maps/sandbox/models/house_02/house_02-col_булыжник.jpg.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://e2e5vo80xstq" -path.s3tc="res://.godot/imported/house_02-col_булыжник.jpg-9b1ccd0008b1bd0c163d5f93a1e31228.s3tc.ctex" +path.s3tc="res://.godot/imported/house_02-col_булыжник.jpg-93c44c998d0f4037569be1a6e8303832.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/house_02/house_02-col_булыжник.jpg" -dest_files=["res://.godot/imported/house_02-col_булыжник.jpg-9b1ccd0008b1bd0c163d5f93a1e31228.s3tc.ctex"] +source_file="res://maps/sandbox/models/house_02/house_02-col_булыжник.jpg" +dest_files=["res://.godot/imported/house_02-col_булыжник.jpg-93c44c998d0f4037569be1a6e8303832.s3tc.ctex"] [params] diff --git a/models/house_02/house_02-col_доски.png b/maps/sandbox/models/house_02/house_02-col_доски.png similarity index 100% rename from models/house_02/house_02-col_доски.png rename to maps/sandbox/models/house_02/house_02-col_доски.png diff --git a/models/house_02/house_02-col_доски.png.import b/maps/sandbox/models/house_02/house_02-col_доски.png.import similarity index 74% rename from models/house_02/house_02-col_доски.png.import rename to maps/sandbox/models/house_02/house_02-col_доски.png.import index a59bc3e..8b75086 100644 --- a/models/house_02/house_02-col_доски.png.import +++ b/maps/sandbox/models/house_02/house_02-col_доски.png.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://b3my1h6q7jfwn" -path.s3tc="res://.godot/imported/house_02-col_доски.png-c72fe1bbc031cea57d00bb33d2692581.s3tc.ctex" +path.s3tc="res://.godot/imported/house_02-col_доски.png-baea634ed5ee5838c4787b8bd0e58f80.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -14,8 +14,8 @@ generator_parameters={ [deps] -source_file="res://models/house_02/house_02-col_доски.png" -dest_files=["res://.godot/imported/house_02-col_доски.png-c72fe1bbc031cea57d00bb33d2692581.s3tc.ctex"] +source_file="res://maps/sandbox/models/house_02/house_02-col_доски.png" +dest_files=["res://.godot/imported/house_02-col_доски.png-baea634ed5ee5838c4787b8bd0e58f80.s3tc.ctex"] [params] diff --git a/models/obelisk_01/Obelisk.glb b/maps/sandbox/models/obelisk_01/Obelisk.glb similarity index 100% rename from models/obelisk_01/Obelisk.glb rename to maps/sandbox/models/obelisk_01/Obelisk.glb diff --git a/models/obelisk_01/Obelisk.glb.import b/maps/sandbox/models/obelisk_01/Obelisk.glb.import similarity index 80% rename from models/obelisk_01/Obelisk.glb.import rename to maps/sandbox/models/obelisk_01/Obelisk.glb.import index 268d5d3..a80bdfa 100644 --- a/models/obelisk_01/Obelisk.glb.import +++ b/maps/sandbox/models/obelisk_01/Obelisk.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://evml2s8rmerw" -path="res://.godot/imported/Obelisk.glb-b126e127b41aeb8aa6446e2e9706dd2f.scn" +path="res://.godot/imported/Obelisk.glb-05c41c7cffd184a06825322551c2ab18.scn" [deps] -source_file="res://models/obelisk_01/Obelisk.glb" -dest_files=["res://.godot/imported/Obelisk.glb-b126e127b41aeb8aa6446e2e9706dd2f.scn"] +source_file="res://maps/sandbox/models/obelisk_01/Obelisk.glb" +dest_files=["res://.godot/imported/Obelisk.glb-05c41c7cffd184a06825322551c2ab18.scn"] [params] diff --git a/models/tower_01/Tower_01.glb b/maps/sandbox/models/tower_01/Tower_01.glb similarity index 100% rename from models/tower_01/Tower_01.glb rename to maps/sandbox/models/tower_01/Tower_01.glb diff --git a/models/tower_01/Tower_01.glb.import b/maps/sandbox/models/tower_01/Tower_01.glb.import similarity index 80% rename from models/tower_01/Tower_01.glb.import rename to maps/sandbox/models/tower_01/Tower_01.glb.import index 18d0aab..c05b8e9 100644 --- a/models/tower_01/Tower_01.glb.import +++ b/maps/sandbox/models/tower_01/Tower_01.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://db05x4f444mr2" -path="res://.godot/imported/Tower_01.glb-724f563bb4f1b3ed4316e8d1441f9c1c.scn" +path="res://.godot/imported/Tower_01.glb-8a914eb64fe3506b2bab9e6cd24092c9.scn" [deps] -source_file="res://models/tower_01/Tower_01.glb" -dest_files=["res://.godot/imported/Tower_01.glb-724f563bb4f1b3ed4316e8d1441f9c1c.scn"] +source_file="res://maps/sandbox/models/tower_01/Tower_01.glb" +dest_files=["res://.godot/imported/Tower_01.glb-8a914eb64fe3506b2bab9e6cd24092c9.scn"] [params] diff --git a/models/Tree_01/Tree_01_low.glb b/maps/sandbox/models/tree_01/Tree_01_low.glb similarity index 100% rename from models/Tree_01/Tree_01_low.glb rename to maps/sandbox/models/tree_01/Tree_01_low.glb diff --git a/models/Tree_01/Tree_01_low.glb.import b/maps/sandbox/models/tree_01/Tree_01_low.glb.import similarity index 79% rename from models/Tree_01/Tree_01_low.glb.import rename to maps/sandbox/models/tree_01/Tree_01_low.glb.import index 8f0a85a..7b2eeed 100644 --- a/models/Tree_01/Tree_01_low.glb.import +++ b/maps/sandbox/models/tree_01/Tree_01_low.glb.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://b6d4btx7xn51j" -path="res://.godot/imported/Tree_01_low.glb-80917d9d74dea44cbc99751337404631.scn" +path="res://.godot/imported/Tree_01_low.glb-be77d2014f7bf6921365444dceccbcb7.scn" [deps] -source_file="res://models/Tree_01/Tree_01_low.glb" -dest_files=["res://.godot/imported/Tree_01_low.glb-80917d9d74dea44cbc99751337404631.scn"] +source_file="res://maps/sandbox/models/tree_01/Tree_01_low.glb" +dest_files=["res://.godot/imported/Tree_01_low.glb-be77d2014f7bf6921365444dceccbcb7.scn"] [params] diff --git a/World/nav-bake.gd b/maps/sandbox/nav_bake.gd similarity index 100% rename from World/nav-bake.gd rename to maps/sandbox/nav_bake.gd diff --git a/World/nav-bake.gd.uid b/maps/sandbox/nav_bake.gd.uid similarity index 100% rename from World/nav-bake.gd.uid rename to maps/sandbox/nav_bake.gd.uid diff --git a/main.tscn b/maps/sandbox/sandbox.tscn similarity index 76% rename from main.tscn rename to maps/sandbox/sandbox.tscn index 12ee0ac..d005b7d 100644 --- a/main.tscn +++ b/maps/sandbox/sandbox.tscn @@ -1,25 +1,23 @@ [gd_scene format=3 uid="uid://6vc0m7mc73f1"] -[ext_resource type="PackedScene" uid="uid://c7tg5v5vpe77k" path="res://models/cyber-office/cyber_office.glb" id="1_2cqfq"] -[ext_resource type="Texture2D" uid="uid://mdxwd8w6hbax" path="res://World/Sky/overcast_soil_puresky_2k.hdr" id="2_5vw27"] -[ext_resource type="PackedScene" uid="uid://c3efk6k8xnf57" path="res://Player/Player.tscn" id="2_h2yge"] -[ext_resource type="PackedScene" uid="uid://cvrj2ay2fq4x8" path="res://World/Floor/main_floor/Floor.glb" id="3_h2yge"] -[ext_resource type="PackedScene" uid="uid://d4evo4b0wv23h" path="res://models/building_02.glb" id="4_7mycd"] -[ext_resource type="PackedScene" uid="uid://db05x4f444mr2" path="res://models/tower_01/Tower_01.glb" id="5_272bh"] -[ext_resource type="PackedScene" uid="uid://dr2udwp3pu8g1" path="res://models/house_02/house_02-col.glb" id="6_5vw27"] -[ext_resource type="AudioStream" uid="uid://ddsynauqeoppw" path="res://World/tron_01.ogg" id="7_272bh"] -[ext_resource type="AudioStream" uid="uid://280pvcvxt2n2" path="res://models/Bochi-Rock/Guitar.ogg" id="7_dg77c"] -[ext_resource type="PackedScene" uid="uid://evml2s8rmerw" path="res://models/obelisk_01/Obelisk.glb" id="9_kek77"] -[ext_resource type="Script" uid="uid://o2kqd0cy4knr" path="res://models/Bochi-Rock/rock-follow.gd" id="10_4c57u"] -[ext_resource type="PackedScene" uid="uid://cowp33ejxcfcl" path="res://models/Bochi-Rock/Rock.glb" id="11_efxa6"] -[ext_resource type="Script" uid="uid://cx16mgkh4bldx" path="res://World/forest.gd" id="12_forest"] -[ext_resource type="PackedScene" uid="uid://b6d4btx7xn51j" path="res://models/Tree_01/Tree_01_low.glb" id="13_treelow"] -[ext_resource type="Script" uid="uid://j5ultotjrstk" path="res://World/birds.gd" id="14_birds"] -[ext_resource type="Script" uid="uid://chtck5eaaddrw" path="res://World/levitate.gd" id="15_levitate"] -[ext_resource type="PackedScene" uid="uid://bmprcwbt78ghq" path="res://models/empire-state/Empire-State.glb" id="17_yaehf"] -[ext_resource type="Script" uid="uid://c2k1kj4a2s2su" path="res://World/nav-bake.gd" id="18_navbake"] -[ext_resource type="Script" uid="uid://bu8v0ivhmnykt" path="res://World/portal.gd" id="19_portal"] -[ext_resource type="PackedScene" path="res://models/verity/verity.tscn" id="20_verity"] +[ext_resource type="PackedScene" uid="uid://c7tg5v5vpe77k" path="res://maps/sandbox/models/cyber_office/cyber_office.glb" id="1_2cqfq"] +[ext_resource type="Texture2D" uid="uid://mdxwd8w6hbax" path="res://maps/sandbox/sky/overcast_soil_puresky_2k.hdr" id="2_5vw27"] +[ext_resource type="PackedScene" uid="uid://c3efk6k8xnf57" path="res://player/player.tscn" id="2_h2yge"] +[ext_resource type="PackedScene" uid="uid://cvrj2ay2fq4x8" path="res://maps/sandbox/floor/Floor.glb" id="3_h2yge"] +[ext_resource type="PackedScene" uid="uid://d4evo4b0wv23h" path="res://maps/sandbox/models/building_02.glb" id="4_7mycd"] +[ext_resource type="PackedScene" uid="uid://db05x4f444mr2" path="res://maps/sandbox/models/tower_01/Tower_01.glb" id="5_272bh"] +[ext_resource type="PackedScene" uid="uid://dr2udwp3pu8g1" path="res://maps/sandbox/models/house_02/house_02-col.glb" id="6_5vw27"] +[ext_resource type="AudioStream" uid="uid://ddsynauqeoppw" path="res://maps/sandbox/audio/tron_01.ogg" id="7_272bh"] +[ext_resource type="PackedScene" uid="uid://evml2s8rmerw" path="res://maps/sandbox/models/obelisk_01/Obelisk.glb" id="9_kek77"] +[ext_resource type="Script" uid="uid://cx16mgkh4bldx" path="res://maps/sandbox/forest.gd" id="12_forest"] +[ext_resource type="PackedScene" uid="uid://b6d4btx7xn51j" path="res://maps/sandbox/models/tree_01/Tree_01_low.glb" id="13_treelow"] +[ext_resource type="Script" uid="uid://j5ultotjrstk" path="res://maps/sandbox/birds.gd" id="14_birds"] +[ext_resource type="Script" uid="uid://chtck5eaaddrw" path="res://maps/sandbox/levitate.gd" id="15_levitate"] +[ext_resource type="PackedScene" uid="uid://bmprcwbt78ghq" path="res://maps/sandbox/models/empire_state/Empire-State.glb" id="17_yaehf"] +[ext_resource type="Script" uid="uid://c2k1kj4a2s2su" path="res://maps/sandbox/nav_bake.gd" id="18_navbake"] +[ext_resource type="Script" uid="uid://bu8v0ivhmnykt" path="res://objects/portal.gd" id="19_portal"] +[ext_resource type="PackedScene" path="res://chasers/verity/verity.tscn" id="20_verity"] +[ext_resource type="PackedScene" path="res://chasers/rock/rock.tscn" id="21_rock"] [sub_resource type="PanoramaSkyMaterial" id="PanoramaSkyMaterial_6opy2"] panorama = ExtResource("2_5vw27") @@ -63,9 +61,8 @@ script = ExtResource("15_levitate") amplitude = 5.0 period = 8.0 -[node name="rock" type="Node3D" parent="Architecture" unique_id=1419147983] +[node name="rock" parent="Architecture" unique_id=1419147983 instance=ExtResource("21_rock")] transform = Transform3D(-0.4002386, 0, -0.916411, 0, 1, 0, 0.916411, 0, -0.4002386, 8.31884, -0.0029411316, 40.503094) -script = ExtResource("10_4c57u") sight_limited = true sight_range = 45.0 sight_fov = 130.0 @@ -73,17 +70,6 @@ hearing_radius = 8.0 lose_time = 5.0 wander_radius = 40.0 -[node name="Rock" parent="Architecture/rock" unique_id=1431376827 instance=ExtResource("11_efxa6")] - -[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="Architecture/rock/Rock" unique_id=912581689] -stream = ExtResource("7_dg77c") -autoplay = true -max_distance = 30.0 - -[node name="NavigationAgent3D" type="NavigationAgent3D" parent="Architecture/rock" unique_id=1616493785] -height = 5.0 -radius = 2.0 - [node name="cyber_office" parent="Architecture" unique_id=1003431047 instance=ExtResource("1_2cqfq")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.9035664, -0.2606399, -24.004528) @@ -140,7 +126,7 @@ exclude = Array[NodePath]([NodePath("../Architecture/rock"), NodePath("../Charac 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") target_map = "hub" -target_scene = "res://World/Hub/hub.tscn" +target_scene = "res://maps/hub/hub.tscn" title = "HUB" color = Color(0.85, 0.9, 1, 1) diff --git a/World/Sky/overcast_soil_puresky_2k.hdr b/maps/sandbox/sky/overcast_soil_puresky_2k.hdr similarity index 100% rename from World/Sky/overcast_soil_puresky_2k.hdr rename to maps/sandbox/sky/overcast_soil_puresky_2k.hdr diff --git a/World/Sky/overcast_soil_puresky_2k.hdr.import b/maps/sandbox/sky/overcast_soil_puresky_2k.hdr.import similarity index 79% rename from World/Sky/overcast_soil_puresky_2k.hdr.import rename to maps/sandbox/sky/overcast_soil_puresky_2k.hdr.import index 5be67a1..5ca1325 100644 --- a/World/Sky/overcast_soil_puresky_2k.hdr.import +++ b/maps/sandbox/sky/overcast_soil_puresky_2k.hdr.import @@ -3,7 +3,7 @@ importer="texture" type="CompressedTexture2D" uid="uid://mdxwd8w6hbax" -path.bptc="res://.godot/imported/overcast_soil_puresky_2k.hdr-feb31b3210223258f07268828ee4e20f.bptc.ctex" +path.bptc="res://.godot/imported/overcast_soil_puresky_2k.hdr-0f15fb36eb0df06b7f2c112caff7f129.bptc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true @@ -11,8 +11,8 @@ metadata={ [deps] -source_file="res://World/Sky/overcast_soil_puresky_2k.hdr" -dest_files=["res://.godot/imported/overcast_soil_puresky_2k.hdr-feb31b3210223258f07268828ee4e20f.bptc.ctex"] +source_file="res://maps/sandbox/sky/overcast_soil_puresky_2k.hdr" +dest_files=["res://.godot/imported/overcast_soil_puresky_2k.hdr-0f15fb36eb0df06b7f2c112caff7f129.bptc.ctex"] [params] diff --git a/models/Bochi-Rock/Guitar.ogg.import b/models/Bochi-Rock/Guitar.ogg.import deleted file mode 100644 index d5f424d..0000000 --- a/models/Bochi-Rock/Guitar.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://280pvcvxt2n2" -path="res://.godot/imported/Guitar.ogg-21bf9bad0fcf3bfe7341e2b1bd9308b9.oggvorbisstr" - -[deps] - -source_file="res://models/Bochi-Rock/Guitar.ogg" -dest_files=["res://.godot/imported/Guitar.ogg-21bf9bad0fcf3bfe7341e2b1bd9308b9.oggvorbisstr"] - -[params] - -loop=false -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/models/Bochi-Rock/rock-path.gd b/models/Bochi-Rock/rock-path.gd deleted file mode 100644 index 55cbe91..0000000 --- a/models/Bochi-Rock/rock-path.gd +++ /dev/null @@ -1,6 +0,0 @@ -extends PathFollow3D - -@export var speed := 7.0 # единиц пути в секунду - -func _process(delta): - progress += speed * delta diff --git a/models/Bochi-Rock/rock-path.gd.uid b/models/Bochi-Rock/rock-path.gd.uid deleted file mode 100644 index 9ab8fe7..0000000 --- a/models/Bochi-Rock/rock-path.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://b3ckck8y0rby6 diff --git a/models/Tree_01/Tree_01.glb b/models/Tree_01/Tree_01.glb deleted file mode 100644 index a5ee1cb..0000000 Binary files a/models/Tree_01/Tree_01.glb and /dev/null differ diff --git a/models/Tree_01/Tree_01.glb.import b/models/Tree_01/Tree_01.glb.import deleted file mode 100644 index d92efcc..0000000 --- a/models/Tree_01/Tree_01.glb.import +++ /dev/null @@ -1,45 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://cqfe5g5ospxic" -path="res://.godot/imported/Tree_01.glb-e3e4d95044780b930423dc5ef7307d2e.scn" - -[deps] - -source_file="res://models/Tree_01/Tree_01.glb" -dest_files=["res://.godot/imported/Tree_01.glb-e3e4d95044780b930423dc5ef7307d2e.scn"] - -[params] - -nodes/root_type="" -nodes/root_name="" -nodes/root_script=null -mesh_library/use_node_names_as_mesh_names=false -array_mesh/deduplicate_surfaces=true -nodes/apply_root_scale=true -nodes/root_scale=1.0 -nodes/import_as_skeleton_bones=false -nodes/use_name_suffixes=true -nodes/use_node_type_suffixes=true -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -animation/import_rest_as_RESET=false -import_script/path="" -materials/extract=0 -materials/extract_format=0 -materials/extract_path="" -_subresources={} -gltf/naming_version=2 -gltf/embedded_image_handling=1 -gltf/texture_map_mode=1 diff --git a/models/tower_01/Tower_01.glb.unwrap_cache b/models/tower_01/Tower_01.glb.unwrap_cache deleted file mode 100644 index 1f73ab6..0000000 Binary files a/models/tower_01/Tower_01.glb.unwrap_cache and /dev/null differ diff --git a/models/verity/verity.glb b/models/verity/verity.glb deleted file mode 100644 index 15281d4..0000000 Binary files a/models/verity/verity.glb and /dev/null differ diff --git a/models/verity/verity.glb.import b/models/verity/verity.glb.import deleted file mode 100644 index f712602..0000000 --- a/models/verity/verity.glb.import +++ /dev/null @@ -1,45 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://cn50f1trssdya" -path="res://.godot/imported/verity.glb-aae30371d8b76c9d120dd8fbd4a369c2.scn" - -[deps] - -source_file="res://models/verity/verity.glb" -dest_files=["res://.godot/imported/verity.glb-aae30371d8b76c9d120dd8fbd4a369c2.scn"] - -[params] - -nodes/root_type="" -nodes/root_name="" -nodes/root_script=null -mesh_library/use_node_names_as_mesh_names=false -array_mesh/deduplicate_surfaces=true -nodes/apply_root_scale=true -nodes/root_scale=1.0 -nodes/import_as_skeleton_bones=false -nodes/use_name_suffixes=true -nodes/use_node_type_suffixes=true -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -animation/import_rest_as_RESET=false -import_script/path="" -materials/extract=0 -materials/extract_format=0 -materials/extract_path="" -_subresources={} -gltf/naming_version=2 -gltf/embedded_image_handling=1 -gltf/texture_map_mode=1 diff --git a/models/verity/verity.ogg.import b/models/verity/verity.ogg.import deleted file mode 100644 index b2426bc..0000000 --- a/models/verity/verity.ogg.import +++ /dev/null @@ -1,19 +0,0 @@ -[remap] - -importer="oggvorbisstr" -type="AudioStreamOggVorbis" -uid="uid://b7qmenkjh1wdk" -path="res://.godot/imported/verity.ogg-c8d59770635466ff43367f93a436eb90.oggvorbisstr" - -[deps] - -source_file="res://models/verity/verity.ogg" -dest_files=["res://.godot/imported/verity.ogg-c8d59770635466ff43367f93a436eb90.oggvorbisstr"] - -[params] - -loop=true -loop_offset=0 -bpm=0 -beat_count=0 -bar_beats=4 diff --git a/models/verity/verity_unnamed.webp b/models/verity/verity_unnamed.webp deleted file mode 100644 index 7fe9047..0000000 Binary files a/models/verity/verity_unnamed.webp and /dev/null differ diff --git a/models/verity/verity_unnamed.webp.import b/models/verity/verity_unnamed.webp.import deleted file mode 100644 index 8f0abb0..0000000 --- a/models/verity/verity_unnamed.webp.import +++ /dev/null @@ -1,44 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://bxiwv7ayauag5" -path.s3tc="res://.godot/imported/verity_unnamed.webp-57398071db19959d3dcf9d9f175390fc.s3tc.ctex" -metadata={ -"imported_formats": ["s3tc_bptc"], -"vram_texture": true -} -generator_parameters={ -"md5": "5d3e31c7af9c06dc059d9fa5104b94dd" -} - -[deps] - -source_file="res://models/verity/verity_unnamed.webp" -dest_files=["res://.godot/imported/verity_unnamed.webp-57398071db19959d3dcf9d9f175390fc.s3tc.ctex"] - -[params] - -compress/mode=2 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/uastc_level=0 -compress/rdo_quality_loss=0.0 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=true -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -process/channel_remap/red=0 -process/channel_remap/green=1 -process/channel_remap/blue=2 -process/channel_remap/alpha=3 -process/fix_alpha_border=true -process/premult_alpha=false -process/normal_map_invert_y=false -process/hdr_as_srgb=false -process/hdr_clamp_exposure=false -process/size_limit=0 -detect_3d/compress_to=0 diff --git a/Net/ghost.gd b/net/ghost.gd similarity index 100% rename from Net/ghost.gd rename to net/ghost.gd diff --git a/Net/ghost.gd.uid b/net/ghost.gd.uid similarity index 100% rename from Net/ghost.gd.uid rename to net/ghost.gd.uid diff --git a/Net/net.gd b/net/net.gd similarity index 97% rename from Net/net.gd rename to net/net.gd index fed671e..5eedc6e 100644 --- a/Net/net.gd +++ b/net/net.gd @@ -40,7 +40,8 @@ var rock_owners := {} # карта -> peer_id владельца камн var rock_seen := {} # карта -> время (сек), когда владелец последний раз присылал камень func _ready() -> void: - is_server = DisplayServer.get_name() == "headless" + # Сервер — это headless-запуск; --client делает клиентом и headless (боты для тестов, tools/test) + is_server = DisplayServer.get_name() == "headless" and not OS.get_cmdline_user_args().has("--client") if is_server: _start_server() else: diff --git a/Net/net.gd.uid b/net/net.gd.uid similarity index 100% rename from Net/net.gd.uid rename to net/net.gd.uid diff --git a/Net/server.tscn b/net/server.tscn similarity index 100% rename from Net/server.tscn rename to net/server.tscn diff --git a/World/portal.gd b/objects/portal.gd similarity index 97% rename from World/portal.gd rename to objects/portal.gd index 82a8296..df104ab 100644 --- a/World/portal.gd +++ b/objects/portal.gd @@ -2,7 +2,7 @@ extends Area3D # Портал на другую карту: шаг в рамку — переход. Для сети игрок попадает в «комнату» новой карты. @export var target_map := "backrooms" -@export var target_scene := "res://World/Backrooms/backrooms.tscn" +@export var target_scene := "res://maps/backrooms/backrooms.tscn" @export var pack_name := "" # Пакет с картой (качается при первом входе); пусто — карта уже в игре @export var title := "BACKROOMS" @export var color := Color(1.0, 0.85, 0.25) diff --git a/World/portal.gd.uid b/objects/portal.gd.uid similarity index 100% rename from World/portal.gd.uid rename to objects/portal.gd.uid diff --git a/Player/character_body_3d.gd b/player/player.gd similarity index 100% rename from Player/character_body_3d.gd rename to player/player.gd diff --git a/Player/character_body_3d.gd.uid b/player/player.gd.uid similarity index 100% rename from Player/character_body_3d.gd.uid rename to player/player.gd.uid diff --git a/Player/Player.tscn b/player/player.tscn similarity index 95% rename from Player/Player.tscn rename to player/player.tscn index 8d2df9d..edb95e4 100644 --- a/Player/Player.tscn +++ b/player/player.tscn @@ -1,6 +1,6 @@ [gd_scene format=3 uid="uid://c3efk6k8xnf57"] -[ext_resource type="Script" uid="uid://c22hclit1affa" path="res://Player/character_body_3d.gd" id="1_iwpo4"] +[ext_resource type="Script" uid="uid://c22hclit1affa" path="res://player/player.gd" id="1_iwpo4"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_h8axm"] radius = 0.35205078 diff --git a/project.godot b/project.godot index 3caf891..ccfad7a 100644 --- a/project.godot +++ b/project.godot @@ -11,14 +11,14 @@ config_version=5 [application] config/name="world2" -run/main_scene="res://World/Hub/hub.tscn" +run/main_scene="res://maps/hub/hub.tscn" config/features=PackedStringArray("4.7", "GL Compatibility") config/icon="res://icon.svg" [autoload] -Net="*res://Net/net.gd" -MapLoader="*res://World/map_loader.gd" +Net="*res://net/net.gd" +MapLoader="*res://core/map_loader.gd" [display] @@ -29,35 +29,47 @@ window/stretch/aspect="expand" move_forward={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null), Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)] +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] } move_back={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null), Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)] +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] } move_left={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null), Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)] +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] } move_right={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null), Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)] +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] } jump={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)] +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] } sprint={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)] +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] } crouch={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":67,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)] +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":67,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] } dash={ "deadzone": 0.2, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)] +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] } [physics] diff --git a/tools/deploy_server.sh b/tools/deploy_server.sh new file mode 100755 index 0000000..374bd33 --- /dev/null +++ b/tools/deploy_server.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# Выкладка выделенного сервера: файлы сети + project.godot, пересборка кэша классов, перезапуск службы. +# tools/deploy_server.sh root@192.168.10.110 +# ВАЖНО: клиент и сервер обновляются вместе (RPC несовместимы между версиями) — сначала пуш grid-world, +# потом этот скрипт. Бэкап прошлой версии кладётся в /opt/backup-my-world-server-<дата>/. +set -euo pipefail +HOST="${1:?укажи user@host}" +cd "$(dirname "$0")/.." +STAMP="$(date +%Y%m%d-%H%M%S)" + +ssh "$HOST" "mkdir -p /opt/backup-my-world-server-$STAMP && cp -a /opt/my-world-server/project.godot /opt/my-world-server/Net /opt/my-world-server/net /opt/backup-my-world-server-$STAMP/ 2>/dev/null || true" +ssh "$HOST" "mkdir -p /opt/my-world-server/net" +scp -q net/net.gd net/net.gd.uid net/ghost.gd net/ghost.gd.uid net/server.tscn "$HOST:/opt/my-world-server/net/" +scp -q deploy/server/project.godot "$HOST:/opt/my-world-server/project.godot" +# Старая раскладка серверной папки (Net/ с большой буквы) больше не нужна +ssh "$HOST" "rm -rf /opt/my-world-server/Net && cd /opt/my-world-server && ./godot --headless --import --path . >/dev/null 2>&1; systemctl restart my-world && sleep 2 && systemctl is-active my-world && journalctl -u my-world -n 3 --no-pager | cut -c1-120" diff --git a/tools/export_all.sh b/tools/export_all.sh new file mode 100755 index 0000000..70cdf3f --- /dev/null +++ b/tools/export_all.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Экспорт веб-клиента и пакетов карт. По умолчанию — в ../grid-world (репозиторий сайта). +# tools/export_all.sh [папка_вывода] +# Пакеты карт (backrooms.pck, world.pck) нужно выкладывать вместе с index.* — клиент качает их при входе в портал. +set -euo pipefail +cd "$(dirname "$0")/.." +OUT="${1:-../grid-world}" +mkdir -p "$OUT" + +# Редактор кэширует зависимости сцен; у недавно изменённых сцен кэш может устареть, и в пакет +# не попадут их модели и звуки. touch заставляет пересчитать. +find maps chasers -name '*.tscn' -exec touch {} + + +godot --headless --export-release Web "$OUT/index.html" +godot --headless --export-pack Backrooms "$OUT/backrooms.pck" +godot --headless --export-pack World "$OUT/world.pck" +ls -la "$OUT"/*.pck "$OUT"/index.wasm | awk '{printf "%7.2f МБ %s\n", $5/1e6, $9}' diff --git a/tools/serve_web.py b/tools/serve_web.py new file mode 100755 index 0000000..dc42ed9 --- /dev/null +++ b/tools/serve_web.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +"""Локальный веб-сервер для проверки сборки, повторяет боевой nginx: +заголовки COOP/COEP (нужны Godot web) и gzip без Content-Length (чанками). +Так я поймал баг: браузер сам распаковывает gzip, и HTTPRequest в движке не должен делать это второй раз. + + python3 tools/serve_web.py ../grid-world 8080 # открой http://127.0.0.1:8080 +""" +import gzip, http.server, os, sys + +ROOT = sys.argv[1] if len(sys.argv) > 1 else '../grid-world' +PORT = int(sys.argv[2]) if len(sys.argv) > 2 else 8080 +CACHE = {} +TYPES = {'.wasm': 'application/wasm', '.js': 'application/javascript', '.html': 'text/html', + '.pck': 'application/octet-stream', '.png': 'image/png'} + + +class Handler(http.server.BaseHTTPRequestHandler): + protocol_version = 'HTTP/1.1' + + def do_GET(self): + path = os.path.join(ROOT, self.path.split('?')[0].lstrip('/') or 'index.html') + if not os.path.isfile(path): + self.send_response(404); self.send_header('Content-Length', '0'); self.end_headers(); return + data = open(path, 'rb').read() + self.send_response(200) + self.send_header('Content-Type', TYPES.get(os.path.splitext(path)[1], 'application/octet-stream')) + self.send_header('Cross-Origin-Opener-Policy', 'same-origin') + self.send_header('Cross-Origin-Embedder-Policy', 'require-corp') + if len(data) > 1024: + key = (path, os.path.getmtime(path)) + gz = CACHE.get(key) or CACHE.setdefault(key, gzip.compress(data, 1)) + self.send_header('Content-Encoding', 'gzip') + self.send_header('Transfer-Encoding', 'chunked') + self.end_headers() + for i in range(0, len(gz), 65536): + chunk = gz[i:i + 65536] + self.wfile.write(b'%x\r\n' % len(chunk) + chunk + b'\r\n') + self.wfile.write(b'0\r\n\r\n') + else: + self.send_header('Content-Length', str(len(data))) + self.end_headers() + self.wfile.write(data) + print('GET', self.path, flush=True) + + def log_message(self, *args): + pass + + +print(f'http://127.0.0.1:{PORT} ← {os.path.abspath(ROOT)}') +http.server.ThreadingHTTPServer(('127.0.0.1', PORT), Handler).serve_forever() diff --git a/tools/test/bot.gd b/tools/test/bot.gd new file mode 100644 index 0000000..868ad2b --- /dev/null +++ b/tools/test/bot.gd @@ -0,0 +1,43 @@ +extends Node +# Тестовый бот (автозагрузка во ВРЕМЕННОЙ копии проекта, см. tools/test/make_test_project.sh). +# Пережидает смену сцен, по расписанию телепортирует игрока и раз в секунду печатает, что видит. +# godot --headless --path <копия> res://maps/hub/hub.tscn -- --client --name=A --tp=2:-2.25,1,-7.5 --tp=9:0,1,5 +# --tp=<секунда>:,, — телепорт игрока на этой секунде (например, прямо в портал). +# Остальные аргументы пользователя (--server-url=..., --pack-url=...) читают Net и MapLoader. + +var t := 0.0 +var label := "?" +var tps := [] +var next_print := 1.0 + +func _ready() -> void: + for a in OS.get_cmdline_user_args(): + if a.begins_with("--name="): + label = a.substr(7) + if a.begins_with("--tp="): + var p := a.substr(5).split(":") + var v := p[1].split(",") + tps.append({"t": float(p[0]), "pos": Vector3(float(v[0]), float(v[1]), float(v[2])), "done": false}) + +func _process(delta: float) -> void: + t += delta + var scene := get_tree().current_scene + var player := get_tree().get_first_node_in_group("local_player") + if scene == null or player == null: + return + if not get_tree().paused: # на паузе идёт загрузка карты + for tp in tps: + if not tp.done and t >= tp.t: + tp.done = true + player.global_position = tp.pos + player.velocity = Vector3.ZERO + print("[%s] t=%.1f ТЕЛЕПОРТ %s" % [label, t, tp.pos]) + if t >= next_print: + next_print += 1.0 + var chasers := [] + for id in Net.chasers: + var c: Node3D = Net.chasers[id] + chasers.append("%s=(%.0f,%.0f)%s" % [id, c.global_position.x, c.global_position.z, "!" if c.get("_state") == 1 else ""]) + print("[%s] t=%4.1f сцена=%s карта=%s владелец=%s свой=%s призраков=%d мёртв=%s %s" % [ + label, t, scene.name, Net.current_map, Net.rock_owner, Net.rock_is_local(), + Net.ghosts.size(), player.is_dead, " ".join(chasers)]) diff --git a/tools/test/bot.gd.uid b/tools/test/bot.gd.uid new file mode 100644 index 0000000..99f177d --- /dev/null +++ b/tools/test/bot.gd.uid @@ -0,0 +1 @@ +uid://do6iy031p0j3m diff --git a/tools/test/make_test_project.sh b/tools/test/make_test_project.sh new file mode 100755 index 0000000..6142780 --- /dev/null +++ b/tools/test/make_test_project.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Делает ВРЕМЕННУЮ копию проекта с ботом-автозагрузкой для тестов без окна. +# tools/test/make_test_project.sh /tmp/test-world +# Дальше: godot --headless --path /tmp/test-world res://maps/hub/hub.tscn -- --client --name=A +# (сервер для сетевых тестов — отдельный headless-запуск папки из tools/test/make_test_server.sh) +set -euo pipefail +SRC="$(cd "$(dirname "$0")/../.." && pwd)" +DST="${1:?укажи папку}" +mkdir -p "$DST" +rsync -a --exclude .git --exclude deploy "$SRC/" "$DST/" +sed -i 's#^MapLoader="\*res://core/map_loader.gd"#MapLoader="*res://core/map_loader.gd"\nBot="*res://tools/test/bot.gd"#' "$DST/project.godot" +# В боевом экспорте tools/* исключён; в тестовой копии бот должен попасть в пакет +sed -i 's#exclude_filter="tools/\*, #exclude_filter="#' "$DST/export_presets.cfg" +echo "готово: $DST" diff --git a/tools/test/make_test_server.sh b/tools/test/make_test_server.sh new file mode 100755 index 0000000..b77c51d --- /dev/null +++ b/tools/test/make_test_server.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# Локальный выделенный сервер для сетевых тестов (та же структура, что на боевом сервере). +# tools/test/make_test_server.sh /tmp/test-server && godot --headless --path /tmp/test-server +set -euo pipefail +SRC="$(cd "$(dirname "$0")/../.." && pwd)" +DST="${1:?укажи папку}" +mkdir -p "$DST/net" +cp "$SRC/deploy/server/project.godot" "$DST/project.godot" +cp "$SRC/net/net.gd" "$SRC/net/net.gd.uid" "$SRC/net/ghost.gd" "$SRC/net/ghost.gd.uid" "$SRC/net/server.tscn" "$DST/net/" +(cd "$DST" && godot --headless --import --path . >/dev/null 2>&1) # кэш классов (class_name Ghost) +echo "готово: $DST"