Автор Тема: Зависимость выпадения призов от кадров анимации в играх  (Прочитано 56 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Sharpnull

  • Пользователь
  • Сообщений: 5294
    • Просмотр профиля
Вид приза зависит от кадра игры, в котором враг умирает, а не от кадра его анимации.
Если упрощать, то любая игра для NES со случайностью будет зависеть от кадра игры, потому что нет другой случайности, кроме ввода пользователя, который обычно проверяют один раз за кадр. Т. е. эта фраза ни о чём не говорит. UPD2: Я ошибся, можно представить случайность, которая бы зависела от того же кадра анимации врага (или героя) в момент смерти врага или высчитываться до смерти, т. е. быть без привязки к кадрам игры в момент смерти врага, но и случайность тогда была бы плохой.

В Darkwing Duck устроено так. Есть 4 байта для генерации случайности в RAM $E4-E7 с начальными значениями 88 00 00 00. Каждый кадр производится XOR между одним битом от $E4 и одни битом от $E5, его значение добавляется слева (старший бит) в $E4, а вместе с этим сдвигаются все биты на 1 у $E4-E7 вправо с переходом между собой, как если бы это было одно число из 4 байт, на языке C или Python было бы: u32var = (u32var >> 1) | (((u32var << 6) ^ (u32var << 14)) & 0x80000000). Код с CPU $C2DE:
Когда нужна случайность, в одном случае складываются RAM $E4 и $E5, сохраняя в $E5, и от этого только 3 младших бита (LDA $E4 /  ADC $E5 /  STA $E5 / AND #$07). Для случая с врагом складываются уже $E5 и $E6, сохраняя в $E6, значение должно быть между 0x7F и 0xFF (129 значений из 256) от этого берётся 5 младших битов (32 значения) и становится индексом для таблицы предметов, в которой разбросаны значения с повторами для неравномерного распределения (значение на кол-во повторов: 1C * 5, 1D * 8, 22 * 5, 23 * 6, 24 * 3, 25 * 5). Код с CPU $875F (банк 6):
UPD: Вдохновение для алгоритма возможно бралось от https://en.wikipedia.org/wiki/Linear-feedback_shift_register, я не силён в математике.

UPD3: Не по теме. Я думал о случайной генерации поля логической игры для NES: появляется главное меню и при выборе игры будет только ограниченный набор, потому что небольшой диапазон кадров от начала игры. Можно позже увеличивать случайность по доп. нажатиям, но первая партия будет унылой. Как варианты: хранить случайность в сохранении на картридже; использовать специальный маппер с генератором (можно даже не псевдо, а настоящие случайные числа получить); заставить пользователя нажимать разные кнопки перед началом как было в Opera на Java ME.
« Последнее редактирование: 01 Июнь 2025, 13:09:13 от Maximum »

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1262
    • ВКонтакте
    • Steam
    • Просмотр профиля
Sharpnull, фига как сложно там всё. А почему нельзя было просто вечно крутить по кругу 10 предметов (про 60 кадров и 60 предметов я что-то усложнил, это из какой-то другой темы) и выбирать попавшийся в момент смерти? Некоторые предметы будут попадаться слишком часто?
Если интересуешься псевдослучайными числами на ретроконсолях, то глянь X-men 2 на Сеге. Эти приколисты хотели как в сериале начинать сразу с экшена, без опенинга/заставки, и захотели случайного персонажа при этом. Т.е. включаешь приставку и у игры даже нет ввода, чтобы создать случайное число! 0_0
Откуда берётся-то?!
Оказывается, при включении и сбросе, в какой-то части памяти появляются электропомехи, переключение битов или что-то такое, и они случайны - игра и считывает их! В детстве мы сбрасывали игру много раз в попытке взять нужного персонажа.
В эмуляторах, естественно, этих помех нет и персонаж всегда один и тот же, сколько ни сбрасывай.
Но десятилетия спустя таки появился более точный эмулятор BlastEm, и он позволяет не обнулять память при запуске, отчего и возможно получить разного персонажа. Причём даже тех, кого никак не получалось получить на оригинальной консоли.
Надеюсь когда-нибудь подробнее изучить этот механизм.

Оффлайн SkyLarge

  • Пользователь
  • Сообщений: 219
  • Пол: Мужской
    • Просмотр профиля
Но десятилетия спустя таки появился более точный эмулятор BlastEm, и он позволяет не обнулять память при запуске, отчего и возможно получить разного персонажа. Причём даже тех, кого никак не получалось получить на оригинальной консоли.
Надеюсь когда-нибудь подробнее изучить этот механизм.
Вопрос, а кого так стало возможно получить? Просто фраза прозвучала так, словно можно выбить Магнето или вообще игру сломать словно.
Если память не подводит то на PSP через пикодрайв персонаж при старте разный выпадал. Но играл давно и сейчас проверить не могу (PSP нет при себе)

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1262
    • ВКонтакте
    • Steam
    • Просмотр профиля
SkyLarge, так и думал, что этот момент можно понять не так, и поэтому переписал несколько раз, но не помогло :)
На приставке мы получали только Ночного Змея, Зверя и Росомаху, изредка Циклопа, и то - это при игре вдвоём. На BlastEm удалось получить всех остальных играя одному. Магнето, очевидно, заблокирован.
Сейчас припоминаю, что какой-то эмулятор таки давал небольшую случайность, но это только при сбросе, а не при первом включении.

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3275
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
В эмуляторах, естественно, этих помех нет и персонаж всегда один и тот же, сколько ни сбрасывай.
Но десятилетия спустя таки появился более точный эмулятор BlastEm, и он позволяет не обнулять память при запуске, отчего и возможно получить разного персонажа. Причём даже тех, кого никак не получалось получить на оригинальной консоли.
Память при сбросе не обнуляют практически все эмуляторы. При включении - зависит от эмуляторов и их настроек. Во многих эмуляторах можно настроить на случайные значения в рам (например, в fceux). Но игры это не используют, так как всё равно очищают память в коде в самом начале, кроме некоторых пираток. И даже если значение при включении не будет 00/FF, то таким образом рандом нормальный (равномерный) не получить.
Касаемо X-men 2 там это может быть связано, с тем что включение или резет в произвольной точке кадра начинается, а в эмуляторах всегда с 1 места. И/или H/V counter.

 'Помехи' с неиспользуемых областей RAM он не читает, хотя такое тоже возможно. Но эмуляторы помехи и температуру не эмулируют. Вот видео помехов: https://gendev.spritesmind.net/forum/viewtopic.php?f=2&t=551#p37603


Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1262
    • ВКонтакте
    • Steam
    • Просмотр профиля
Во многих эмуляторах можно настроить на случайные значения в рам
Но не в сеговских?

Но игры это не используют
Почему же тогда эта функция нужна?

включение или резет в произвольной точке кадра начинается
Т.е. приставка считывает в каком месте находится луч телевизора в данный момент? Я не очень разбираюсь в этой части.

Касаемо X-men 2
Если бы в этой игре рандом был связан на "точке кадра", то не приходилось бы использовать в эмуляторе случайные данные в памяти при включении.

не будет 00/FF, то таким образом рандом нормальный (равномерный) не получить.
Да с любого значения равномерно не получить, скорее всего, поэтому эти лишь зерно/семя для дальнейших вычислений.
Вопрос теперь в том, почему у Darkwing Duck такой сложный рандом, если можно было просто крутить предметы в цикле. Скорее всего, этот механизм перекочевал вместе с движком от мегаменов.

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3275
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
Но не в сеговских?

Почему же тогда эта функция нужна?

Т.е. приставка считывает в каком месте находится луч телевизора в данный момент? Я не очень разбираюсь в этой части.
Если бы в этой игре рандом был связан на "точке кадра", то не приходилось бы использовать в эмуляторе случайные данные в памяти при включении.

Да с любого значения равномерно не получить, скорее всего, поэтому эти лишь зерно/семя для дальнейших вычислений.

Вопрос теперь в том, почему у Darkwing Duck такой сложный рандом, если можно было просто крутить предметы в цикле. Скорее всего, этот механизм перекочевал вместе с движком от мегаменов.
1) В сеговских да, там по нулям при повер-оне. И в бластеме тоже, но там в конфиг файле можно сделать не нулевой.
В default.cfg
#set this to random to debug initialization bugs
ram_init zero
изменить на ram_init random

2) Нужна для проверки багов, и вот они: https://www.nesdev.org/wiki/Game_bugs#Reliance_on_RAM_values

3) Да, Hcounter это точка луча по горизонатали, а Vcounter -по вертикали. Эти значения можно считывать на Sega MD.

4) Там в памяти остаётся предыдущее значение, и когда выключаешь память разряжается и постепенно значение меняется на FF или 00, по крайней мере у меня так было на сега-сд.

5) Простенький генератор случайных чисел есть практически в каждой игре. Они занимают байт 10-20. Никто не делает чтобы подряд выпадало одно и тоже в определённом порядке, это просто нелепо по гейм дизайну. Плюс можно даже без генератора, в зависимости от счетчика кадров делать (так тоже делают). Ну иногда ещё смешивают с нажатиями кнопок.

Добавлено позже:
Если бы в этой игре рандом был связан на "точке кадра", то не приходилось бы использовать в эмуляторе случайные данные в памяти при включении.
В моём конфиге ram_init zero (дефолтный конфиг - то есть в памяти нули при включении). При запуске эмулятора персонаж всегда один и тот же. При софт резете персонаж рандомный. Но софт резет не сбрасывает память и в других эмуляторах, так как и не должен. То есть с ram это не связано.  Ну и вот даже тут написано, что это каунтеры: https://gendev.spritesmind.net/forum/viewtopic.php?f=2&t=1006&p=14949&hilit=x+men#p14949
« Последнее редактирование: 30 Июль 2023, 17:45:26 от Ti_ »

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1262
    • ВКонтакте
    • Steam
    • Просмотр профиля
Ты повторяешь многое, что мы написали в последних комментах, похоже ты их не читал.
Почему в BlastEm появляются другие персонажи только с включением рандомизации памяти? "Точка кадра" тоже хранится в памяти? Или рандомизируется не только память, но и всё окружение эмулируемой Сеги, получается?

можно даже без генератора, в зависимости от счетчика кадров делать (так тоже делают)
Я так же написал и потом задумался - а причём здесь счётчик кадров? (и самой игре вообще зачем такой счётчик?).
Никто не делает чтобы подряд выпадало одно и тоже в определённом порядке, это просто нелепо по гейм дизайну.
Но ведь человек не может убивать врага всегда в один и тот же кадр или в кадр рядом, и получать примерно те же предметы. Допустим, крутятся по кругу 10 предметов, меняются каждый кадр, за 60 кадров эти 10 предметов прокрутятся 6 раз. Не верится, что это плохой генератор, что человек сможет попадать на одни предметы чаще. И счётчик кадров для этого не нужен, только зацикленный указатель на предметы.
Надо бы попробовать сделать тест.

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3275
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
Почему в BlastEm появляются другие персонажи только с включением рандомизации памяти? "Точка кадра" тоже хранится в памяти? Или рандомизируется не только память, но и всё окружение эмулируемой Сеги, получается?
У меня независимо от того, включаю я рандомизатор памяти или нет, при запуске эмулятора - один и тот же персонаж с палкой, при сбросе через TAB - рандомно разные персонажи. Версия бластема 0.6.3 - 10.02.2023.

Оффлайн Werton

  • Пользователь
  • Сообщений: 929
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SkyLarge, так и думал, что этот момент можно понять не так, и поэтому переписал несколько раз, но не помогло :)
На приставке мы получали только Ночного Змея, Зверя и Росомаху, изредка Циклопа, и то - это при игре вдвоём. На BlastEm удалось получить всех остальных играя одному. Магнето, очевидно, заблокирован.
Сейчас припоминаю, что какой-то эмулятор таки давал небольшую случайность, но это только при сбросе, а не при первом включении.
Так говоришь, "всех остальных", как будто там их еще вагон и маленькая тележка:). А не назвал только Псайлок и Гамбита, и у меня они на консоли так же обычно выпадали, не сказал бы что реже других.

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3275
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
Я так же написал и потом задумался - а причём здесь счётчик кадров? (и самой игре вообще зачем такой счётчик?).Но ведь человек не может убивать врага всегда в один и тот же кадр или в кадр рядом, и получать примерно те же предметы. Допустим, крутятся по кругу 10 предметов, меняются каждый кадр, за 60 кадров эти 10 предметов прокрутятся 6 раз. Не верится, что это плохой генератор, что человек сможет попадать на одни предметы чаще. И счётчик кадров для этого не нужен, только зацикленный указатель на предметы.
Счётчик есть в любой игре. Это просто 1 строчка, которая прибавляет +1 к какому-то значению в памяти каждый кадр. Если 1-байтовый получается 256 разных значений. Далее это универсально используется для всего, и в т.ч. для 'рандома' разных вещей, если отдельного генератора нет. А отдельные зацикленные указатели-счётчики как раз не создают. Просто используют меньшее кол-во битов от кадрового, например на 8 или 16, и делают таблицу где 'предметы'.

Посмотрел - вот в роме ЧП эти таблицы на 32 значения:
187b2 - 187d1,  далее ещё такая же на 32 для какого-то другого случая.  $1C - корона (100), $1D - золото? (500), далее не проверял. Значения которые влияют на выбор индекса - в памяти $E5 и $E6.
« Последнее редактирование: 30 Июль 2023, 20:35:13 от Ti_ »

Оффлайн perfect_genius

  • Пользователь
  • Сообщений: 1262
    • ВКонтакте
    • Steam
    • Просмотр профиля
при запуске эмулятора - один и тот же персонаж с палкой
Так я про это ведь и пытаюсь донести - при рандомиза
персонаж
Сейчас проверил и ты прав, мой фейл. Оказывается, на выбор персонажа при включении влияет то, что подключено к портам геймпада - я как раз этим и занимался в этом эмуляторе в то время, когда заметил разных персонажей при включении, но закономерность тогда не уловил. Оказывается:
6-кнопочный в первом или втором порту - Гамбит (мужик с палкой)
Два таких геймпада в портах - Росомаха.
3-хкнопочный - Псайлок
Второй порт занят мышкой - Ночной Змей.
И т.д.
Это просто потрясающе, я узнал ещё немного о своей любимой игре детства, всё ещё не дойдя до её реверса :wow:
Ну и этому эмулятору надо бы обзавестись ещё и рандомизацией положения луча, получается.

у меня они на консоли так же обычно выпадали, не сказал бы что реже других.
Я пробовал этот рандом на разных консолях и в каждом какие-то выпадали чаще. Видимо, зависело от качества клона Сеги, от каких-то его особенностей рандома положения луча.

Ок, про X-men 2 надо бы закончить тогда оффтоп - я ошибся, даже более точные эмуляторы так и не дают получить случайного перса при запуске :(


используют меньшее кол-во битов от кадрового
Вот как связан тут счётчик кадров, понятно теперь. А сам этот счётчик кадров - он зачем игре? Для таймеров что ли? Или это стандартная аппаратная функция консоли?

А про рандом Darkwing Duck - может кто-то где-то в сети визуализирует ГПСЧ у игр, не знаете? Если такого нет, то у меня такая идея давно лежит. Sharpnull подробно расписал, но это не для простых смертных, обычные люди любят глазами и попроще :)

Оффлайн Ti_

  • Пользователь
  • Сообщений: 3275
  • Пол: Мужской
    • ВКонтакте
    • Youtube
    • Просмотр профиля
Ок, про X-men 2 надо бы закончить тогда оффтоп - я ошибся, даже более точные эмуляторы так и не дают получить случайного перса при запуске
Ну главное, что они делают это при резете. А то в генсе всегда один персонаж при запуске, и другой при резете. То есть только 2 разных.

от как связан тут счётчик кадров, понятно теперь. А сам этот счётчик кадров - он зачем игре? Для таймеров что ли? Или это стандартная аппаратная функция консоли?
Это не функция консоли, а просто 1 строчка в коде игры. Некий стандартный подход в играх, он сам по себе много для чего бывает нужен, для разных моментов. Но для таймеров, если имеется ввиду секунды то нет, там отдельно делают на 60 кадров отсчёт (если нтсц). Но именно в ЧП для выпадения призов там какие-то другие счётчики. Перечитал предыдущую страницу - Sharpnull написал подробно же. Это наверно сложно понять, но в игре это не какой-то мудрёный код, это просто несколько строк.
Разные вариации генераторов есть почти везде, где-то совсем простые, где-то немного сложнее. Где-то смешивают с кадровым счётчиком и/или нажатиями кнопок. Но принципиально они все простые в 5-15 строк кода. То есть, это не сотни-тысячи операций, 'тормозов' не добавляет (всё делали максимально простым).
« Последнее редактирование: 30 Июль 2023, 22:50:05 от Ti_ »