Skip to content
E
Egmatic
браузерные игрысохранения в игреlocalStorageIndexedDBигры без бэкендаинди-разработка

Где браузерные игры хранят сохранения без сервера?

Браузерная игра хранит сохранения в localStorage и IndexedDB — на устройстве игрока, в одном браузере. Разбираем квоты, удаление данных и грабли движков.

Vladislav Kovnerov25 сентября 2026 г.17 мин

Браузерная игра хранит данные внутри самого браузера. Почти каждая веб-игра держится на двух механизмах: localStorage — небольшое хранилище пар ключ-значение на сайт — и IndexedDB, куда более крупная база данных, которой управляет браузер на устройстве игрока. Сервер не получает ничего. Сохранение переживает перезапуски и работает офлайн, но принадлежит одному браузеру на одной машине, и браузер оставляет за собой право его удалить. Всё остальное в статье — следствия этих трёх свойств: где данные физически лежат, сколько влезает и что заставляет их исчезнуть.

Тема постоянно всплывает в читках сообществ, которые мы проводим, и в двух видах. Игроки спрашивают, как игра во вкладке вообще что-то помнит между сессиями. Разработчики — куда уходят сохранения, если они не написали ни строчки кода хранилища, и почему сохранение, работавшее во вторник, к пятнице исчезает. Когда в этом месяце однофайловое демо-приложение, держащее все данные в SQLite, собрало сотни голосов на Hacker News, обсуждение под ним было ровно об этом: сколько веб-страница может надёжно помнить без бэкенда. Честная оговорка сразу: этот блог принадлежит Egmatic, no-code-редактору двухмерных игр в пре-альфе, и при чём тут сохранения — ближе к концу.

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

Ваш вопросЕсли коротко
Где сохранение физически живёт?На устройстве игрока, в хранилище, которое браузер выделяет каждому сайту
Какой механизм использует веб-игра?localStorage для нескольких мегабайт настроек; IndexedDB для всего, что крупнее
Сохранение переживает перезапуск?Да, пока игрок не очистит данные сайта или браузер их не выселит
Сохранение следует за игроком на другое устройство?Нет. Один профиль браузера на одной машине — и всё
Какой риск самый незаметный?Safari удаляет доступное скриптам хранилище сайта после семи дней без взаимодействия с ним

Если вы здесь из-за пропавшего сохранения: оно всё ещё на машине, в том профиле браузера, где появилось, — если только данные сайта не чистили и игра не запускалась в приватном окне. Если вы делаете веб-игру или играбельное демо: ниже вся карта территории — от квот по браузерам до того, как Godot, Unity и Construct подключают свои системы сохранений к хранилищам браузера, и до плана, который убережёт от этих сюрпризов на неделе запуска. Хостинг самой сборки — отдельный вопрос, разобранный в статье о том, как разместить веб-демо игры.

Хранилище, которое браузер даёт каждой странице

Браузер выделяет каждому сайту отдельное приватное хранилище, привязанное к origin — источнику страницы, комбинации протокола и домена, с которой она загружена. Из этого следуют два факта. Одна и та же игра, отданная с двух разных адресов, получает два разных хранилища сохранений. И хранилище игры невидимо для всех остальных сайтов — поэтому одна страница не может прочитать сохранения другой.

Внутри этого хранилища важны три механизма.

localStorage — простое хранилище строковых ключей и значений. Оно синхронное: чтение и запись завершаются до следующей строки кода, что удобно — и чем легко злоупотребить: крупная запись в главном потоке подвешивает игру. Места — несколько мегабайт на сайт. Для настроек, разблокировок, лучшего результата или компактного блока сохранения этого хватает, и веб-игры используют его именно так со времён стандартизации.

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

IndexedDB — настоящая база данных: асинхронная, с индексами, умеющая держать структурированные записи и бинарные блобы, и ей достаётся куда большая доля устройства, чем localStorage. Сюда движки складывают файловые системы, и сюда попадает каждое сохранение тяжелее настроек. Асинхронность означает, что запись не блокирует кадр, — ценой танца с колбэками, который каждый движок уже давно завернул за вас.

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

Сколько влезает: квоты по браузерам

Квоты IndexedDB велики и у каждого браузера свои. Опорные числа — из документации web.dev:

БраузерКвота IndexedDBПримечания
Chrome и Chromiumorigin может использовать до 60% всего дискаСам браузер ограничен 80%; инкогнито-окна с очисткой при закрытии получают примерно 300 МБ
FirefoxБраузер может занять до 50% свободного места дискаГруппа сайтов (домен вместе с поддоменами) ограничена примерно 2 ГБ
SafariНа практике около 1 ГБОфициально опубликованной квоты нет; игроку показывают запросы шагами по 200 МБ при приближении к лимиту

localStorage в любом браузере — маленький сосед: единицы мегабайт на сайт и только строки. Для сохранения в виде JSON-блока состояния этого обычно хватает. Для скриншотов, реплеев, наборов уровней или многолетней истории инкременталки — нет, и правильный ответ здесь — IndexedDB с самого начала, а не localStorage плюс хак со сжатием.

Код может спросить у браузера, сколько места осталось: интерфейс StorageManager даёт оценку использования и квоты. Это оценки, а не обещания — в целом точное описание браузерных хранилищ.

Когда браузер выбрасывает сохранения

Хранилище браузера по умолчанию best-effort: браузер старается удержать данные, но не обещает этого, и при нехватке места на устройстве может удалить данные сайта. Документированный порядок выселения в Chromium безжалостен: первым уходит origin, не использовавшийся дольше всех, за ним следующий — пока давление не спадёт. Игрок, не открывавший вашу игру месяцами, по этому правилу — первый кандидат на выселение.

Четыре режима отказа объясняют большинство потерянных сохранений:

  1. Очистка данных сайта. Кнопка удаления cookies и данных сайта сносит localStorage и IndexedDB разом. Игроки с чистильщиками сталкиваются с этим регулярно.
  2. Приватные окна. Инкогнито и приватный режим выбрасывают всё хранилище при закрытии окна. Документация Godot говорит прямо: приватный просмотр отменяет персистентность.
  3. Выселение хранилища. Нехватка места плюс статус best-effort — и данные удалены, хотя никто не решал их удалять. Сайт может запросить постоянное хранилище: persist() просит браузер сохранить данные сайта и чистить best-effort-сайты первыми. Если ваш движок или шаблон выставляет этот переключатель, а в игре настоящие сохранения — включите.
  4. Семидневный лимит Safari. Safari удаляет всё доступное скриптам хранилище сайта, включая IndexedDB и localStorage, после семи дней пользования Safari без взаимодействия с этим сайтом. Исключение — веб-приложения, добавленные на домашний экран: они живут в собственном отдельном хранилище. Игре, в которую играют еженедельно, лимит не грозит. Игре, в которую собирались вернуться, сохранения к моменту возврата уже нет.

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

Где сохранения живут у Godot, Unity и Construct

Экспортёры движков переносят свои родные механизмы сохранений в хранилища браузера, поэтому те же правила действуют уровнем выше:

ДвижокКуда попадают сохранения в вебеНа что смотреть
GodotФайловая система user:// персистится через IndexedDBДля персистентности нужны разрешённые cookies, именно IndexedDB; игре в iframe нужны ещё и third-party cookies; приватные окна блокируют персистентность
UnityPlayerPrefs хранятся через IndexedDB, до 1 МБ на веб-сборкахФайловые сохранения из персистентного пути данных игрока попадают в хранилище браузера — внутри тех же квот и правил выселения
Construct 3Плагин Local Storage держит все данные во внутренней базе браузера — файлов на диске не найтиНесмотря на имя, это полноценная асинхронная система хранения; для продвинутых случаев есть IndexedDB
Чистый JavaScript и фреймворкиТо, что вызовет код: localStorage для мелких значений, IndexedDB для остальногоВсе квоты и правила выселения из этой статьи применяются напрямую, без посредников

Из строки Godot следуют два практических вывода. Персистентность держится на настройках cookies, поэтому игрок, полностью заблокировавший куки, будет играть в веб-сборку без сохранений — обычно не догадываясь, почему. А поскольку порталы встраивают игры в iframe на собственном домене, оговорка про iframe там — нормальный случай, а не экзотика.

Порталы: сохранения живут на их домене

Хранилище привязано к origin, с которого загрузили игру. На портале этот origin принадлежит порталу. Три следствия:

  • Сохранение цепляется к домену портала, а не к вам и не к аккаунту игрока на вашем сайте. Игрок, который позже найдёт ту же сборку на вашей странице, начнёт с нуля.
  • Все игры, которые портал раздаёт по этой схеме, делят общее хранилище портала — ещё одна причина давать ключам характерный префикс, а не безликий save.
  • Правила iframe бьют сюда первыми: у игрока портала с заблокированными third-party cookies персистентность может пропасть целиком — см. таблицу движков выше.

Это не делает порталы плохим выбором хостинга — просто контекст персистентности у них другой. Тестируйте систему сохранений внутри встраивания портала, а не только в локальном экспорте: это два разных мира хранилищ.

SQLite в браузере: паттерн для тяжёлых данных

Когда данным игры становится тесно в хранилище ключ-значение, есть вариант поновее. SQLite компилируется в WebAssembly и может держать целую базу в OPFS — Origin Private File System, приватной области хранилища браузера, привязанной к origin и созданной ровно для этого. Паттерн определяет одно ограничение: приватная файловая система доступна только в воркерах, фоновых потоках, а не в главном потоке — работа с базой уходит из кадрового цикла, где ей и место.

Широкую аудиторию паттерн собрал в этом месяце: Capsule, инструмент для однофайловых веб-приложений, которые держат данные в SQLite, набрал на Hacker News около 380 голосов. Привлекательность проста: полноценная реляционная база поверх мегабайтов состояния — с запросами, с экспортом одним файлом, и всё ещё внутри origin-правил браузера. Для насыщенной сохранениями веб-инкременталки или RPG это текущий потолок персистентности без бэкенда.

У потолка тот же весовой лимит. SQLite в браузере живёт в origin-хранилище: квоты, выселение, семидневный лимит Safari и кнопка очистки данных применяются ровно так же. Более мощный движок для данных не меняет условий земли, на которой стоит.

План сохранений, который переживёт релиз

  1. Держите сохранение компактным и версионируйте его. Номер версии схемы в блоке сохранения стоит одного поля, а спасает весь конвейер обновлений. Что хранить и когда — отдельный дизайн-вопрос, у него есть своё руководство по системе сохранений.
  2. Ставьте ключам хранилища префикс с именем игры. На любом общем origin — а их больше, чем кажется, — безликие ключи конфликтуют.
  3. Добавьте экспорт и импорт файла сохранения. Одна кнопка, скачивающая JSON, спасает во всех режимах отказа выше: игрок, потерявший сохранение от выселения или лимита Safari, восстановит его из файла, а поддержка превращается из расследования в одно предложение.
  4. Тестируйте в приватном окне и после очистки данных сайта. Это два состояния, в которых ваши игроки реально оказываются, когда что-то ломается, — и оба воспроизводятся по требованию.
  5. Запрашивайте постоянное хранилище, если сохранения важны. Движок выставляет настройку — включите её; код ваш — один вызов просит браузер вывести игру из-под best-effort-выселения.
  6. Читайте спрос на кроссплатформенный прогресс как сигнал. Когда игроки просят прогресс с телефона на десктоп, одним браузером тут уже не обойтись. Это момент для аккаунтов и облачных сохранений — есть способ добавить облачные сохранения без сервера. В том же origin-хранилище живут и рекорды, которые веб-демо обычно делают первыми: лидерборд без сервера закрывает ту половину задачи.

Частые ошибки

  • Мегабайты в localStorage. Запись падает при упоре в квоту, и до разработчика это доходит репортом игрока, а не сообщением об ошибке.
  • Предположение, что сохранение следует за игроком. Другой браузер, другое устройство, другая машина — с точки зрения хранилища это другой человек.
  • Тесты только в Chrome. У Safari и самый жёсткий лимит, и меньше всего официальной документации — именно там сохранения реально умирают.
  • Долгий прогресс, доверенный порталу. Правила iframe действуют там первыми, и у игрока нет отношений с origin, который держит данные.
  • Выпуск сохранения без поля версии. Приходит обновление, старые сохранения парсятся наполовину, а баг-репорты описывают симптомы на три шага в стороне от причины.
  • Расчёт на персистентность инкогнито-прогонов. Приватные окна популярны для вторых прохождений веб-игр — и всё в них временно по замыслу.

Место Egmatic

Всё, что выше, — сантехника. Различать IndexedDB и localStorage полезно для веб-разработчика, но это не делает игру лучше спроектированной. Решение, которое заслуживает вашего внимания, — что игра помнит и для кого, а остальное — слой, который должен нести инструмент.

Egmatic — no-code-редактор и движок двухмерных игр в пре-альфе, построенный вокруг слоя выпуска, который относится к персистентности как к части публикации: тот же конвейер, что ведёт игру от сцены до размещённой ссылки, проектируется так, чтобы вести и её сохранения — от локального хранилища до аккаунтов и облачной синхронизации. Тогда вопрос о том, где живут сохранения, становится настройкой, а не исследовательской статьёй. Вы решаете, что игра помнит, редактор исполняет, и каждый файл остаётся вашим.

О стадии скажем прямо: Egmatic в пре-альфе, и мы не называем сроков, которых не можем сдержать. Лист ожидания на egmatic.com — место, где слой персистентности обретает форму: рассказ там о том, что ваша веб-игра должна запоминать, — это вход, который направляет разработку.

Источники

  1. web.dev — Storage for the web: Chrome разрешает origin использовать до 60% всего диска при потолке браузера 80%; инкогнито-окна с очисткой при закрытии ограничены примерно 300 МБ; Firefox — до 50% свободного места диска, группа сайтов eTLD+1 (домен с поддоменами) ограничена примерно 2 ГБ; Safari — около 1 ГБ с запросами шагами по 200 МБ; best-effort как режим по умолчанию; Chromium первым вычищает origin, не использовавшийся дольше всех; постоянное хранилище как отказ от best-effort; Cache Storage рекомендован для сетевых ресурсов, а не пользовательских данных
  2. WebKit Blog — Full Third-Party Cookie Blocking and More: семидневный лимит на всё хранилище, доступное скриптам, — IndexedDB, LocalStorage, SessionStorage и регистрации Service Worker в списке типов; применяется после семи дней пользования Safari без взаимодействия с сайтом; веб-приложения, добавленные на домашний экран, держат отдельное собственное хранилище
  3. MDN Web Docs — Web Storage API: localStorage и sessionStorage хранят строки в рамках origin; оба API синхронные
  4. MDN Web Docs — Storage API: интерфейс StorageManager даёт оценки хранилища; постоянные бакеты удерживаются до последнего, best-effort чистятся первыми при нехватке места
  5. Документация Godot Engine — Exporting for the Web: персистентность файловой системы user:// требует разрешённых cookies, конкретно IndexedDB; игре в iframe дополнительно нужны third-party cookies; инкогнито и приватный просмотр блокируют персистентность
  6. Unity Script Reference — PlayerPrefs: веб-сборки хранят до 1 МБ данных PlayerPrefs через IndexedDB браузера
  7. Construct 3 Manual — Local Storage plugin (прочитано через снапшот archive.org от 7 марта 2026 — живая страница собирается скриптами): все данные хранятся во внутренней базе браузера, файлов на диске не найти; IndexedDB — для более сложных случаев
  8. Документация SQLite — Persistence for the sqlite3 WASM/JS build: Origin Private File System как API браузерного персистентного хранилища для баз SQLite; OPFS доступен в контексте воркера, а не главного потока
  9. Hacker News — Show HN: Capsule, single-file web apps that save their data into SQLite: около 380 голосов, прочитано 25 сентября 2026; обсуждение сообществом веб-приложений, которые держат структурированные данные без бэкенда

Похожие статьи