Как правило, вы не справляетесь с нехваткой памяти. Единственный разумный вариант в программном обеспечении, таком большом и сложном, как игра, - просто сбить / утвердить / завершить работу распределителя памяти как можно скорее (особенно в отладочных сборках). Условия нехватки памяти тестируются и обрабатываются в некоторых основных системных или серверных программах в некоторых случаях, но обычно в других местах.
Когда у вас есть верхний предел памяти, вы просто гарантируете, что вам никогда не понадобится больше, чем этот объем памяти. Например, вы можете сохранить максимальное количество разрешенных NPC за один раз и просто прекратить порождать новых несущественных NPC, как только эта крышка будет достигнута. Для важных NPC вы можете либо заменить их второстепенными, либо иметь отдельный пул / колпачок для важных NPC, которые ваши дизайнеры знают для разработки (например, если у вас есть только 3 основных NPC, дизайнеры не будут помещать более 3 в область / кусок - хорошие инструменты помогут дизайнерам сделать это правильно, и тестирование, конечно, необходимо).
Действительно хорошая потоковая система также важна, особенно для игр с песочницей. Вам не нужно хранить все NPC и предметы в памяти. По мере того, как вы перемещаетесь по кусочкам мира, новые куски будут поступать внутрь, а старые куски вытекать. Как правило, они включают в себя NPC и предметы, а также ландшафт. Принимая во внимание эту систему, необходимо установить ограничения на дизайн и конструирование лимитов предметов, зная, что не более X старых чанков будут храниться и активно загружаться Y новых чанков будут загружаться, поэтому в игре должно быть место, чтобы сохранить все данные X + Y + 1 кусков в памяти.
Некоторые игры пытаются справиться с ситуациями нехватки памяти с помощью двухпроходного подхода. Помните, что в большинстве игр содержится много технически ненужных кэшированных данных (скажем, старых блоков, упомянутых выше), и распределение памяти может выглядеть примерно так:
allocate(bytes):
if can_allocate(bytes):
return internal_allocate(bytes)
else:
warning(LOW_MEMORY)
tell_systems_to_dump_caches()
if can_allocate(bytes):
return internal_allocate(bytes)
else:
fatal_error(OUT_OF_MEMORY)
Это последний шаг для решения непредвиденных ситуаций в выпуске, но во время отладки и тестирования вы, вероятно, должны сразу же аварийно завершить работу. Вы не хотите полагаться на такого рода вещи (особенно потому, что сброс кэшей может иметь некоторые серьезные последствия для производительности).
Вы можете также рассмотреть возможность выгрузки копий некоторых данных в высоком разрешении, например, вы можете сбросить текстуру уровней mipmap с более высоким разрешением, если вам не хватает памяти GPU (или любой памяти в архитектуре с разделяемой памятью). Это обычно требует много архитектурных работ, чтобы это того стоило.
Обратите внимание, что некоторые очень неограниченные игры-песочницы могут быть просто легко разбиты, даже на ПК (помните, что обычные 32-битные приложения имеют ограничение в 2-3 ГБ адресного пространства, даже если у вас есть компьютер с 128 ГБ ОЗУ; Битовая ОС и аппаратное обеспечение позволяют одновременно запускать больше 32-разрядных приложений, но ничего не могут сделать, чтобы 32-разрядный двоичный файл имел большее адресное пространство). В конце концов, у вас либо очень гибкий игровой мир, для которого в каждом случае потребуется неограниченное пространство памяти, либо у вас очень ограниченный и контролируемый мир, который всегда отлично работает в ограниченной памяти (или что-то среднее).