FiveM жилая система и апартаменты: shells, instances, stashes и ключи

Как работает жилая система в FiveM: оболочки и MLO интерьеры, инстансирование с routing buckets, storage для каждого дома, ключи и доступ, сохранение владения в базе данных.

Симптом: два игрока входят в два разных апартамента и видят друг друга, storage разделён между всеми домами, или владение теряется при перезагрузке сервера.

Жилая система — это четыре вещи, работающие вместе: интерьер, способ разделения игроков, место для хранения предметов и запись о том, кто может входить. В этой статье объясняется каждая часть и как они взаимодействуют.

Shell или MLO интерьер

У вас есть два способа создать интерьер дома:

Тип Как это работает Подходит для
Shell Пропс, спаунящийся в координатах, удаляется при выходе Апартаменты, много идентичных домов
MLO Постоянный интерьер на карте Уникальные дома и особняки

Shell — это модель, которую вы загружаете, размещаете в фиксированном месте (часто высоко в небе или далеко, под картой) и удаляете когда игрок выходит. Поскольку один и тот же shell может быть спаунят для любого количества домов, shells используются для жилых зданий. MLO остаётся на карте, поэтому он ограничен одним местом. Чтобы установить его, смотрите установка MLO, и если он нарушит карту вокруг него, конфликты MLO.

Инстансирование с routing buckets

Если каждый апартамент использует один и тот же shell на одних и тех же координатах, то все, кто входит, стоят в одной комнате. Решение — дать каждому дому свой routing bucket, изолированную копию мира на сервере. Игроки в разных buckets не видят друг друга и друг друга сущностей. Суть в одном предложении: дом номер 12 использует bucket 12 (плюс смещение, чтобы он никогда не совпадал с другими использованиями).

lua
-- server
local HOUSE_BUCKET_OFFSET = 1000

RegisterNetEvent('housing:enter', function(houseId)
    local src = source
    if not canEnter(src, houseId) then return end   -- ownership or key check

    SetPlayerRoutingBucket(src, HOUSE_BUCKET_OFFSET + houseId)
    TriggerClientEvent('housing:spawnShell', src, houseId)
end)

RegisterNetEvent('housing:leave', function()
    local src = source
    SetPlayerRoutingBucket(src, 0)
    TriggerClientEvent('housing:removeShell', src)
end)

Каждый, кто посещает этот дом, должен быть помещён в один bucket, и каждый выход должен установить bucket обратно в 0. Обработайте также отключения и перезагрузки скриптов, чтобы ни один игрок не остался в bucket, который больше никто не может достичь. Все native функции объяснены в routing buckets.

Совет: если вы спаунят shell пропс на клиенте, только этот игрок его видит. Для shell, который видят и посетители, каждый посетитель спаунят его для себя, или сервер создаёт его в одном bucket.

Storage для каждого дома

Каждому дому нужно своё хранилище. С ox_inventory зарегистрируйте stash для каждого дома с идентификатором, который включает id дома:

lua
-- server
exports.ox_inventory:RegisterStash('house_' .. houseId, 'House storage', 50, 100000, ownerId)

Затем откройте его с тем же идентификатором на клиенте:

lua
exports.ox_inventory:openInventory('stash', 'house_' .. houseId)

Если идентификатор одинаков для всех домов, все дома будут разделять один stash, что является симптомом из начала статьи. Добавьте проверку разрешения на сервере перед открытием stash, и смотрите ox_inventory stashes для информации о слотах, весе и кто может открыть один.

Ключи и доступ

Владение — не единственный способ входа. Планируйте эти случаи:

  • Владелец: всегда входит, может продать дом и выдать ключи.
  • Владельцы ключей: друзья или арендаторы, которые могут входить и использовать storage, но не могут продать.
  • Гости: посещают когда владелец внутри и разрешает им войти (звонок в дверь).
  • Полиция: рейд или официальный вход, если ваш сервер это имеет.

Храните ключи как данные, а не как предмет, который можно выбросить: список идентификаторов персонажей на дом. Проверяйте список на сервере каждый раз, когда кто-то пытается войти или открыть storage.

Сохранение владения в базе данных

Всё, что должно пережить перезагрузку, должно быть в базе данных. Простая структура — одна таблица для домов и одна для ключей:

sql
CREATE TABLE IF NOT EXISTS houses (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(64) NOT NULL,
  owner VARCHAR(64) DEFAULT NULL,
  price INT NOT NULL DEFAULT 0
);

CREATE TABLE IF NOT EXISTS house_keys (
  house_id INT NOT NULL,
  holder VARCHAR(64) NOT NULL,
  PRIMARY KEY (house_id, holder)
);

Храните идентификатор персонажа, который использует ваш фреймворк для персонажей (например идентификатор персонажа, а не лицензию игрока), чтобы владение следовало персонажу. Загружайте данные при запуске ресурса и храните копию в таблице сервера для быстрых проверок, записывая обратно в базу данных при каждом изменении. Запросы из Lua находятся в oxmysql запросы.

Потоки денег тоже имеют значение: покупка, аренда и возврат при продаже должны обрабатываться на сервере, и они действуют как сток денег, как описано в балансировка экономики сервера.

Распространённые ошибки

  • Неправильный сброс bucket при выходе, смерти, отключении или перезагрузке.
  • Один и тот же stash id для всех домов.
  • Проверка владения только на клиенте.
  • Владение хранится только в памяти и теряется при перезагрузке.
  • Спаун shell больше одного раза когда игрок быстро входит снова, оставляя дубликаты пропсов.

Контрольный список

Симптом Решение
Игроки в разных домах видят друг друга Дайте каждому дому свой routing bucket
Игрок застрял в пустом мире Сбросьте bucket в 0 при выходе, смерти и отключении
Все дома разделяют один stash Используйте stash id, который включает id дома
Владение теряется при перезагрузке Сохраняйте его в базе данных
Кто угодно может входить Проверьте владение или ключ на сервере
Дубликаты shell пропсов Удалите shell при выходе и защитите от двойного спауна

Короткие ответы

В чём разница между shell и MLO интерьером?

MLO — это реальный интерьер, расположенный на карте в фиксированных координатах. Shell — это пропс, который вы спаунятся по требованию, обычно далеко от карты, и удаляется когда игрок выходит.

Почему игроки видят дома друг друга?

Каждый дом использует одни и те же координаты, поэтому игроки в разных домах находятся в одном пространстве. Поместите каждый дом в свой routing bucket, чтобы они были разделены.

Где должны быть сохранены данные владения домом?

В базе данных с идентификатором дома и идентификатором персонажа владельца, плюс отдельная таблица или колонка для людей, у которых есть ключи. Никогда не храните владение только в памяти.

Скрипты без этой проблемы

CCTV Security CamerasУстанавливаемые камеры, планшет с мультиэкраном в реальном времени и распечатанные фото-улики.Смотреть скрипт →Shop CreatorМагазин меньше чем за минуту — владельцы, сотрудники, сейфы и ограбления в комплекте.Смотреть скрипт →Item Creator V2Создавайте используемые предметы с анимациями, пропами, эффектами и не только — без кода.Смотреть скрипт →

Читайте также

FiveMLuaСценарииFiveM механик работа: repair natives, tuning модификации и проверки работыПостройте FiveM механик работу: отремонтируйте машину с SetVehicleFixed и health natives, настройте с SetVehicleModKit и SetVehicleMod, сохраните модификации, и заблокируйте действия по работе.1 октября 2026 г. · 2 мин чтенияЧитать →FiveMБаза данныхСерверFiveM сервер экономика баланс: зарплаты, денежные стоки и инфляцияКак сбалансировать FiveM сервер экономику: зарплаты, начальные деньги, цены, денежные стоки как ремонты, топливо, налоги и жилищное хозяйство, чёрные деньги, и SQL чтобы смотреть инфляцию.1 октября 2026 г. · 3 мин чтенияЧитать →FiveMБезопасностьСценарииFiveM магазин и банк грабёж скрипты: setup и разработка на сервереКак установить и дизайнировать магазин и банк грабежи на FiveM: количество полиции, server-side cooldowns, награды даны только сервером, оповещения полиции и проверки расстояния.1 октября 2026 г. · 3 мин чтенияЧитать →