Кстати в качестве ИЗ отлично подойдет обычный теннисный корт
А вот это уже интересная идея!
но ~200 баков на полный комплект (с контроллерами)
Ну, года три назад я бы согласился, но теперь подсел на отдых на Карибах... Если у меня появляются свободные $100 - они тут же уплывают в копилочку к отпуску в ноябре. Чтобы не как в прошлом году, нищебродское маринование на пляже под пальмами - а и на экскурсию в джунгли съездить, и на шоколадную фабрику, и с аквалангом поплавать, и пинью коладу каждый день жрать - и вообще осилить родню с собой затащить.
И тут внезапно получается, что денег - не мало, а охрененно мало!
З.Ы. Сейчас мееедленно строгаю диспетчер памяти для инстансов. Медленно - потому что на работе, что характерно, есть много работы, которую нужно сделать!

А чентра - так, на выходных погудеть.
Будет абсолютно без блокировки благодаря следующему хитрому хаку: пулы памяти отдельные для каждого потока, и у каждого пула - N кладбищ для всех потоков. Если память освобождается из неродного - она вместо этого кладётся на соответствующее кладбище. А очищаются кладбища при глобальной синхронизации всех потоков, которая происходит несколько раз в минуту.
Используется единственная на весь движок threadvar, в которую записывается индекс потока.
Зафига отдельный менеджер памяти? Для поддержки индексов, флагов и просто ускоренных полей, лежащих отдельно от самих инстансов. Что, в теории, даст конский прирост производительности при обработке многаобъектов (читай: миллион) за счёт радикального уменьшения загрязнения кеша. Поскольку для получения этих "отдельных" сущностей вообще не нужно трогать сам инстанс: обнуляешь младшие 17 бит Self - и получаешь инстанс пула памяти, у которого уже спрашиваешь нужное, оно всё плотно упаковано. Главное не ступить и не сделать соответствующий функционал виртуальными методами: ведь тогда код полезет в инстанс за указателем на vmt, и всё насмарку.
Пример: 50 тысяч монстров, каждый класс 64 байта (утопия, только для примера). Читаем у каждого ускоренное поле типа longint. Память - офисная, 10 Гб/с.
Традиционный метод: через кеш прокачивается 3 мегабайта. У современных процов должно влезать в кеш третьего уровня... Но он же не только монстрами занимается. Расход времени - 300 микросекунд.
Если это поле надо ещё и модифицировать - все 3 Мб приходится писать обратно в память. 600 микросекунд.
Ускоренное поле: объекты разбросаны по ~25 Пулам памяти. Принимая полное заполнение: придётся прочитать 25 пулов (вес пера) и 25 массивов, суммой 50000 * 4 = 195 килобайт. Мало того, что это всё в кеш второго уровня влезает, расходы на перезапись памяти будут 40 микросекунд. Медленнее в реальных боевых, где пулы фрагментированы, часть ячеек пустые, часть - инстансы других вещей, не монстров. Но ~100мкс я надеюсь получить.
Вы можете сказать, что <1мс можно забить. Но:
1. Память - одна на все потоки. Цена кеш-промахов по всему движку складывается, и быстрее этих 10Гб/с никакая многоядерность не позволит ехать. А ведь при встроенном видео от этого пирога ещё и видяха откусывает.
2. Движок занимается ещё дохрена вещей, кроме тупого обхода монстров. Так что 1мс - это таки дорого.
З.З.Ы. Оцениваю стоимость перебаламучивания памяти так: один кадр ~15мс. За это время можно перебаламутить (на 5 Гб/с, ибо обмен идёт в обе стороны) до 75 Мб. Мегабайт, Карл!
Множим на коэффициент Нежданчика 0.3 (ибо см. выше про встроенное видео) и получаем, что движку позволительно за кадр потревожить лишь около 25 Мб памяти. Это меньше четырёхсот тысяч объектов. Причём "перебаламутить" - модифицировать у каждого хотя бы одно поле. Да хоть байт. Память всё равно работает кусками по 64 байта.