드워프 요새는 성능을 잃지 않으면 서 어떻게 많은 개체를 추적합니까? Fortress에서는 한 번에 수백 가지의 드워프,

Dwarf Fortress에서는 한 번에 수백 가지의 드워프, 동물, 고블린 등을 게임에 넣을 수 있으며 각각 고유 한 복잡한 AI 및 길 찾기 루틴이 있습니다. 내 질문은 이것이 어떻게 눈에 띄게 느려지지 않습니까? 각 드워프는 자체 스레드에서 실행됩니까?



답변

너무 많은 문자 각각에 스레드가있는 시스템에는 리소스가 매우 빨리 소모됩니다. 스레드를 사용하면 추가 프로세서 코어에 액세스 할 수 있지만 본질적으로 더 효율적인 것은 없으며 오버 헤드가 발생합니다.

간단한 대답은 게임에서 각 엔티티를 처리하는 데 효율적입니다.

  • 각 프레임마다 모든 엔티티를 처리하지 마십시오.
  • 처리를 자주 수행해야하는 작업과 자주 수행하지 않는 작업으로 분할하십시오.
  • 장기 실행 알고리즘을 여러 프레임에 분산시켜 다른 시스템의 처리를 차단하지 않도록합니다.
  • 효율적인 알고리즘 및 데이터 구조가 사용되는지 확인하십시오.
  • 값 비싼 계산 결과를 다시 사용할 가능성이 높은 경우 캐시하십시오.

답변

Dwarf Fortress는 오픈 소스가 아니며 모든 작동 방식에 적용 할 수있는 많은 추측 및 리버스 엔지니어링이 있지만 대신 3D (3D 그래픽이 아닌 3D 세계) 로그 라이크를 최적화하는 몇 가지 기본 기술에 중점을 둘 것입니다. 같은 타입.

모든 비디오 게임의 경우와 마찬가지로 간단한 규칙과 시스템에서 복잡한 환상을 만들어내는 많은 연기와 거울이 있습니다. 이것들은 단순한 난수를 사용하여 겨냥한 움직임을 없애는 것에서부터 길 찾기를 위해 높은 수준의 노드 메쉬를 사전 베이킹하는 것까지 다양합니다.

운동

길 찾기에 대해 말하면, DF 맵 (768x768x64 IIRC 정도)과 같은 넓은 공간에서 해결하기가 매우 어려운 문제 일 수 있지만 문제는 다음과 같은 방식으로 단순화되고 가속화 될 수 있습니다.

  • 사전 베이킹 노드 네트워크 : 맵이 생성되면 월드가 덩어리로 나뉘어 질 수 있으며 각 덩어리의 출구와 입구가 매핑 될 수 있습니다. 벽이 빌드 될 때와 같이 청크가 업데이트되면 해당 청크의 네트워크 만 업데이트하면됩니다.
  • 단계적 경로 찾기 : 전체 맵, 셀의 셀을 통해 경로를 실행하는 데 시간이 오래 걸리는 대신 큰 청크 네트워크를 통해 경로를 찾은 다음 청크 간의 모든 연결을 매핑 한 다음 청크 내 경로 만 실행합니다. 청크에서 청크로 이동. 이것은 당신을 위해 두 가지 일을합니다. 작은 조각으로 나누어 길 찾기 속도를 높이고 청크가 업데이트 될 때 경로를 따라 방향을 바꿀 수 있습니다. 교차 업데이트가 필요한 노드가 있으면 대규모 네트워크를 통해 경로를 재 지정합니다.
  • 랜덤 조향 : 목표로 이동하지 않을 때, 유닛은 목표없이 걸 으면됩니다. 많은 로그 라이크가 장치를 임의의 방향으로 움직이면 부자연 스럽습니다. 다양한 조향 기술이 사용될 수 있으며, 간단한 조향 기술은 직선으로 움직이기를 선호하며 뒤쪽으로 방사되는 방향으로 움직일 기회가 적고 약 1 %의 확률을 갖습니다. 따라서 장치는 때로는 방향을 완전히 바꾸지 만 거의하지 않습니다.

길 찾기의 기본 사항은 다루지 않겠습니다. 대부분의 로그 라이크는 A *를 사용하지만 고양이를 피부에 바르는 다른 방법이 있습니다. 음 고양이 가죽

개인 작업

DF 유닛을 대중적으로 만들고 느끼게하는 주요 요소 중 하나는 개인 목표 목록입니다. 사실 많은 불량 게임은 기본 수준에서 이것을 가지고 있습니다. 기본적으로 각 부서에는 욕구 목록이 있으며 (도르프의 경우 원하는 작업을 선택할 수 있음) 개성 (통계)에 따라 선택합니다.

일부 작업에는 요구 사항이 있습니다. 가죽 치마를 만들려면 도르프가 X 품목이있는 그런 가게에 있어야합니다. 따라서 모든 항목을 확인하고 목록에 작업으로 추가합니다. 그렇게 간단합니다.

유닛이 운송되는 대부분의 시간 동안, 유닛이 수행하는 작업에 대한 점검은 매우 빠를 수 있으며, 특정 시점에 소수의 유닛 만 선택하므로 전체적으로 수백 또는 수천 단위. 그리고 DF에서 꿀벌부터 혈거 원까지, 나무까지 모든 것이 단위임을 기억하십시오.


추가적인 연구를 통해 유감스럽게도 DF는 일반적으로 끔찍한 길 찾기 작업을 수행하고 있음이 분명합니다. 그것은지도를 덩어리로 나누지 않고, 연결된 세그먼트 또는 영역으로지도를 나눕니다 (확실하지 않은 것보다 낫습니다). 위의 평가는 생각보다 DF가 어떻게 작동하는지에 대한 예입니다. 🙂 DF가 백만 가지 다른 이유로 놀랍지 않은 것은 아닙니다.

게임에서 중요한 것은 게임 플레이라는 것을 보여줍니다. 그래픽도 아니고, 훌륭한 프로그래밍도 아니고, 훌륭한 작문도, 훌륭한 음악도 아니고, 인터페이스조차도 아닙니다. 게임 자체만큼 중요한 것은 1 %도 아닙니다.


답변

에서 이 페이지 :

글쎄요. 길 찾기는 엄청나게 놀랍습니다. 모든 캐릭터가 한 번에 처리하기 때문입니다.

TA : 드워프들 대부분은 A와 함께 움직이고, 규칙적인 오래된 거리-거리 휴리스틱을 사용합니다. 까다로운 부분은 사전에 도착할 수 있는지 모르는 경우 실제로 A *를 호출 할 수 없거나지도를 범람하고 프로세서를 죽일 수 있다는 것입니다.

이것이 그가 “지도 홍수” 를 막는 방법인지 확실하지 않지만, 게임에서 이것을하는 일반적인 방법은 계층 적 경로 찾기 A * 또는 HPA * 라는 A *를 변경하는 것 입니다. 그리드를 더 적지 만 더 큰 청크로 분할 한 다음 A *를 사용하여 각 청크에서 인접한 청크까지의 최상의 경로를 찾는 것이 좋습니다. 이를 사용하여 각 단위에 대해 A *를 실행할 훨씬 더 작은 그래프를 작성할 수 있습니다.

계층 적 경로 찾기

이 청크를 더 큰 청크로 그룹화 할 수도 있습니다.이 계층은 “계층 구조”의 시작 부분입니다.

이 알고리즘은 거의 최적의 경로 만 찾지 만 드워프 포트리스와 같은 게임에서는 일반적으로 괜찮습니다. 경로가 존재하는 경우 여전히 경로를 찾을 수 있습니다. 경로가 없으면 더 작은 그래프 만 플러딩하여 시간을 크게 절약 할 수 있습니다.

또한 일부 지형 을 통과 할 수 있지만 다른 지형으로 는 통과 할 수없는 유닛 (공기 유닛은 통과 할 수 있지만 지상 유닛은 통과 할 수없는 절벽) 을 다루는 HPA *의 추상화가 있습니다 . HAA * 라고 하며 여기에 설명하는 매우 접근 가능한 기사가 있습니다 .

다양한 경로 찾기 알고리즘에 대한 자세한 내용은 여기를 참조하십시오 .


답변

무엇이든, 그것은 반대입니다. 모든 것이 하나의 스레드에서 실행되고 이제 차단 요소가되는 지점에 도달하고 있습니다 (마지막으로 확인했습니다!)

빠른 이유는 멋진 그래픽이 없기 때문입니다. 속임수이지만 물건을 늦추는 것은 물건을 그리는 것입니다 (AAA 타이틀에서 프레임의 2/3 이상을 생각하십시오). 왜소한 요새는 매우 기본적이기 때문에 그 시간의 나머지 부분을 흥미로운 일에 바칩니다.


답변

DF가 어떻게 코딩되는지는 모르겠지만 AI가 정밀도를 필요로하지 않는 사람들이 종종 그것을 감독하기 때문에 AI의 양은 ​​나에게 깊은 인상을 주지 않습니다 . 몇 초마다 대부분의 작업을 수행하는 것이 완벽하게 가능합니다. 부정확 한 계산을 사용하는 것도 가능합니다. 불완전 성은 많은 성능을 저장합니다 . 100 ms마다 100 단위의 의사 결정 루틴을 실행하거나 초당 1000 단위로 실행할 수 있습니다. 동일한 CPU 시간이 걸리지 만 단위는 10 배입니다.

다음은 많은 단위를 처리 할 수있는 간단한 예입니다.

int curUnit;
Array<Unit> units;
[...]
while([...]) // Game Loop
{
  [...game logic...]
  // process 10 AIs per Frame
  for(int i=0; i++; i<10)
  {
    curUnit++
    if(curUnit == units.length()) curUnit=0;
    if(curUnit < units.length())
      units[curUnit].processAI();
  }

  // Update the position of all units, this should be as optimized as possible
  foreach(Unit& unit in units){ unit.move(); };

  [...graphics...]
}

AI는 반응 속도가 높을수록 반응 속도가 느려지고 반응이 심해지지만 플레이어는 극단적 인 경우에만 AI를 알아 차릴 것입니다.


답변