결정 론적 물리 시뮬레이션을 어떻게 수행 할 수 있습니까?


43

플레이어가 퍼즐 / 맵을 풀기 위해 조각과 부품을 이동시키는 강체와 관련된 물리 게임을 만들고 있습니다. 게임의 매우 중요한 측면은 플레이어가 시뮬레이션을 시작할 때 운영 체제, 프로세서 등에 관계없이 모든 곳 에서 동일하게 실행된다는 것입니다 .

복잡성이 많고 시뮬레이션이 오랫동안 실행될 수 있으므로 물리 엔진이 부동 소수점 연산과 관련하여 완전히 결정적이어야합니다. 그렇지 않으면 솔루션이 한 플레이어의 컴퓨터에서 "해결"되는 것처럼 보일 수 있습니다. 다른 사람에 "실패".

게임에서이 결정론을 어떻게 이해할 수 있습니까? Javascript, C ++, Java, Python 및 C #을 포함한 다양한 프레임 워크 및 언어를 사용하려고합니다.

필자는 필자의 요구를 충족시키는 것처럼 Box2D (C ++)와 다른 언어의 해당 기능에 유혹을 받았지만 특히 삼각 함수와 관련하여 부동 소수점 결정 성이 부족합니다.

지금까지 내가 본 최고의 옵션은 Box2D의 Java와 동등한 것 (JBox2D)입니다. 많은 작업 StrictMath대신 에 사용하여 부동 소수점 결정을 시도하는 것처럼 Math보이지만이 엔진이 아직 게임을 빌드하지 않은 상태에서 필요한 모든 것을 보장하는지 여부는 확실하지 않습니다.

필요에 따라 기존 엔진을 사용하거나 수정할 수 있습니까? 아니면 내 엔진을 직접 만들어야합니까?

편집 : 누군가가 왜 그런 정밀도가 필요한지 신경 쓰지 않는다면이 게시물의 나머지 부분을 건너 뛰십시오. 의견과 답변을받은 개인은 내가하지 말아야 할 것을 추구한다고 생각하는 것 같습니다. 따라서 게임이 어떻게 작동하는지 더 설명 할 것입니다.

플레이어에게는 장애물과 목표가 포함 된 퍼즐이나 레벨이 부여됩니다. 초기에는 시뮬레이션이 실행되고 있지 않습니다. 그런 다음 제공된 조각이나 도구를 사용하여 기계를 만들 수 있습니다. 시작을 누르면 시뮬레이션이 시작되고 더 이상 기계를 편집 할 수 없습니다. 기계가지도를 해결하면 플레이어가 레벨을 이겼습니다. 그렇지 않으면 중지를 누르고 기계를 변경 한 후 다시 시도해야합니다.

모든 것이 결정 론적이어야하는 이유는 각 조각의 위치, 크기 및 회전을 기록하여 모든 컴퓨터 (레벨을 해결하려고하는 조각 및 도구 세트)를 xml 또는 json 파일에 매핑하는 코드를 생성 할 계획이기 때문입니다. 그런 다음 플레이어가 해결 (이 파일로 표시)을 공유하여 해결을 확인하고, 서로로부터 배우고, 경쟁을 개최하고, 공동 작업하는 등의 작업을 수행 할 수 있습니다. 물론 대부분의 해결은 특히 간단하거나 빠릅니다. 결정론의 결여로 영향을받지 않습니다. 그러나 실제로 어려운 레벨을 해결하는 느리거나 복잡한 디자인은 아마도 가장 흥미롭고 공유 할 가치가있는 디자인 일 것입니다.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 . 문제에 대한 해결책이 있다고 생각되면 의견이 아니라 답변으로 게시하십시오. 이렇게하면 편집, 투표 / 마킹을 통해 평가하거나 의견이 아닌 의견 자체에 직접 의견을 제시 할 수 있습니다. 위빙은 더 긴 대화 스레드로 응답합니다.
DMGregory

답변:


45

결정적 방식으로 부동 소수점 숫자 처리

부동 소수점은 결정적입니다. 글쎄요. 복잡하다.

부동 소수점 숫자에 대한 많은 문헌이 있습니다.

그리고 그들이 어떻게 문제가되는지 :

초록. 적어도 단일 스레드에서 동일한 순서로 발생하는 동일한 데이터를 가진 동일한 작업은 결정 론적이어야합니다. 따라서 입력에 대한 걱정과 재정렬로 시작할 수 있습니다.


문제를 일으키는 그러한 입력 중 하나는 시간입니다.

우선, 항상 같은 타임 스텝을 계산해야합니다. 시간을 측정하지 말라고 말하는 것이 아닙니다. 시간의 변화는 시뮬레이션의 노이즈 소스이기 때문에 물리 시뮬레이션에 시간을 보내지 않을 것이라고 말하고 있습니다.

물리 시뮬레이션에 시간을 전달하지 않으면 왜 시간을 측정합니까? 시뮬레이션 단계를 언제 호출해야하는지 알기 위해 경과 시간을 측정하려고합니다 (잠자기를 사용한다고 가정 할 경우).

그러므로:

  • 측정 시간 : 예
  • 시뮬레이션에서 시간 사용 : 아니오

이제 명령 순서 변경.

컴파일러는와 f * a + b같은 것을 결정할 수 b + f * a있지만 결과가 다를 수 있습니다. 또한 fmadd로 컴파일 하거나 SIMD를 사용 하여 작성하는 것과 같은 여러 줄을 취 하거나 현재 생각할 수없는 다른 최적화를 결정할 수 있습니다. 그리고 동일한 작업이 동일한 순서로 발생하기를 원한다는 것을 기억하십시오. 이는 어떤 작업이 수행되는지 제어하려는 이유입니다.

그리고 아니요, double을 사용해도 저장되지 않습니다.

특히 네트워크에서 부동 소수점 숫자를 동기화하려면 컴파일러와 해당 구성에 대해 걱정해야합니다. 동일한 작업을 수행하려면 빌드를 가져와야합니다.

틀림없이 글쓰기 어셈블리가 이상적 일 것입니다. 그렇게하면 어떤 작업을 수행할지 결정할 수 있습니다. 그러나 이는 여러 플랫폼을 지원하는 데 문제가 될 수 있습니다.

그러므로:

  • 어른 ... 흠 ... 부동 소수점 숫자를 처리하는 방법을 구성 할 수있는 컴파일러를 사용하십시오 . 예를 들어 / fp (부동 소수점 동작 지정) 를 참조하십시오 .

고정 소수점 수의 경우

플로트가 메모리에 표시되는 방식으로 인해 큰 값은 정밀도를 잃게됩니다. 값을 작게 (클램프) 유지하면 문제가 완화 될 수 있습니다. 따라서 큰 속도와 방이 없습니다. 또한 터널링의 위험이 적기 때문에 이산 물리학을 사용할 수 있습니다.

반면에 작은 오류가 누적됩니다. 자르십시오. 나는 정수형으로 스케일하고 캐스트하는 것을 의미합니다. 그렇게하면 아무것도 구축되지 않는다는 것을 알 수 있습니다. 정수 유형으로 머무를 수있는 작업이 있습니다. 부동 소수점으로 돌아 가야 할 때 스케일링을 캐스팅하고 실행 취소합니다.

나는 스케일이라고 말합니다. 아이디어는 1 단위가 실제로 2의 거듭 제곱으로 표시된다는 것입니다 (예 : 16384). 그것이 무엇이든, 그것을 일정하게 만들고 사용하십시오. 기본적으로 고정 소수점 숫자로 사용하고 있습니다. 사실, 신뢰할 수있는 라이브러리의 적절한 고정 소수점 수를 훨씬 더 잘 사용할 수 있다면.

나는 자르고있다. 반올림 문제에 대해, 이는 캐스트 후 얻은 값의 마지막 비트를 신뢰할 수 없음을 의미합니다. 따라서 캐스트 스케일이 필요하기 전에 1 비트 이상을 확보 한 후 나중에 잘립니다.

그러므로:

  • 값을 작게 유지하십시오 : 예
  • 주의해서 반올림 : 예
  • 가능한 경우 고정 소수점 수 : 예

잠깐, 왜 부동 소수점이 필요한가요? 정수 유형으로 만 작업 할 수 없습니까? 아 맞다 삼각법 및 복사. 삼각법 및 복사에 대한 테이블을 계산하여 소스에서 구워 낼 수 있습니다. 또는 고정 소수점 숫자를 대신 사용하는 것을 제외하고 부동 소수점 숫자로 알고리즘을 계산하는 데 사용되는 알고리즘을 구현할 수 있습니다. 예, 메모리, 성능 및 정밀도의 균형을 유지해야합니다. 그러나 부동 소수점 숫자를 피하고 결정론을 유지할 수 있습니다.

오리지널 PlayStation에서 그런 것들을했다는 것을 알고 있습니까? 제발 , 패치를 만나 내 개 .

그건 그렇고, 나는 그래픽에 부동 소수점을 사용하지 말라고 말하지 않습니다. 물리학을 위해서만 물리학에 따라 위치가 달라집니다. 그러나 알다시피 충돌체가 모델과 일치하지 않아도됩니다. 모델이 잘린 결과를보고 싶지 않습니다.

따라서 : 고정 소수점 숫자를 사용하십시오.


분명히 말하면, 부동 소수점의 작동 방식을 지정할 수있는 컴파일러를 사용할 수 있고 그 정도면 충분합니다. 항상 옵션은 아닙니다. 게다가, 우리는 결정론을 위해 이것을하고 있습니다. 고정 소수점 숫자는 정밀도가 제한되어 있어도 오류가 없음을 의미하지 않습니다.

나는 "고정 포인트 번호가 어렵다"고 생각하지 않는 것이 좋은 이유라고 생각합니다. 그리고 당신이 그것들을 사용해야 할 좋은 이유를 원한다면, 그것은 결정론, 특히 플랫폼 간 결정론입니다.


또한보십시오:


부록 : 나는 세상의 크기를 작게 유지할 것을 제안하고 있습니다. 그러나 두 OP ans Jibb Smart는 원점 수레에서 멀어지면 정확도가 떨어집니다. 그것은 물리학에 영향을 미치며, 이는 세계의 가장자리보다 훨씬 일찍 보일 것입니다. 고정 소수점 숫자는 고정 정밀도를 가지며 어디에서나 동일하게 좋을 것입니다. 결정론을 원한다면 좋습니다. 또한 우리가 일반적으로 물리를하는 방식에는 작은 변형을 증폭시키는 성질이 있다고 언급하고 싶습니다. Incredible Machine and Contraption Maker의 버터 플라이 효과 결정적 물리를 참조하십시오 .


물리를 수행하는 또 다른 방법

부동 소수점 숫자의 정밀도에서 작은 오류가 증폭되는 이유는 그 숫자에 대해 반복을 수행하기 때문입니다. 각 시뮬레이션 단계는 마지막 시뮬레이션 단계의 결과를 가져 와서 수행합니다. 오류 발생시 오류를 누적합니다. 그것은 당신의 나비 효과입니다.

동일한 머신에서 단일 스레드를 사용하는 단일 빌드가 동일한 입력으로 다른 출력을 생성한다고 생각하지 않습니다. 그러나 다른 컴퓨터에서는 또는 다른 빌드에서 가능합니다.

거기에서 테스트 할 논증이 있습니다. 작업 방식을 정확하게 결정하고 대상 하드웨어를 테스트 할 수 있다면 다른 동작을 가진 빌드를 작성해서는 안됩니다.


그러나 너무 많은 오류가 누적되는 작동하지 않는 것에 대한 주장도 있습니다. 아마도 이것은 다른 방식으로 물리학을 할 수있는 기회 일 것입니다.

아시다시피, 연속적이고 이산적인 물리학이 있습니다. 둘 다 각 단계에서 각 물체가 얼마나 많은 양으로 진행되는지에 관한 연구입니다. 그러나 연속 물리학은 충돌이 발생했는지 확인하기 위해 서로 다른 가능한 순간을 조사하는 대신 충돌 순간을 파악할 수있는 수단을 가지고 있습니다.

따라서, 나는 다음을 제안하고있다 : 연속적인 물리학 기법을 사용하여 각 물체의 다음 충돌이 언제 일어날 지 알아 내고, 단일 시뮬레이션 단계보다 훨씬 더 큰 시간 간격을두고. 그런 다음 가장 가까운 충돌 순간을 가져 와서 그 순간의 모든 위치를 알아냅니다.

그렇습니다. 이는 단일 시뮬레이션 단계의 많은 작업입니다. 즉, 시뮬레이션이 즉시 시작되지 않습니다.

... 그러나 다음 충돌이 언제 발생할지 이미 알고 있기 때문에 (또는 큰 타임 스텝에서 충돌이 발생하지 않음) 매번 충돌을 확인하지 않고 다음 몇 개의 시뮬레이션 단계를 시뮬레이션 할 수 있습니다. 더욱이, 시뮬레이션이 큰 타임 스텝에 도달하면, 우리는 미리 계산 한 위치를 배치하기 때문에 시뮬레이션에 축적 된 오류는 무의미합니다.

이제 각 시뮬레이션 단계에서 충돌을 확인하는 데 사용한 시간 예산을 사용하여 발견 된 충돌 이후의 다음 충돌을 계산할 수 있습니다. 즉, 큰 시간 단계를 사용하여 미리 시뮬레이션 할 수 있습니다. 범위가 제한된 월드 (거대한 게임에서는 작동하지 않음)를 가정하면 시뮬레이션을위한 미래 상태 대기열이 있어야합니다. 그런 다음 각 프레임은 마지막 상태에서 다음 상태로 보간됩니다.


보간을 주장합니다. 그러나 가속이 있기 때문에 모든 것을 같은 방식으로 보간 할 수는 없습니다. 대신 각 개체의 가속도를 고려하여 보간해야합니다. 그 문제에 대해 우리는 큰 시간 단계와 같은 방식으로 위치를 업데이트 할 수 있습니다 (또한 동일한 움직임에 대해 두 가지 다른 구현을 사용하지 않기 때문에 오류가 덜 발생합니다).


참고 :이 부동 소수점 숫자를 수행하는 경우이 방법으로 객체가 원점에서 멀어 질수록 다르게 동작하는 문제를 해결할 수 없습니다. 그러나 원점에서 멀어 질수록 정밀도가 손실되는 것은 사실이지만 여전히 결정적입니다. 사실, 그것은 원래 그것을 제기하지 않은 이유입니다.


추가

의견의 OP에서 :

아이디어는 플레이어가 자신의 머신을 xml 또는 json과 같은 일부 형식으로 저장하여 각 조각의 위치와 회전을 기록 할 수 있다는 것입니다. 그런 다음 해당 xml 또는 json 파일을 사용하여 다른 플레이어의 컴퓨터에서 컴퓨터를 재생성합니다.

따라서 이진 형식이 없습니다. 즉, 복구 된 부동 소수점 숫자가 원본과 일치하는지 걱정할 필요가 없습니다. 참고 : Float Precision Revisited : 9 Digit Float Portability


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Vaillancourt

2
좋은 답변입니다! 고정 소수점에 찬성하여 2 개 이상의 포인트 : 1. 부동 소수점은 원점과 다르게 가까워 지거나 멀어 질 것입니다 (다른 장소에 같은 퍼즐이있는 경우). 2. 고정 소수점은 실제로 대부분의 범위에서 부동 소수점 보다 정밀도가 높습니다. 고정 소수점을 잘 사용하면 정밀도를 얻을 수 있습니다.
Jibb Smart

base64요소를 사용하여 XML 및 JSON으로 이진 데이터를 인코딩 할 수 있습니다 . 이러한 많은 양의 데이터를 표현하는 효율적인 방법은 아니지만 이진 표현의 사용을 막는 것은 아닙니다.
Pikalek

1
@Pikalek 나는 알고있다 .OP는 의견에 대해 나에게 물었다. 나는 16 진수, int로 캐스트를 재 해석하고 프로토 타입 형식을 사용하는 것을 포함하여 base64를 하나의 옵션으로 언급했다. ) 인간 판독 가능. 그런 다음-나는 가정합니다-mod가 주석을 제거했습니다 (아니, 위에 링크 된 채팅에 없습니다). 다시 일어날까요? 답변에서 제거해야합니까? 더 길게 만들어야합니까?
Theraot

@ Theraot 아, 삭제 된 주석의 맥락에서 어떻게 다르게 해석했는지 볼 수 있습니다. (FWIW, 나는이 답변과 질문에 대한 채팅을 읽었습니다). 그리고 데이터를 인코딩하는 기본적이고 효율적인 방법이 있었음에도 여전히 플랫폼간에 동일한 의미를 갖는지 확인하는 것이 더 중요합니다. 변동이 주어지면 그대로 두는 것이 가장 좋습니다. 설명해 주셔서 감사합니다!
Pikalek

6

저는 잘 알려진 실시간 전략 게임을 만드는 회사에서 일하며 부동 소수점 결정이 가능하다고 말할 수 있습니다.

다른 컴파일러 또는 다른 설정을 가진 동일한 컴파일러를 사용하거나 같은 컴파일러의 다른 버전을 사용하면 결정 성이 깨질 수 있습니다.

플랫폼이나 게임 버전간에 크로스 플레이가 필요한 경우 고정 소수점으로 이동해야한다고 생각합니다. 유동 소수점으로 알고있는 유일한 크로스 플레이는 PC와 XBox1 사이에서만 가능하지만 정말 미친 듯합니다.

완전히 결정적인 물리 엔진을 찾거나 오픈 소스 엔진을 사용하여 결정적으로 만들거나 자신의 엔진을 굴려야합니다. 내 머리 꼭대기에서 나는 모든 것들의 Unity가 결정 론적 물리 엔진을 추가했다고 생각하지만, 그것이 동일한 머신에서 결정적인지 모든 머신에서 결정적인지 확실하지 않습니다.

자신만의 물건을 굴 리려고 할 때 도움이 될만한 몇 가지 사항 :

  • 과일을 너무 많이 먹지 않으면 IEE754 수레가 결정 론적입니다.
  • 모든 클라이언트에 반올림 모드와 정밀도가 동일하게 설정되어 있는지 확인해야합니다 (controlfp를 사용하여 설정)
  • 반올림 모드와 정밀도는 특정 수학 라이브러리에 의해 변경 될 수 있으므로 닫힌 라이브러리를 사용하는 경우 전화를 한 후 다시 확인해야 할 수 있습니다 (controlfp를 사용하여 확인)
  • 일부 SIMD 명령어는 결정 론적이며 많은 것이 아니므로 조심하십시오
  • 위에서 언급했듯이 결정 성을 보장하려면 동일한 컴파일러 설정으로 동일한 구성, 동일한 구성을 컴파일하는 동일한 플랫폼의 동일한 컴파일러가 필요합니다.
  • 상태 비 동기화를 감지하고 진단하는 데 도움이되는 툴링을 구축합니다. 예를 들어, 매 프레임마다 게임 상태를 CRC하여 비동기 화가 발생한시기를 감지 한 다음 게임 상태에 대한 수정이 파일에 힘들게 기록되는 곳에서 자세한 로깅 모드를 사용할 수 있습니다. 그런 다음 서로 동기화되지 않은 시뮬레이션에서 2 개의 파일을 가져 와서 diff 도구를 비교하여 잘못된 위치를 봅니다.
  • 게임 상태에서 모든 변수를 초기화, 주요 비동기 소스
  • 전체 게임 시뮬레이션은 비 동기화를 피하기 위해 매번 정확히 같은 순서로 발생해야하며,이를 잘못 이해하는 것은 매우 쉽습니다.이를 최소화하는 방식으로 게임 시뮬레이션을 구성하는 것이 좋습니다. 나는 실제로 소프트웨어 디자인 패턴 사람은 아니지만이 경우 아마도 좋은 생각 일 것입니다. 게임 시뮬레이션이 안전한 상자와 같은 패턴을 고려할 수 있으며 게임 상태를 변경하는 유일한 방법은 삽입하는 것입니다 "메시지"또는 "명령", 게임 상태 이외의 모든 것에 대한 const 액세스 만 제공합니다 (예 : 렌더링, 네트워킹 등). 따라서 멀티 플레이어 게임을위한 시뮬레이션 네트워킹은 네트워크를 통해 이러한 명령을 전송하거나 동일한 시뮬레이션을 재생하는 것이 처음으로 명령 스트림을 기록하는 경우입니다.

1
Unity는 실제로 데이터 지향 기술 스택을위한 새로운 Unity Physics 시스템을 사용하여 크로스 플랫폼 결정의 목표를 향해 노력하고 있지만 이해하지만 여전히 진행 중이며 아직 완성되지 않은 상태입니다.
DMGregory

비 결정적 SIMD 명령의 예는 무엇입니까? 당신은 대략적인 것들을 생각하고 rsqrtps있습니까?
Ruslan

@DMGregory 이미 사용할 수 있으므로 미리보기에 있어야하지만 아직 완료되지 않았을 수도 있습니다.

@Ruslan 예 rsqrtps / rcpps 결과는 구현에 따라 다릅니다
Joe

5

이것이 당신이 찾고있는 대답 유형인지 확실하지 않지만 대안 중앙 서버에서 계산을 실행하는 것일 수 있습니다. 클라이언트가 구성을 서버로 보내도록하고 시뮬레이션을 수행 (또는 캐시 된 것을 검색) 한 다음 결과를 다시 보내도록합니다. 결과는 클라이언트가 해석하여 그래픽으로 처리합니다.

물론, 이렇게하면 오프라인 모드에서 클라이언트를 실행해야하는 계획이 종료되고 계산 집약적 인 시뮬레이션에 따라 매우 강력한 서버가 필요할 수 있습니다. 또는 여러 개이지만 적어도 동일한 하드 및 소프트웨어 구성을 갖는 옵션이 있습니다. 실시간 시뮬레이션은 어렵지만 불가능하지는 않습니다 (실시간 비디오 스트림을 생각하십시오-작동하지만 약간의 지연이 있습니다).


1
완전히 동의 해. 이것이 모든 사용자와의 공유 경험을 보장하는 방법입니다. gamedev.stackexchange.com/questions/6645/… 클라이언트 측과 서버 측 물리의 차이점을 비교하여 비슷한 주제에 대해 설명합니다.
팀 홀트

1

100 % 신뢰할 수는 없지만 대부분의 경우 제대로 작동하고 구현하기가 쉽다는 반 직관적 인 제안을하겠습니다.

정밀도를 줄입니다.

미리 결정된 일정한 시간 단계 크기를 사용하고 표준 배정 밀도 부동 소수점에서 각 시간 단계에 대해 물리를 수행 한 다음 각 단계 후에 모든 변수의 분해능을 단정도 (또는 더 나쁜 것)로 정량화합니다. 그런 다음 부동 소수점 재정렬로 인해 발생할 수있는 가능한 대부분의 편차 (동일한 프로그램의 기준 실행과 비교하여)는 편차가 감소 된 정밀도에는 존재하지 않는 숫자로 발생하기 때문에 잘릴 수 있습니다. 따라서 편차로 인해 Lyapunov 빌드 업 (버터 플라이 효과)이 발생하지 않아 결국 눈에 띄게됩니다.

물론 시뮬레이션은 실제 물리와 비교할 때보 다 정확도가 약간 떨어질 것이지만, 모든 프로그램 실행이 동일한 방식으로 부정확 한 한 실제로 주목할만한 것은 아닙니다 .

기술적으로 말하자면, 재정렬로 인해 편차가 더 높은 유효 자릿수에 도달 할 가능성이 있지만, 편차가 실제로 부동으로 만 발생하고 값이 연속 물리량을 나타내는 경우에는 그럴 가능성이 거의 없습니다. double두 값 사이에 50 억 개의 값이 single있으므로 대부분의 시뮬레이션에서 대부분의 시간 단계는 시뮬레이션 실행간에 정확히 동일 할 것으로 예상 할 수 있습니다. 편차로 인해 양자화를 통해 편차가 발생하는 경우는 그다지 오래 걸리지 않는 시뮬레이션에있을 것입니다 (적어도 혼돈 된 역학에서는 그렇지 않음).


나는 또한 당신이 요구하는 것에 대해 완전히 반대되는 접근법을 고려할 것을 권한다 : 불확실성을 포용하라 ! 행동이 약간 결정적이지 않으면 실제로 실제 물리 실험에 더 가깝습니다. 그렇다면 각 시뮬레이션 실행에 대한 시작 매개 변수를 의도적으로 무작위 화 하지 않고 시뮬레이션 이 여러 번의 시행에서 일관되게 성공해야하는 이유는 무엇입니까? 그것은 물리학에 대해, 그리고 시뮬레이션에서만 현실적으로 작동하는 초약 한 기계보다는 충분히 견고 / 선형으로 기계를 설계하는 방법에 대해 더 많이 배울 것입니다.


내림차순은 도움이되지 않습니다. 고정밀 결과가 결정적이지 않은 경우 결과는 한 시스템에서 한 방향으로, 다른 시스템에서 다른 방식으로 반올림하기 때문입니다. 예를 들어 항상 가장 가까운 정수로 반올림 할 수 있지만 한 시스템 컴퓨터 1.0과 다른 시스템은 0.99999999999999999999999999999999999999999999를 계산하고 다르게 반올림합니다.
yoyo

예, 이미 답변에서 말했듯이 가능합니다. 그러나 게임 물리학의 다른 결함과 마찬가지로 극히 드물게 발생 합니다. 반올림 도움이됩니다. ( 하지만 반올림 하지는 않습니다 .
편중

0

숫자를 저장하기위한 자신 만의 클래스를 만드십시오!

계산이 어떻게 수행되는지 정확하게 알고 있다면 결정 론적 행동을 강요 할 수 있습니다. 예를 들어, 처리하는 유일한 연산이 곱셈, 나누기, 덧셈 및 뺄셈이면 모든 숫자를 합리적인 숫자로 나타내는 것으로 충분합니다. 이를 위해서는 간단한 Rational 클래스가 적합하다.

그러나 더 복잡한 계산 (예 : 삼각 함수)을 처리하려면 이러한 함수를 직접 작성해야합니다. 숫자의 사인을 얻을 수 있으려면 위에서 언급 한 연산 만 사용하면서 숫자의 사인을 근사하는 함수를 작성할 수 있어야합니다. 이것은 모두 가능하며 내 의견으로는 다른 답변에서 많은 털이 많은 세부 사항을 우회합니다. 단점은 대신 수학을 처리해야한다는 것입니다.


3
모든 종류의 수치 적분에는 합리적인 산술이 불가능합니다. 각 시간 단계 만 수행하더라도 * / + -분모는 시간이 지남에 따라 점점 커집니다.
왼쪽

통합을 고려하지 않아도 몇 번의 곱셈이나 나눗셈 후에 분자와 분모를 나타내는 숫자가 64 비트 정수를 오버플로하기 때문에 이것은 좋은 해결책이 아닐 것이라고 기대합니다.
jvn91173

0

여기에는 용어의 혼동이 있습니다. 물리적 시스템은 완전히 결정 론적이지만 동작이 초기 조건에 매우 민감하기 때문에 유용한 기간 동안 모델링하기가 불가능하며 초기 조건의 무한한 작은 변화는 완전히 다른 동작을 생성합니다.

통계적 의미를 제외하고 의도적으로 예측할 수없는 실제 장치의 비디오는 다음과 같습니다 .

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

N 단계 이후의 결과가 시작 조건의 N 번째 소수점 자리에 따라 달라지는 간단한 수학적 시스템 (가산 및 곱셈 만 사용)을 쉽게 구성 할 수 있습니다. 사용자가 가질 수있는 모든 컴퓨터 하드웨어 및 소프트웨어에서 이러한 시스템을 일관되게 모델링하기 위해 소프트웨어를 작성 하는 것은 예산과 예산이 충분하더라도 가능한 모든 하드웨어 및 소프트웨어 조합에서 응용 프로그램을 테스트 할 수 없습니다.

이 문제를 해결하는 가장 좋은 방법은 문제의 근원을 공격하는 것입니다. 게임의 물리학을 재현 가능한 결과를 얻는 데 필요한 결정 론적 요소로 만듭니다.

대안은 모델 뭔가 컴퓨터 소프트웨어 조정하여 결정적 만들려고하는 것입니다 하지 물리학 지정 무엇을. 문제는 물리를 명시 적으로 변경하는 것과 비교하여 시스템에 몇 가지 더 복잡한 계층을 도입했다는 것입니다.

특정 예로서, 게임에 강체 충돌이 있다고 가정합니다. 마찰을 무시하더라도, 움직일 때 회전 할 수있는 임의의 모양의 물체 간의 정확한 충돌 모델링은 실제로 불가능합니다. 그러나 물체가 회전하지 않는 직사각형 벽돌 만되도록 상황을 변경하면 인생이 훨씬 간단 해집니다. 게임의 오브젝트가 벽돌처럼 보이지 않는 경우, "비 물리적"그래픽으로 사실을 숨기십시오. 예를 들어 연기 나 불꽃 뒤에 충돌하는 순간을 숨기거나 만화 텍스트 버블 "Ouch" 또는 무엇이든.

플레이어는 게임을 통해 게임 물리 를 발견해야 합니다. 자기 일관성이 있고 상식적인 경험이 그럴듯 해 보일 정도로 "완전히 현실적이지"않는지는 중요하지 않습니다.

물리학 자체가 안정적인 방식으로 동작하게되면, 컴퓨터 모델도 최소한 반올림 오류와 관련이 없다는 의미에서 안정적인 결과를 얻을 수 있습니다.


1
용어가 혼동되지 않습니다. OP는 혼란스러운 시스템에서 결정적인 행동을 원합니다. 그것은 전적으로 가능합니다.
마크

더 간단한 모양 (예 : 원 및 사각형)을 사용해도 문제가 전혀 바뀌지 않습니다. 여전히 삼각 함수, sqrt 등이 많이 필요합니다.
jvn91173

-1

단일 부동 소수점 정밀도 대신 이중 부동 소수점 정밀도를 사용하십시오 . 완벽하지는 않지만 물리학에서 결정 론적이라고 생각할만큼 정확합니다. 부동 소수점 정밀도는 두 배인 부동 소수점 정밀도로 달에 로켓을 보낼 수 있습니다.

완벽한 결정 성이 필요한 경우 고정 소수점 수학을 사용하십시오 . 이렇게하면 정밀도가 떨어지지 만 (같은 수의 비트를 사용한다고 가정) 결정적인 결과가 나타납니다. 고정 소수점 수학을 사용하는 물리 엔진을 알지 못하므로이 길을 가고 싶다면 직접 작성해야 할 수도 있습니다. (내가 조언하는 것)


11
배정도 접근법은 버터 플라이 효과를 무시 합니다 . (물리 시뮬레이션과 같은) 동적 시스템에서 초기 조건의 작은 편차조차도 피드백을 통해 증폭 될 수 있으며, 눈에 띄는 오류까지 눈을 ing 수 있습니다. 여분의 숫자는 이것을 조금 더 지연시키는 것입니다. 눈덩이가 문제를 일으킬 정도로 커지기 전에 조금 더 굴 리도록 강요합니다.
DMGregory

2
한 번에 두 가지 실수 : 1) 이중 부동 소수점은 동일한 문제를 겪고 일반적으로 미래를 디버그하기가 더 어려운 문제로 연기합니다. 2) 고정 소수점이 부동 소수점보다 덜 정확해야한다는 규칙은 없습니다. 스케일과 당면한 문제 또는 고정 소수점 수마다 사용할 준비가 된 메모리에 따라 정확도가 떨어질 수 있습니다. "정확하지 않다"고 말하는 것은 말이되지 않습니다.
프레 넬

@phresnel은 고정 소수점 정밀도의 예로 IBM 1400 시리즈가 임의 정밀도 고정 소수점 10 진수 수학을 사용했습니다. 각 숫자에 624 자리를 사용하면 배정 밀도 부동 소수점 의 범위 정밀도를 초과했습니다 .
마크

@phresnel (2) 좋은 지적입니다. 같은 수의 비트를 가정하도록 답변을 업데이트했습니다.
Evorlor

-2

Memento 패턴을 사용하십시오 .

초기 실행에서 각 프레임 또는 필요한 벤치 마크 위치 데이터를 저장하십시오. 그것이 너무 성능이 좋지 않으면 n 프레임마다 수행하십시오.

그런 다음 시뮬레이션을 재현 할 때 임의의 물리를 따르지만 n 프레임마다 위치 데이터를 업데이트하십시오.

지나치게 단순화 된 의사 코드 :

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

9
나는 이것이 OP의 경우에는 효과가 없다고 생각합니다. 당신과 나 둘 다 다른 시스템에서 게임을하고 있다고 가정 해 봅시다. 우리 각자는 퍼즐 조각을 같은 방식으로 배치합니다. 개발자가 미리 예측하지 못한 솔루션입니다. "시작"을 클릭하면 PC가 물리를 시뮬레이션하여 솔루션이 성공합니다. 내가 똑같이 할 때, 시뮬레이션에서 약간의 작은 차이로 인해 (동일한) 솔루션이 성공적으로 평가되지 않습니다. 여기서는 성공적인 실행에서 메멘토를 상담 할 기회가 없습니다. 왜냐하면 그것은 기계가 아닌 기계에서 일어났기 때문입니다.
DMGregory

@DMGregory 맞습니다. 감사합니다.
jvn91173
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.