CAFE

CK 모드 게시판

[CK2 모딩 팁]내멋대로 쓰는 Crusader King 2 모딩 매뉴얼 (5) 랜덤 구문 - 개정판 (2015/04/30 수정)

작성자tacitus|작성시간15.02.13|조회수1,149 목록 댓글 1

내멋대로 쓰는 Crusader Kings 2 모딩 매뉴얼 - 개정판

4. 디시전 파일의 작성

(6) 확률 및 랜덤 구문

어떤 이벤트를 일정한 확률에 따라서 랜덤으로 발생시키는 구문 역시 모드에서 빠질 수 없는 요소입니다. 불확실성은 재미의 중요한 요소가 되니까요. CKII 에서는 이처럼 랜덤 이벤트를 실행시키는 구문을 두 개 제공하고 있습니다. random = { } 과 random_list = { } 구문이 그것입니다. 이곳에서 다루는 내용도 디시전에 한정되는 내용이 아니라, 다른 부분에서도 써먹을 수 있는 내용입니다. 의도한 건 아닌데, 어째 내용이 갈수록 쉬워지는 느낌입니다. 뒤로 갈 수록 어려워져야 정상인데, 앞부분이 어려워서 독자 다 떨어져나가는 꼴?

■ random = { }

이름에서 느껴지듯이, 지정한 확률로 어떤 이벤트나 효과를 발생시키기 위해 사용하는 구문입니다. 바로 전 회에서 예제 코드에서 한 번 등장한 적이 있죠.

random = {
  chance = N
  ...실행할 구문...
}

N은 퍼센트 포인트를 의미하며, 0~100 사이의 값을 입력하면 됩니다.

CKII의 랜덤 값 출력은 사실 그다지 믿을 만 한 것이 못 된다고 생각합니다. 제대로 된 랜덤 값 출력을 구현하려면 부담이 너무 커서인지(CKII의 연산량이 상당한 수준인 건 사실이니..), 상당히 느슨한 방식으로 랜덤 값을 도출하고 있거든요. 실제 해 보시면 아시겠지만, 여러 개의 랜덤을 기반으로 하는 구문을 중첩적으로 돌리다 보면, 굉장히 패턴화된 경향이 눈에 보입니다. 오죽하면 필자의 경우에는 이벤트의 경우 random_list 구문의 사용을 거의 회피하다시피 하고 있습니다. 이 내용은 이벤트 파트에서 다시 말씀드리겠습니다.

■ random_list = { }

이 구문은 일정한 목록을 주고 확률에 따라서 특정한 목록의 명령을 실행하는 구문입니다.

random_list = {
  N = {
    ...명령...
  }
  N = {
    ...명령...
  }
  N = {
    ...명령...
  }
}

N값은 각각의 확률을 의미합니다. random_list 를 쓴 아주 좋은 예를 하나 보여드리죠. 원본 데이터의 경우, 디시전에서는 의도적인지 아닌지는 모르겠지만 random_list 의 사용을 회피하고 있고, 대부분 일반 event 에서 등장합니다. 아래의 예 역시 이벤트에서 나온 것입니다.

random_list = {
  50 = {
    FROM = { add_trait = arbitrary }
  }
  45 = {}
  5 = {
    FROM = { add_trait = paranoid }
  }
}

위와 같이 사용하면 됩니다. 50% 의 확률로 FROM 스코프의 캐릭터에게 arbitrary 트레잇을, 5%의 확률로 paranoid 트레잇을 달게 합니다. 45% 의 중괄호 안에는 아무 것도 없는데, 저렇게 하면 45%에 걸렸을 때에는 아무 일도 일어나지 않게 됩니다.

참고로, random_list 에서 확률로 지정하는 값의 총합은 정확히 100이 되어야 한다는 이야기가 있습니다만, 지금은 잘못된 이야기입니다. 현재는 꼭 100을 맞출 필요는 없고(다만 사용자가 알아보기 편하려면 합산 100을 맞춰주는 게 좋죠), 합산 100이 안 되는 경우에는 개별값/합산값 으로 확률을 다시 계산하여 적용해 줍니다.

잊을 뻔 했군요. 어떤 분들은 그럼 random_list = { } 구문을 사용하는 것과, random = { } 구문을 여러 개 사용하는 것과의 차이가 무엇인가가 궁금해지실 것입니다. random_list = { } 구문은 나열된 구문들 중 단 하나만의 실행을 보장합니다. 여러 개의 선택지 중 확률에 따라 단 하나만 실행되는 거죠. 하지만 random = { } 구문을 여러 개 늘어놓은 경우 그 중에 하나만 실행된다는 보장은 없습니다. 하나도 실행되지 않을 수도 있고, 모두 다 실행될 수도 있습니다. 이런 차이점이 있으니, 필요에 따라서 사용하시면 되겠습니다.

그러나, random_list = { } 구문을 사용하더라도 아무 일도 일어나지 않도록 할 수 있습니다. 바로 앞에서 보셨잖아요. 해당 확률 내부에 아무 것도 없으면 아무 것도 실행되지 않는 거죠. 그렇더라도 "아무 일도 하지 않는" 그 선택지가 "선택" 된 거니까요.

■ 랜덤 확률 구문의 중첩

예를 들면, random_list = { } 구문 내에서 다시 random_list = { } 구문을 사용할 수 있을까요? 네. 가능합니다.

다음 예를 보시죠.

  random_list = {
    50 = { character_event = { id = WoL.12007 days = 260 } }
    25 = { character_event = { id = WoL.12006 days = 260 } }
    25 = {
      random_list = {
        50 = { character_event = { id = WoL.12004 days = 260 } }
        50 = { character_event = { id = WoL.12005 days = 260 } }
      }
    }
  }

웨이 오브 라이프 DLC 에서 추가된 wol_rulership_events.txt 에 포함된 이벤트의 일부분입니다. random_list = { } 구문을 이용해서 여러개의 이벤트 중 하나를 실행하도록 하는 것인데, 희한하게도 마지막의 25% 안쪽에 또 하나의 random_list = { } 가 존재하죠? 결과적으로 WoL.12004 와 WoL.12005 이벤트는 각각 12.5% 의 확률로 실행되는 결과가 됩니다.

왜 굳이 저렇게 썼는지는 저도 모르겠습니다. 12.5% 라는 확률을 구현하기 위해서 일부러 저렇게 했나 싶긴 합니다.

■ 조건과 랜덤 확률의 조정 : modifier = { }

1) modifier = { } 구문의 사용법

2.1.6 때까지만 해도, 랜덤 구문에 관한 내용은 이게 끝이었습니다. 그런데, 지금은 굉장히 흥미로운 구문이 들어갔습니다. 조건에 따라서 정한 랜덤 확률값을 변화시킬 수 있게 된 것이죠.

예를 들어서, 50%의 확률로 어떤 이벤트를 발생시킬 예정입니다.

random = {
  chance = 50
  character_event = {
    id = TST.1003
  }
}

그런데, 이 이벤트가 굉장히 야시시한 이벤트여서, 만약 플레이어가 이런 종류의 트레잇 (hedonist, lustful, seducer 등)을 가지고 있다면 이 이벤트가 발생할 확률을 높이고, 반대 트레잇 (chaste, celibate) 를 가지고 잇다면 이벤트가 발생할 확률을 낮추고 싶다.. 충분히 가능한 요구사항이죠?

random = { } 의 경우에는 2.1.6 에서도 이런 형태의 작성이 가능했던 걸로 기억합니다만, random_list 의 경우는 그렇지 않았는데, 이제는 둘 모두 이런 식의 조작이 가능합니다.

random = {
  chance = 50
  modifier = {
    factor = 0
    trait = chaste
  }
  modifier = {
    factor = 0.5
    trait = celibate
  }
  modifier = {
    factor = 1.3
    trait = hedonist
  }
  modifier = {
    factor = 1.5
    trait = lustful
  }
  modifier = {
    factor = 1.8
    trait = seducer
  }
  character_event = {
    id = TST.1003
  }
}

이런 식으로 modifier = { } 를 추가할 수 있다는 거죠. 사실 이 modifier = { } 구문은 이미 다른 곳에서도 사용되고 있던 구문인데, 이것을 random = { } 구문과 random_list = { } 구문에서도 사용할 수 있도록 확장한 것입니다. 아래와 같은 구조를 가집니다.

  modifier = {
    factor = N
    ...(조건들)...
  }

modifier = { } 내부의 factor 값은 chance 값에 곱해질 배율입니다. 같은 random = { } 블록 내에 modifier = { } 가 여러 개 지정되어 있는 경우에, 지정한 조건을 충족한다면 충족하는 modifier = { } 구문의 factor 값은 모두 곱해집니다. 예를 들어, 같은 블록 내에서 조건을 충족하는 modifier = { } 의 갯수가 3개이고, 그 값이 1.2, 0.6, 1.4 라면, 최종적으로 적용될 factor 값은 이 세 값을 모두 곱한 1.008 이 되는 거죠. 이 값과 chance 에 지정된 확률을 다시 곱해서 최종 확률값을 구하게 됩니다.

아, 위 예시에도 있지만, factor = 0 인 조건도 있을 수 있습니다. 이 조건에 걸리면 다른 조건을 아무리 충족하더라도 절대로 실행이 안 되는 건 초등학교 5학년 이상이면 다 아시겠죠? 제아무리 많은 숫자를 곱해봐야 거기에 0이 곱해지면 최종 결과는 0이 되는 거니까요.

짐작은 하시겠지만, random_list = { } 의 경우에는 확률 중괄호 안쪽에 같은 방식으로 지정을 합니다. 해석도 동일합니다. chance 값 대신에 중괄호 앞의 숫자값이 곱해지는 것만 다른 거죠.

random_list = {
  50 = {
    modifier = {
      factor = 0
      trait = chaste
    }
    FROM = { add_trait = arbitrary }
  }
  45 = {
    modifier = {
      factor = 1.6
      trait = lustful
    }
  }
  5 = {
    modifier = {
      factor = 0.3
      trait = homosexual
    }
    FROM = { add_trait = paranoid }
  }
}

혹시, 2회의 끝 부분에서 ai_will_do = { } 섹션에 이와 비슷한 구조가 있었던 것을 기억하시나요? 이제 modifier = { } 를 배웠으니 그 부분도 해석이 가능하실 겁니다. 다른 점은 ai_will_do = { } 의 기본 factor 가 0이상 1이하의 값(0~100%)으로 주어지고, 그 기본 factor 값(여기선 기본 확률값이 0~100으로 주어졌죠)에 조건을 충족하는 modifier = { } 의 factor 값이 곱해진다는 것입니다.

2) modifier = { } 구문을 사용한 경우의 최종 확률의 적용법

random = { } 의 경우에, 계산된 factor 값과 chance 값을 곱한 결과가 100이 넘는다면 이 구문은 무조건 실행됩니다. (random = { } 구문의 chance 값은 그 자체가 %로 계산되니까요.)

그런데, 필연적으로 선택지가 여러 개가 나오는 random_list = { } 의 경우에는 이렇게 단순하지 않습니다. 초기 확률값과 계산된 factor 값을 곱한 값이 그대로 확률(%)이 되는 것이 아니라, 각각의 선택지의 modifier = { } 를 모두 계산한 값을 모두 더하여 그것을 분모로 하는 분수값을 만들어 그것을 기초로 하여 다시 확률을 정합니다. 앞에서 이미 봤던 이야기죠? 그 규칙이 modifier = { } 값을 적용한 후에도 동일하게 적용되는 거예요.

예를 들어, random_list = { } 구문에 지정된 선택지가 3개이고, 이들의 초기 확률이 각각 20, 30, 50 이었는데, modifier = { } 를 적용하여 계산한 결과값이 각각 25, 45, 20 이 되었다고 생각해 봅시다. 그러면 이들 선택지가 실행될 확률이 25%, 45%, 20% 인 걸까요? 문제가 있죠. 다 더하면 100이 안 되잖아요. random_list = { } 구문은 세 선택지 중의 하나가 반드시 실행이 되어야 하는데, 모든 확률의 합산이 100이 안 된다면 아무것도 실행되지 않을 확률이 남는다는 이야기가 되므로 문제가 발생해요. 따라서, 새로 계산된 값인 25, 45, 20을 모두 더한 90 을 분모로 해서, 25/90, 45/90, 20/90 으로 확률을 계산합니다. 아, 이것은 모든 확률의 합산이 100이 안 되는 경우뿐만 아니라, 100을 넘기는 경우에도 같은 방식으로 계산됩니다!

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
  • 작성자학습한국사 | 작성시간 15.02.13 모딩의 기초에 대한 좋은 글이네요. 잘 읽었습니다!
댓글 전체보기

CK 모드 게시판 다른글

현재페이지 1234
맨위로

카페 검색

카페 검색어 입력폼