(Возможно, вы захотите узнать о термине «исправление обезьяны» или «штамповка утки», если не по каким-либо иным причинам, кроме юмористического образа мыслей.)
И это в стороне: если ваша цель - уменьшить время итерации для изменений «поведения», попробуйте несколько подходов, которые помогут вам в этом, и хорошо сочетаются, чтобы в будущем это стало возможным.
(Это будет немного касательно, но я обещаю, что это вернется!)
- Начните с данных и начните с малого: перезагрузите на границах («уровнях» и т. П.), Затем перейдите к использованию функциональности ОС для получения уведомлений об изменениях файлов или просто регулярно проводите опросы .
- (Для получения бонусных баллов и меньшего времени загрузки (опять же, уменьшая время итерации) посмотрите на запекание данных .)
- Скрипты являются данными и позволяют вам повторять поведение. Если вы используете язык сценариев, у вас теперь есть уведомления / возможность перезагрузить эти сценарии, интерпретированные или скомпилированные. Вы также можете подключить ваш переводчик к игровой консоли, сетевому сокету и т. П. Для повышения гибкости во время выполнения.
- Код также может быть данными : ваш компилятор может поддерживать оверлеи , общие библиотеки, библиотеки DLL и т.п. Таким образом, теперь вы можете выбрать «безопасное» время для выгрузки и перезагрузки оверлея или DLL, как ручного, так и автоматического. Другие ответы подробно здесь. Обратите внимание, что некоторые варианты этого могут мешать криптографической подписи подписи, биту NX (без выполнения) или подобным механизмам безопасности.
- Рассмотрим глубокую версионную систему сохранения / загрузки . Если вы можете надежно сохранять и восстанавливать свое состояние даже перед лицом изменений кода, вы можете закрыть свою игру и перезапустить ее с новой логикой в той же точке. Проще сказать, чем сделать, но это выполнимо, и это заметно проще и более портативно, чем перетаскивание памяти для изменения инструкций.
- В зависимости от структуры и детерминизма вашей игры вы можете выполнять запись и воспроизведение . Если эта запись находится только над «игровыми командами» (например, карточная игра), вы можете изменить весь код рендеринга и воспроизвести запись, чтобы увидеть ваши изменения. Для некоторых игр это так же просто, как записать некоторые начальные параметры (например, случайное начальное число), а затем действия пользователя. Для некоторых это намного сложнее.
- Приложите усилия, чтобы сократить время компиляции . В сочетании с вышеупомянутыми системами сохранения / загрузки или записи / воспроизведения, или даже с оверлеями или библиотеками DLL, это может уменьшить ваш оборот больше, чем любая другая вещь.
Многие из этих моментов полезны, даже если вы не полностью перезагрузите данные или код.
Вспомогательные анекдоты:
На большом ПК RTS (команда ~ 120 человек, в основном C ++) существовала невероятно глубокая система сохранения состояния, которая использовалась как минимум для трех целей:
- «Неглубокое» сохранение было передано не на диск, а на механизм CRC, чтобы многопользовательские игры оставались в режиме симуляции с блокировкой по одному CRC каждые 10-30 кадров; это гарантировало, что никто не изменял и через несколько кадров обнаружил ошибки рассинхронизации
- Если и когда произошла ошибка рассинхронизации в многопользовательском режиме, было выполнено сверхглубокое сохранение в каждом кадре, которое снова передавалось в механизм CRC, но на этот раз механизм CRC генерировал бы много CRC, каждый для меньших пакетов байтов. Таким образом, он может точно сказать, какая часть состояния начала расходиться в последнем кадре. Мы обнаружили неприятную разницу в «режиме с плавающей запятой по умолчанию» между процессорами AMD и Intel, использующими это.
- Обычное сохранение глубины может не сохранять, например, точный кадр анимации, в котором играл ваш юнит, но оно получит положение, здоровье и т. Д. Всех ваших юнитов, что позволит вам сохранять и возобновлять игру в любое время в течение игрового процесса.
С тех пор я использовал детерминированную запись / воспроизведение в C ++ и Lua карточной игре для DS. Мы подключились к API, который мы разработали для AI (на стороне C ++), и записали все действия пользователя и AI. Мы использовали эту функциональность в игре (чтобы обеспечить воспроизведение для игрока), но также и для диагностики проблем: когда происходил сбой или странное поведение, все, что нам нужно было сделать, это получить файл сохранения и воспроизвести его в отладочной сборке.
С тех пор я также использовал оверлеи несколько раз, и мы объединили их с нашей системой «автоматически разбрасывать этот каталог и загружать новый контент в карманный компьютер». Все, что нам нужно сделать, это оставить кат-сцену / уровень / что угодно и вернуться обратно, и будут загружены не только новые данные (спрайты, разметка уровней и т. Д.), Но и любой новый код в оверлее. К сожалению, с более новыми карманными компьютерами становится все труднее из-за механизмов защиты от копирования и защиты от взлома, которые обрабатывают код специально. Мы все еще делаем это для сценариев Lua, хотя.
И последнее, но не менее важное: вы можете (и я имею в виду, в различных очень маленьких особых обстоятельствах) сделать небольшую пробивку утки, непосредственно исправляя коды операций. Это работает лучше всего, если вы работаете на фиксированной платформе и компиляторе, и, поскольку он почти не поддерживается, очень подвержен ошибкам и ограничен в том, что вы можете быстро выполнить, я в основном использую его только для перенаправления кода во время отладки. Тем не менее, он очень быстро научит вас многому об архитектуре набора команд.