Як я можу виконати детерміноване моделювання фізики?


43

Я створюю фізичну гру, що включає жорсткі тіла, в яких гравці переміщують шматки та деталі для вирішення головоломки / карти. Надзвичайно важливим аспектом гри є те, що коли гравці починають симуляцію, вона працює однаково скрізь , незалежно від їх операційної системи, процесора тощо ...

Існує місце для великої кількості складностей, і симуляції можуть працювати тривалий час, тому важливо, щоб фізичний двигун був повністю детермінованим щодо операцій з плаваючою комою, інакше може з'явитися рішення, що "вирішує" на машині одного гравця, і "провалити" на іншому.

Як я можу сприйняти цей детермінізм у своїй грі? Я готовий використовувати різні рамки та мови, включаючи Javascript, C ++, Java, Python та C #.

Мене спокусили Box2D (C ++), а також його еквіваленти в інших мовах, як це, здається, відповідає моїм потребам, але йому не вистачає детермінізму з плаваючою комою, особливо з тригонометричними функціями.

Найкращим варіантом, який я бачив до цього часу, був Java-еквівалент Box2D (JBox2D). Здається, зробити спробу детермінізму з плаваючою комою скористатись, StrictMathа не Mathдля багатьох операцій, але незрозуміло, чи буде цей двигун гарантувати все необхідне, оскільки я ще не створив гру.

Чи можливо використовувати чи змінювати існуючий двигун відповідно до моїх потреб? Або мені потрібно буде побудувати двигун самостійно?

РЕДАКТУВАННЯ: Пропустіть решту цієї публікації, якщо вам не байдуже, чому комусь потрібна така точність. Люди, коментуючи коментарі та відповіді, здається, вважають, що я шукаю щось, чого не повинен, і, як таке, я далі поясню, як гра повинна працювати.

Гравцеві дається пазл або рівень, який містить перешкоди та мету. Спочатку моделювання не працює. Потім вони можуть використовувати шматки або інструменти, надані їм для побудови машини. Як тільки вони натискають на пуск, починається моделювання, і вони вже не можуть редагувати свою машину. Якщо машина вирішує карту, гравець побив рівень. В іншому випадку їм доведеться натиснути стоп, змінити свою машину та спробувати ще раз.

Причина, що все має бути детермінованою, полягає в тому, що я планую створити код, який буде відображати кожну машину (набір фрагментів та інструментів, які намагаються вирішити рівень) у файл xml або json, записуючи положення, розмір та обертання кожної деталі. Тоді гравці зможуть ділитися рішеннями (які представлені цими файлами), щоб вони могли перевіряти рішення, вчитися один у одного, проводити змагання, співпрацювати тощо ... Звичайно, більшість вирішує, особливо прості чи швидкі не впливатиме на відсутність детермінізму. Але повільні або складні конструкції, які вирішують дійсно важкі рівні, можуть бути саме тими, які, ймовірно, будуть найцікавішими та варто ділитися.


Коментарі не для розширеного обговорення; ця розмова переміщена до чату . Якщо ви вважаєте, що у вас є рішення проблеми, розгляньте, як розмістити її як відповідь, а не коментар - це полегшує редагування, оцінку за допомогою голосування / маркування прийнято або коментувати саму пропозицію для зворотного зв’язку, а не плетіння відповідей у ​​більш довгу нитку розмови.
DMGregory

Відповіді:


45

Поводження з числами з плаваючою комою детерміновано

Плаваюча точка є детермінованою. Ну, так і має бути. Це складно.

Існує багато літератури про числа з плаваючою комою:

І наскільки вони проблемні:

Для реферату. Принаймні, на одному потоці ті самі операції з тими ж даними, що відбуваються в одному порядку, повинні бути детермінованими. Таким чином, ми можемо почати, турбуючись про введення та переупорядкування.


Одним із таких даних, що викликає проблеми, є час.

Перш за все, слід завжди обчислювати один і той же часовий крок. Я не кажу, щоб не вимірювати час, я кажу, що ви не витратите час на фізичне моделювання, тому що зміни часу є джерелом шуму в моделюванні.

Чому ви вимірюєте час, якщо не передаєте його на фізичне моделювання? Ви хочете виміряти минулий час, щоб знати, коли слід викликати крок моделювання, і - якщо ви використовуєте сон - скільки часу спати.

Таким чином:

  • Час вимірювання: Так
  • Використовуйте час для моделювання: Ні

Тепер переупорядкування інструкцій.

Компілятор міг би вирішити, що f * a + bце те саме, що b + f * a, однак, може мати інший результат. Він також може компілюватись до fmadd , або він може вирішити взяти кілька рядків, як це відбувається разом, і записати їх за допомогою SIMD , або якусь іншу оптимізацію, про яку я зараз не можу думати. І пам’ятайте, що ми хочемо, щоб одні й ті ж операції відбувалися в одному порядку, це стає причиною того, що ми хочемо контролювати, які операції відбуваються.

І ні, використання подвійного не врятує вас.

Вам потрібно потурбуватися про компілятор та його конфігурацію, зокрема для синхронізації чисел з плаваючою комою по всій мережі. Вам потрібно домогтися, щоб погодитись робити те саме.

Напевно, ідея складання була б ідеальною. Таким чином ви вирішите, яку операцію робити. Однак це може бути проблемою для підтримки декількох платформ.

Таким чином:


Справа для фіксованих точок чисел

Через те, як поплавці представлені в пам'яті, великі значення втрачають точність. Це стає причиною того, що збереження малих цінностей (затискач) пом'якшує проблему. Таким чином, немає величезних швидкостей і великих приміщень. Що також означає, що ви можете використовувати дискретні фізики, оскільки у вас менше ризику тунелювання.

З іншого боку, будуть накопичуватися невеликі помилки. Отже, усікайте. Я маю на увазі, масштабувати та додавати до цілого типу. Таким чином, ви знаєте, що нічого не створюється. Будуть операції, які ви можете виконати, залишившись з цілим типом. Коли вам потрібно повернутися до плаваючої точки, ви кидаєте та скасовуєте масштабування.

Примітка. Я кажу, що масштаб. Ідея полягає в тому, що 1 одиниця буде фактично представлена ​​як потужність двох (наприклад, 16384). Як би там не було, зробіть це постійним і використовуйте. Ви в основному використовуєте його як номер фіксованої точки. Насправді, якщо ви можете використовувати правильні цифри з фіксованою точкою з якоїсь надійної бібліотеки набагато краще.

Я кажу, усікати. Щодо проблеми округлення, це означає, що ви не можете довіряти останній біт будь-якого значення, яке ви отримали після виступу. Отже, перед тим, як накинути шкалу, набрати трохи більше, ніж потрібно, і обрізати її згодом.

Таким чином:

  • Тримайте значення малі: Так
  • Ретельне округлення: так
  • Коли можливі фіксовані номери точок: Так

Зачекайте, навіщо вам плаваюча точка? Не могли б ви працювати лише з цілим типом? О, так. Тригонометрія та радикація. Ви можете обчислити таблиці для тригонометрії та радикації та запекти їх у вашому джерелі. Або ви можете реалізувати алгоритми, що використовуються для обчислення їх з числом плаваючої крапки, за винятком використання цифр фіксованої точки. Так, вам потрібно збалансувати пам’ять, продуктивність та точність. Тим не менш, ви можете залишатися осторонь чисел з плаваючою комою та залишатися детермінованими.

Чи знаєте ви, що вони робили подібні речі для оригінальної PlayStation? Будь ласка , Meet My Dog, пластирі .

До речі, я не кажу не використовувати плаваючу крапку для графіки. Тільки для фізики. Я маю на увазі, звичайно, позиції будуть залежати від фізики. Однак, як відомо, коллайдер не повинен відповідати моделі. Ми не хочемо бачити результатів усічення моделей.

Таким чином: ВИКОРИСТУЙТЕ ФІКСОВАНІ БОЧКИ.


Щоб було зрозуміло, якщо ви можете використовувати компілятор, який дозволяє вам вказати, як працює плаваючі точки, і цього вам достатньо, то ви можете це зробити. Це не завжди варіант. Крім того, ми робимо це для детермінізму. Фіксовані точки не означають, що помилок немає, адже вони мають обмежену точність.

Я не думаю, що "фіксований номер важкий" - це вагомий привід не використовувати їх. І якщо ви хочете поважно використовувати їх, це детермінізм, зокрема детермінізм у різних платформах.


Дивитися також:


Додаток : Я пропоную зробити розмір світу невеликим. З огляду на це, обидва OP та Jibb Smart доводить до того, що віддалення від похідних поплавців має меншу точність. Це матиме вплив на фізику, таку, яку побачать набагато раніше, ніж край світу. Цифри з фіксованими точками, ну, мають фіксовану точність, вони будуть однаково хорошими (або поганими, якщо вам зручніше) скрізь. Що добре, якщо ми хочемо детермінізму. Я також хочу зазначити, що те, як ми зазвичай займаємось фізикою, має властивість посилювати невеликі варіації. Дивіться Ефект Метелика - Детермінована фізика в неймовірному виробнику машин та видобутку .


Ще один спосіб займатися фізикою

Я думав, що причина невеликих помилок у точності в числах з плаваючою точкою посилюється в тому, що ми робимо ітерації на цих числах. На кожному етапі моделювання ми беремо результати останнього кроку моделювання та робимо їх на роботі. Накопичення помилок на вершині помилок. Це ваш ефект метелика.

Я не думаю, що ми побачимо одну збірку, використовуючи одну нитку на одній машині, даючи різний вихід на одному вході. Однак на іншому верстаті це могло, або інша збірка могла.

Там є аргумент для тестування. Якщо ми вирішимо, як саме повинні працювати, і ми можемо протестувати на цільовому обладнання, ми не повинні розміщувати конструкції з іншою поведінкою.


Однак є також аргумент щодо того, щоб не працювати вдалині, що накопичує стільки помилок. Можливо, це можливість займатися фізикою по-іншому.

Як ви можете знати, існує неперервна і дискретна фізика, обидві працюють над тим, скільки б кожен об'єкт просунувся на часовий крок. Однак безперервна фізика має засоби з'ясувати момент зіткнення замість того, щоб перевірити різні можливі моменти, щоб побачити, чи сталося зіткнення.

Таким чином, я пропоную наступне: використовуйте методи безперервної фізики, щоб з'ясувати, коли відбудеться наступне зіткнення кожного об'єкта, з великим часовим кроком, набагато більшим за крок одного моделювання. Тоді ви берете найближчий момент зіткнення і з'ясовуєте, де все буде в цей момент.

Так, це велика робота одного кроку моделювання. Це означає, що моделювання не почнеться миттєво ...

... Однак ви можете імітувати наступні кілька кроків моделювання, не перевіряючи зіткнення кожен раз, тому що ви вже знаєте, коли відбудеться наступне зіткнення (або що у великому часовому кроці не відбувається зіткнення). Крім того, помилки, накопичені в цьому моделюванні, не мають значення, оскільки, як тільки моделювання досягає великого часового кроку, ми просто розміщуємо попередньо обчислені позиції.

Тепер ми можемо використовувати часовий бюджет, який ми використовували б для перевірки на зіткнення кожного кроку моделювання для обчислення наступного зіткнення після знайденого. Тобто ми можемо імітувати вперед, використовуючи великий часовий крок. Якщо припустити, що у світі обмежений обсяг (це не спрацює для величезних ігор), для моделювання повинна бути черга майбутніх станів, а потім кожен кадр, який ви просто інтерполюєте з останнього стану в наступний.


Я б заперечував за інтерполяцію. Однак, враховуючи, що є прискорення, ми не можемо просто інтерполювати все так само. Натомість нам потрібно інтерполювати з урахуванням прискорення кожного об'єкта. З цього питання ми можемо просто оновити позицію так само, як ми робимо для великого часового кроку (що також означає, що вона менш схильна до помилок, оскільки ми б не використовували дві різні реалізації для одного руху).


Примітка . Якщо ми робимо ці числа з плаваючою комою, такий підхід не вирішує проблему, коли предмети поводяться інакше, чим далі від походження. Однак, хоча це правда, що точність втрачається, чим далі ви йдете від походження, це все-таки детерміновано. Насправді, тому навіть не спочатку це підняли.


Додаток

Від ОП у коментарі :

Ідея полягає в тому, що гравці зможуть зберегти свої машини в якомусь форматі (наприклад, xml або json), щоб записати положення та обертання кожної деталі. Цей XML або json файл буде використаний для відтворення машини на комп'ютері іншого гравця.

Отже, жодного бінарного формату, правда? Це означає, що ми також повинні турбуватися, незалежно від відновлення чисел з плаваючою точкою, що відповідають оригіналу. Див.: Поточна точність переглянута: Переносимість дев'ятизначного поплавця


Коментарі не для розширеного обговорення; ця розмова переміщена до чату .
Vaillancourt

2
Чудова відповідь! Ще 2 бали на користь фіксованої точки: 1. плаваюча точка поводитиметься інакше ближче чи далі від початку (якщо у вас однакова головоломка в іншому місці), але фіксована точка не буде; 2. Фіксована точка фактично має більшу точність, ніж плаваюча точка на більшій частині свого діапазону - ви можете досягти точності, використовуючи добре фіксовану точку
Jibb Smart

Можливо кодування двійкових даних у обох XML та JSON за допомогою base64елементів. Це не ефективний спосіб подання великої кількості таких даних, але неправильно розуміти, що вони перешкоджають використанню бінарних представлень.
Пікалек

1
@Pikalek Я знаю, ОП запитав мене про це в коментарях, я згадував base64 як один з варіантів, серед яких, зокрема, шістнадцятковий, переосмислюється в якості int та використання формату protobuf, оскільки ніхто не зрозуміє ці файли, все-таки вони не є (непідготовлені ) людська читана. Потім - я припускаю - мод видалив коментарі (ні, це не в чаті, пов'язаному вище). Чи станеться це знову? Чи слід це видалити з відповіді? Чи варто робити це довше?
Тераот

@Theraot Ах, я бачу, як я міг би трактувати це по-різному в контексті видалених коментарів. (FWIW, я читав чати і на цю відповідь, і на питання). І навіть якщо існував нативний, ефективний спосіб кодування даних, все одно важливіше переконатися, що це означає те саме, що на всіх платформах. Зважаючи на рівномірність, можливо, найкраще просто залишити його так, як є. Дякуємо за уточнення!
Пікалек

6

Я працюю в компанії, яка займається певною відомою стратегічною грою в реальному часі, і можу вам сказати, що детермінізм з плаваючою комою можливий.

Використання різних компіляторів або одного і того ж компілятора з різними налаштуваннями, або навіть різних версій одного і того ж компілятора може все порушити детермінізм.

Якщо вам потрібен кроссплей між платформами або ігровими версіями, то, я думаю, вам знадобиться пройти фіксовану точку - єдиний можливий кроссплей, про який я знаю з плаваючою точкою, між ПК і XBox1, але це досить божевільно.

Вам потрібно буде або знайти двигун фізики, який повністю детермінований, або взяти двигун з відкритим кодом і зробити його детермінованим, або закатати власний двигун. У верхній частині голови у мене є відчуття, що Єдність усього іншого додала двигуна детермінованої фізики, але я не впевнений, чи це просто детермінований на одній машині чи детермінований на всіх машинах.

Якщо ви збираєтеся спробувати прокрутити свої речі, кілька речей, які можуть допомогти:

  • IEE754 поплавці є детермінованими, якщо ви не робите нічого надто фруктового (Google "IEE754 детермінізм" для отримання додаткової інформації про те, що є чи не охоплюється)
  • Потрібно переконатися, що кожен клієнт має свій режим округлення та точність встановлені однаково (використовуйте controlfp для його встановлення)
  • Режим округлення та точність можуть бути змінені певними математичними бібліотеками, тому, якщо ви використовуєте будь-які закриті вкладки, можливо, ви захочете перевірити їх після здійснення дзвінків (знову використовуючи контрольну процедуру для перевірки)
  • деякі інструкції SIMD детерміновані, багато - ні, будьте обережні
  • як було сказано вище, для забезпечення детермінізму вам також потрібна та сама платформа, така ж точна версія того ж компілятора, що збирає ту саму конфігурацію, з тими ж налаштуваннями компілятора
  • створити деякі інструменти для виявлення desyncs стану та допомогти їх діагностувати - наприклад, CRC ігрового стану, кожен кадр для виявлення, коли відбувається десинхронізація, а потім мати режим багатословного ведення журналу, який ви можете ввімкнути, коли зміни до ігрового стану ретельно входять у файл, потім візьміть 2 файли з симуляцій, які були розроблені з іншого, і порівняйте у різному інструменті, щоб побачити, де він пішов не так
  • ініціалізуйте всі ваші змінні в ігровому стані, головне джерело дизайну
  • вся імітація гри повинна відбуватися в абсолютно однаковому порядку щоразу, щоб уникнути десинків, це неймовірно просто зрозуміти це неправильно, бажано структурувати своє моделювання гри таким чином, що це мінімізує. Я справді не хлопець з дизайну програмного забезпечення, але в цьому випадку це, мабуть, гарна ідея - ви можете розглянути якийсь зразок, де моделювання гри схоже на безпечний ящик, і єдиний спосіб змінити ігровий стан - це вставити "повідомлення" або "команди", з доступом до const, що надається лише до будь-якого, що знаходиться поза станом гри (наприклад, візуалізація, мережа тощо). Отже, мережеве моделювання для багатокористувацької гри - це випадок надсилання цих команд по мережі, або повторне ж моделювання є випадком запису потоку команд вперше,

1
Єдність дійсно працює над метою детермінованості між платформами з їхньою новою системою фізики єдності для їхнього технологічного стеку, орієнтованого на дані, але, як я розумію, це все ще триває робота, яка ще не завершена / готова використатись з полиці.
DMGregory

Що таке приклад недетермінованої інструкції SIMD? Ви думаєте про наближених подібних rsqrtps?
Руслан

@DMGregory він повинен бути в попередньому попередньому перегляді, оскільки ви вже можете ним користуватися - але, як ви кажете, він ще не може бути закінчений.
Джо

@Ruslan так rsqrtps / rcpps результати залежать від впровадження
Джо

5

Я не впевнений, чи це тип відповіді, який ви шукаєте, але альтернативою може бути запуск обчислень на центральному сервері. Запропонуйте клієнтам надіслати конфігурацію на ваш сервер, дозвольте йому виконати моделювання (або отримати кешований) та надіслати назад результати, які потім інтерпретуються клієнтом і обробляються у графіку.

Звичайно, це відключає будь-які плани, які, можливо, доведеться запускати клієнта в автономному режимі, і залежно від того, наскільки обчислювально інтенсивні симуляції, вам може знадобитися дуже потужний сервер. Або кілька, але принаймні у вас є можливість переконатися, що вони мають однакову конфігурацію жорсткого та програмного забезпечення. Моделювання в реальному часі може бути важким, але не неможливим (подумайте про прямі потоки відео - вони працюють, але з невеликою затримкою).


1
Я повністю згоден. Таким чином ви гарантуєте спільний досвід з усіма користувачами. gamedev.stackexchange.com/questions/6645/… щось обговорює подібну тему, порівнюючи різницю між фізикою на стороні клієнта та фізикою.
Тім Холт

1

Я буду давати контр-інтуїтивну пропозицію, яка, хоча і не на 100% надійна, повинна працювати нормально більшу частину часу і дуже просто реалізується.

Зниження точності.

Використовуйте заздалегідь визначений постійний розмір крокового часу, виконайте фізику на кожному часовому кроці в стандартному повороті з подвійною точністю, але потім кількісно зменшуйте роздільну здатність всіх змінних на одноточну (або щось ще гірше) після кожного кроку. Тоді більшість можливих відхилень, які могло б запровадити переупорядкування з плаваючою комою (порівняно з еталонним запуском тієї ж програми), буде відрізано, оскільки ці відхилення трапляються у цифрах, які навіть не існують із зниженою точністю. Таким чином, відхилення не отримують шансу на наростання Ляпунова (ефект "Метелик"), який з часом стане помітним.

Звичайно, моделювання буде дещо менш точним, ніж могло б бути (порівняно з реальною фізикою), але це насправді не примітно, доки всі ваші програми неточні однаково .

З технічної точки зору, звичайно, можливо, що переупорядкування призведе до відхилення, яке доходить до цифри більш високої значущості, але якщо відхилення справді викликаються лише поплавком і ваші значення представляють собою постійні фізичні величини, це навряд чи. Зауважте, що doubleміж будь-якими двома з singleних є півмільярда значень , тому переважна більшість часових кроків у більшості моделей можна очікувати, що вони будуть однаковими між моделями. Мало сподіваємось, що в деяких випадках, коли відхилення роблять це шляхом кількісної оцінки, буде моделювання, яке не працює так довго (принаймні, не з хаотичною динамікою).


Я також рекомендую вам розглянути цілком протилежний підхід до того, про що ви питаєте: сприйняти невизначеність ! Якщо поведінка трохи недетерміновано, то це насправді ближче до фактичних фізичних експериментів. Отже, чому б не навмисно рандомізувати початкові параметри для кожного запуску моделювання, а не поставити перед ним вимогу, щоб моделювання здійснювалося послідовно протягом декількох випробувань? Це навчить набагато більше про фізику та про те, як сконструювати машини, щоб бути досить надійними / лінійними, а не надмірно тендітними, які реалізують лише в симуляції.


Округлення вниз не допоможе, тому що якщо результат високої точності не детермінований, то в підсумку результат збирається в один бік в одній системі, а в інший в інший. Наприклад, ви завжди можете округляти до найближчого цілого числа, але тоді один системний комп'ютер 1.0, а інший обчислює 0,999999999999999999999999999999999999999999, і вони округляються по-різному.
yoyo

Так, це можливо, як я вже говорив у відповіді. Але це станеться вкрай рідко , як і інші провали в фізиці ігор. Таким чином , округлення робить допомогу. (Я не хотів би
округлювати

0

Створіть власний клас для зберігання номерів!

Ви можете змусити детерміновану поведінку, якщо точно знаєте, як будуть виконуватися обчислення. Наприклад, якщо єдиними операціями, якими ви займаєтесь, є множення, ділення, додавання та віднімання, то було б достатньо представити всі числа як просто раціональне число. Для цього простий клас Раціональний був би чудово.

Але якщо ви хочете мати справу зі складнішими обчисленнями (можливо, наприклад, тригонометричними функціями), тоді вам доведеться писати такі функції самостійно. Якщо ви хочете мати можливість прийняти синус числа, вам доведеться записати функцію, яка наближає синус числа, використовуючи лише операції, згадані вище. Це все можливо, і, на мою думку, обходить більшу частину волохатих деталей в інших відповідях. Компроміс полягає в тому, що вам замість цього доведеться мати справу з якоюсь математикою.


3
Раціональна арифметика абсолютно нездійсненна для будь-якої чисельної інтеграції. Навіть якщо кожен часовий крок робиться лише * / + -тоді, знаменники з часом ставатимуть все більшими та більшими.
близько

Я б очікував, що навіть не враховуючи інтеграцію, це не буде хорошим рішенням, оскільки після декількох множень чи ділень цифри, що представляють ваш чисельник та знаменник, переповнять 64-бітове ціле число.
jvn91173

0

Тут є деяка плутанина термінології. Фізична система може бути повністю детермінованою, але неможливою для моделювання протягом корисного періоду часу, тому що її поведінка надзвичайно чутлива до початкових умов, а нескінченно мала зміна початкових умов призведе до зовсім іншого поведінки.

Ось відео реального пристрою, поведінка якого навмисно непередбачуване, за винятком статистичного сенсу:

https://www.youtube.com/watch?v=EvHiee7gs9Y

Неважко побудувати прості математичні системи (використовуючи лише додавання та множення), де результат після N кроків залежить від N-го десяткового місця стартових умов. Написання програмного забезпечення для послідовного моделювання такої системи на будь-якому комп’ютерному та програмному забезпеченні, яке може мати користувач, є майже неможливим - навіть якщо у вас бюджет достатньо великий, тестуйте програму на кожній ймовірній комбінації апаратного та програмного забезпечення.

Найкращий спосіб вирішити це - атакувати проблему біля її джерела: зробіть фізику своєї гри такою ж детермінованою, як це потрібно для отримання відтворюваних результатів.

Альтернативою є спробувати зробити його детермінованим шляхом налаштування комп'ютерного програмного забезпечення для моделювання чогось, що не є тим, що визначено фізикою. Проблема полягає в тому, що ви ввели ще кілька складних шарів у систему, порівняно з явною зміною фізики.

В якості конкретного прикладу, припустимо, ваша гра передбачає зіткнення жорстких тіл. Навіть якщо ви ігноруєте тертя, точне моделювання зіткнень між об'єктами довільної форми, які можуть крутитися, коли вони рухаються, на практиці неможливо. Але якщо змінити ситуацію, щоб єдиними об'єктами були прямокутні цегли, що не обертаються, життя стає набагато простішим. Якщо об’єкти у вашій грі не схожі на цеглу, то приховуйте цей факт за допомогою деякої "нефізичної" графіки - наприклад, буквально приховуйте мить зіткнення за димом чи полум’ям, або мультяшним текстовим бульбашкою "Ой" чи що завгодно.

Гравець повинен відкрити для себе фізику гри, граючи. Не має значення, чи не є "цілком реалістичним", якщо він є послідовним і схожий на здоровий глузд, щоб бути правдоподібним.

Якщо ви змусите себе фізику вести себе стабільно, комп'ютерна модель її також може дати стабільні результати, принаймні в тому сенсі, що помилки округлення будуть неактуальними.


1
Я не бачу ніякої плутанини в термінології. ОП хоче детермінованої поведінки від потенційно хаотичної системи. Це цілком можливо.
Марк

Використання більш простих фігур (таких як кола та прямокутники) зовсім не змінює проблему. Вам ще потрібно багато тригонометричних функцій, sqrt тощо ...
jvn91173

-1

Використовуйте подвійну точність з плаваючою точкою, а не точну точку з плаваючою точкою . Хоча це не ідеально, але він є досить точним, щоб вважати його детермінованим у вашій фізиці. Ви можете відправити на Місяць ракету з подвійною точністю з плаваючою точкою, але не одиничною точністю з плаваючою точкою.

Якщо вам справді потрібен ідеальний детермінізм, використовуйте математику з фіксованою точкою . Це дасть вам меншу точність (якщо використовувати однакову кількість біт), але детерміновані результати. Я не знаю жодних двигунів фізики, які використовують математику з фіксованою точкою, тому вам може знадобитися написати свій власний, якщо хочете пройти цей маршрут. (Щось, що я б порадив.)


11
Підхід з подвійною точністю відповідає ефекту метелика . У динамічній системі (як фізичний сим) навіть крихітні відхилення в початкових умовах можуть посилюватися завдяки зворотній зв'язці, сніговій кулі до відчутної помилки. Усі зайві цифри - це затримати це трохи довше - змушуючи сніжний ком котитися трохи далі, перш ніж він стане досить великим, щоб викликати проблеми.
DMGregory

2
Одразу дві помилки: 1) Подвійні плаваючі точки зазнають однакових проблем і зазвичай лише відкладають проблему в дедалі важче налагодження майбутнього. 2) Не існує правила, яке зазначає, що нерухома точка повинна бути менш точною, ніж плаваюча точка. Залежно від масштабу та проблеми, що склалася, або пам'яті, яку ви готові використовувати за номером фіксованої точки, вони можуть бути менш точними, однаково точними або більш точними. Немає сенсу говорити "вони менш точні".
phresnel

@phresnel, як приклад точності з фіксованою точкою, серія IBM 1400 використовувала десяткову математику з фіксованою точкою довільної точності. Присвячіть 624 цифри кожному номеру, і ви перевищили діапазон і точність плаваючої точки з подвійною точністю.
Марк

@phresnel (2) Хороший момент. Я оновив свою відповідь, щоб припустити однакову кількість біт.
Еворлор

-2

Скористайтеся шаблоном Memento .

У початковому виконанні збережіть від позиційних даних кожен кадр або будь-які необхідні орієнтири. Якщо це занадто неефективно, виконайте це лише на кожних n кадрах.

Потім, відтворюючи симуляцію, дотримуйтесь довільної фізики, але оновлюйте позиційні дані кожні n кадрів.

Надмірно спрощений псевдо-код:

function Update():
    if(firstRun) then (SaveData(frame, position));
    else if(reproducedRun) then (this.position = GetData(frame));

9
Я не думаю, що це працює для справи ОП. Скажімо, ми з вами граємо в різних системах. Кожен з нас розміщує фрагменти головоломки однаково - рішення, яке заздалегідь не було передбачено розробником. Після натискання кнопки "Пуск" ваш ПК моделює фізику таким чином, щоб рішення було успішним. Коли я роблю те саме, деяка невелика різниця в моделюванні призводить до того, що моє (однакове) рішення не оцінюється як успішне. Тут я не маю можливості проконсультуватися з пам'яткою з вашого успішного запуску, бо це сталося на вашій машині, а не в розробник.
DMGregory

@DMGregory Це правильно. Дякую.
jvn91173
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.