나는 아직도 당신이 이것을 읽고 있는지 확실하지 않지만 오랫동안 이런 종류의 문제로 어려움을 겪었습니다.
다양한 유형의 영향 시스템을 설계했습니다. 이제 간단히 살펴 보겠습니다. 이것은 모두 내 경험에 근거한 것입니다. 나는 모든 답을 알고 있다고 주장하지 않습니다.
정적 수정 자
이 유형의 시스템은 대부분 수정을 결정하기 위해 간단한 정수에 의존합니다. 예를 들어 +100은 최대 HP, +10은 공격 등입니다. 이 시스템은 퍼센트도 처리 할 수 있습니다. 스태킹이 제어 범위를 벗어나지 않도록해야합니다.
이 유형의 시스템에 대해 생성 된 값을 실제로 캐시하지 않았습니다. 예를 들어, 최대 건강 상태를 표시하려는 경우 그 자리에서 값을 생성합니다. 이를 통해 오류가 발생하기 쉬우 며 관련된 모든 사람이 이해하기 쉬워졌습니다.
(저는 Java 기반으로 작업하므로 Java 기반이지만 다른 언어에서는 일부 수정 작업을 수행해야합니다.)이 시스템은 수정 유형에 대해 열거 형을 사용한 다음 정수를 사용하여 쉽게 수행 할 수 있습니다. 최종 결과는 키, 값 순서 쌍이있는 일종의 컬렉션에 배치 할 수 있습니다. 빠른 조회 및 계산이 가능하므로 성능이 매우 좋습니다.
전반적으로 평평한 정적 수정 자와 함께 잘 작동합니다. 그러나 수정자가 사용될 적절한 위치에 코드가 있어야합니다 (getAttack, getMaxHP, getMeleeDamage 등).
이 방법이 실패하는 곳은 버프 간의 매우 복잡한 상호 작용입니다. 게토를 조금만 더하는 것 외에는 상호 작용을하는 쉬운 방법이 없습니다. 간단한 상호 작용 가능성이 있습니다. 그렇게하려면 정적 수정자를 저장하는 방식을 수정해야합니다. 열거 형을 키로 사용하는 대신 문자열을 사용합니다. 이 문자열은 Enum 이름 + 추가 변수입니다. 10에서 9 번, 추가 변수는 사용되지 않으므로 열거 이름을 키로 유지합니다.
간단한 예를 들어 보자 : 언데드 생물에 대한 피해를 수정하려면 다음과 같은 순서 쌍을 가질 수 있습니다 : (DAMAGE_Undead, 10) DAMAGE는 열거 형이고 언데드는 추가 변수입니다. 따라서 전투 중에 다음과 같은 작업을 수행 할 수 있습니다.
dam += attacker.getMod(Mod.DAMAGE + npc.getRaceFamily()); //in this case the race family would be undead
어쨌든, 그것은 잘 작동하고 빠릅니다. 그러나 복잡한 상호 작용 및 모든 곳에서 "특별한"코드를 갖는 데 실패합니다. 예를 들어, "죽음으로 순간 이동할 확률 25 %"의 상황을 고려하십시오. 이것은 "정당한"복잡한 것입니다. 위의 시스템은 다음을 필요로하므로 쉽게 처리 할 수는 없습니다.
- 플레이어에이 모드가 있는지 확인하십시오.
- 성공하면 어딘가에 순간 이동을 수행하는 코드가 있습니다. 이 코드의 위치는 그 자체로 토론입니다!
- Mod 맵에서 올바른 데이터를 얻으십시오. 그 가치는 무엇을 의미합니까? 그들이 텔레포트하는 방입니까? 플레이어가 두 개의 순간 이동 모드를 가지고 있다면 어떨까요? 금액이 합산되지 않습니까 ?????? 실패!
그래서 이것은 다음으로 나를 데려옵니다.
궁극의 복잡한 버프 시스템
한때 혼자서 2D MMORPG를 쓰려고했습니다. 이것은 끔찍한 실수 였지만 많은 것을 배웠습니다!
영향 시스템을 3 번 다시 작성했습니다. 첫 번째는 위의 변형이 덜 강력했습니다. 두 번째는 제가 이야기 할 내용이었습니다.
이 시스템에는 각 수정에 대한 일련의 클래스가 있으므로 ChangeHP, ChangeMaxHP, ChangeHPByPercent, ChangeMaxByPercent와 같은 것들이 있습니다. 나는 TeleportOnDeath와 같은 것들조차도 백만 명을 가졌습니다.
제 수업에는 다음과 같은 일이있었습니다.
- applyAffect
- 제거
- checkForInteraction <--- 중요
설명 자체를 적용하고 제거하십시오 (백분율과 같은 경우 영향은 입었을 때 HP가 얼마나 많이 증가했는지 추적하여 추가 된 양만 제거합니다). 그것이 옳은지 확인하는 데 오랜 시간이 걸렸습니다. 나는 여전히 그것에 대해 좋은 느낌을 얻지 못했습니다.)
checkForInteraction 메소드는 엄청나게 복잡한 코드 조각이었습니다. 각 영향 (예 : ChangeHP) 클래스에는 입력 영향으로 수정해야하는지 여부를 결정하는 코드가 있습니다. 예를 들어, 당신이 같은 것을 가지고 있다면 ...
- 버프 1 : 공격시 10의 화염 피해를 입 힙니다.
- 버프 2 : 모든 화염 피해가 25 % 증가합니다.
- 버프 3 : 모든 화염 공격력이 15 증가합니다.
checkForInteraction 메소드는 이러한 모든 영향을 처리합니다. 이를 위해 근처에있는 모든 플레이어에 대한 각 영향을 확인해야했습니다 !! 이것은 내가 여러 지역에 걸쳐 여러 플레이어를 상대 한 영향의 유형 때문입니다. 이것은 코드에 위와 같은 특별한 진술이 없었 음을 의미합니다. 이 시스템은 적시에 자동으로 올바르게 처리합니다.
이 시스템을 작성하는 데 2 개월이 걸렸으며 머리로 여러 번 폭발했습니다. 그러나, 그것은 정말 강력하고 미쳤던 양의 일을 할 수 있습니다. 특히 내 게임의 능력에 대해 다음 두 가지 사실을 고려할 때 : 1. 목표 범위를 가졌습니다. , PB AE 타겟, 타겟 AE 등). 2. 능력은 그들에게 하나 이상의 영향을 미칠 수 있습니다.
위에서 언급했듯이, 이것은이 게임의 2 차 3 차 영향 시스템이었습니다. 나는 왜 이것을 멀리 했습니까?
이 시스템은 내가 본 것 중 최악의 성능이었습니다! 그것이 진행되는 각각의 일에 대해 너무 많은 점검을해야했기 때문에 그것은 너무 느 렸습니다. 나는 그것을 개선하려고 시도했지만 실패로 간주했습니다.
그래서 우리는 내 세 번째 버전 (그리고 다른 유형의 버프 시스템)에 왔습니다.
핸들러가있는 복잡한 영향 클래스
따라서 이것은 처음 두 가지의 조합입니다. 많은 기능과 추가 데이터를 포함하는 Affect 클래스에 정적 변수를 가질 수 있습니다. 그런 다음 처리기를 호출하면 특정 작업에 대한 하위 클래스 대신 정적 유틸리티 메서드가 거의 호출됩니다. 그러나 원하는 경우 작업을 위해 하위 클래스와 함께 갈 수 있다고 확신합니다.
Affect 클래스는 대상 유형, 지속 시간, 사용 횟수, 실행 기회 등과 같은 수분이 많은 좋은 것들을 모두 갖습니다.
순간 이동 등의 상황을 처리하기 위해 여전히 특수 코드를 추가해야합니다. 우리는 여전히 전투 코드에서 수동으로 이것을 확인해야하고, 존재한다면 영향 목록을 얻을 것입니다. 이 영향 목록에는 사망시 순간 이동을 처리 한 플레이어에게 현재 적용된 모든 영향이 포함됩니다. 그런 다음 각 항목을보고 실행되어 성공했는지 확인합니다 (첫 번째 성공한 단계에서 중지 함). 성공 했으므로 처리기를 호출하여 처리합니다.
원하는 경우 상호 작용을 수행 할 수 있습니다. 플레이어 등의 특정 버프를 찾기 위해 코드를 작성해야합니다. 성능이 우수하기 때문에 (아래 참조) 그렇게하는 것이 상당히 효율적입니다. 더 복잡한 처리기 등이 필요합니다.
따라서 첫 번째 시스템의 많은 성능과 두 번째 시스템과 같은 많은 복잡성을 갖습니다 (그러나 AS는 아님). Java에서는 최소한 대부분의 경우 거의 첫 번째 성능을 얻기 위해 까다로운 작업을 수행 할 수 있습니다 (예 : 열거 형 맵 ( http://docs.oracle.com/javase/6/docs/api/java) /util/EnumMap.html )을 키로 사용하고 ArrayList의 값을 값으로 사용하면 [목록이 0이거나 맵에 열거 형이 없기 때문에] 영향을 빠르게 받는지 여부를 확인할 수 있습니다. 이유없이 플레이어의 영향 목록을 계속 반복합니다.이 시점에서 필요에 따라 영향을 반복하는 것은 괜찮습니다. 문제가되면 나중에 최적화하겠습니다.)
2005 년에 끝난 MUD를 현재 재개하고 있는데 (원래 있던 FastROM 코드 기반 대신 Java로 게임을 다시 작성하고 있음) MUD를 최근에 버프 시스템을 어떻게 구현하고 싶었습니까? 이 시스템은 이전에 실패한 게임에서 잘 작동했기 때문에 사용할 것입니다.
글쎄, 누군가가 어딘가에서 이러한 통찰력 중 일부가 유용하다는 것을 알게 될 것입니다.