[작성중/교양 프로그래밍] 발악데미지 원리 추측

    개요

    민속놀이 스타크래프트에는 몇몇 기괴한 현상이 일어난다. 그 중 하나인 럴커의 발악데미지에 대한 뇌피셜을 풀어본다. 발악데미지란, 럴커가 발사한 가시가 끝에 도달하기 전에 럴커가 죽으면 엄청난 데미지를 뿜어내는 버그성 현상이다. 자주 챙겨보는 열사 운장이형의 럴커는 죽을 때도 데미지를 입힌다는 점 알고 계셨나요? 영상에서 가설을 세우고 실험을 통해 증명하는 모습을 보면서, 현상보다 더 깊이 있는 코딩에 대한

    럴커의 디자인

    가시 발사는 럴커가 1회 공격하였을 때, 가시는 1회의 공격에서 시각적으로 보이는 각각의 가시 1개를 말하겠다.

    기획자는 럴커 가시 범위 내의 유닛에게 한 번의 데미지를 주기를 원하였을 것이다. 실제로도 럴커가 죽지 않고 공격을 수행한다면, 의도대로 한 번의 가시 발사에 한 번의 데미지밖에 입지 않는다. 그런데...

    문제의 가시 범위

    한 번의 럴커 공격에서 나오는 각 가시의 피격 판정은 생각보다 넓어보인다. 아래 그림을 참고하자.

    보이는 것 보다 피격판정이 크다.

    과장되게 그림을 그렸지만, 실제 보이는 가시보다 피격판정이 크다고 체감된다. 여기서 생기는 문제는, 만약 각 가시의 범위에 겹친다면 어떤 일이 벌어질까?

    각 가시가 독립적으로 데미지를 주도록 구현이 되어있다면, 두 개의 가시 범위에 겹치는 유닛은 2번의 데미지를 받을 것이다. 이는 기획자의 의도에 벗어난 구현일 것이고, 이를 방지하기 위해서 추가적인 아이디어가 필요했을 것이다.

    중복 피격 방지하기

    * 여기서부턴 뇌피셜의 영역입니다. 가볍게 읽어주시길 바랍니다.

    럴커가 살아있을 경우 이미 발사된 가시들은 id=25인 럴커가 발사했다는 정보를 담고 있을 것이고, 어떤 유닛이 1회 피격 시 특정 시간 동안에는 같은 럴커가 발사한 다른 가시에 데미지를 받지 않도록 구현할 수 있을 것이다. 실제로 럴커가 살아 있을 때에는 잘 작동하고, 20년 스타 역사에 수천,수만 프로 경기를 치러오면서도 문제가 되지 않았음을 알 수 있다.

    문제는 럴커의 가시 발사가 끝나지 않았는데 럴커가 죽은 경우이다.

    발악 데미지 상황에서의 동작

    럴커가 데미지를 받아 사망하면, 게임 내에서 모종의 처리가 이루어질 것이다. id=25인 럴커는 사망하였기 때문에 더 이상 게임 내에서 유효한 유닛이 아니게 될 것이고, 럴커의 정보를 담은 객체는 소멸할 것이다. 각 가시를 구현한 객체가 럴커 객체에 의존하고 있다면, 그리고 해당 객체가 존재했던 메모리 공간이 초기화되거나 다른 객체가 덮어 쓸 경우 기존 럴커의 id를 참조하려고 메모리에 접근하지만 엉뚱한 값이 나오게 될 것이다. 럴커 사망 후 올라오는 가시들에 대해서는 발사한 럴커의 id가 25가 아닌 다른 값이 되어서 2회 피격 판정을 받아 사망하는 경우라고 볼 수 있을 것이다.

    관측으로 뇌피셜 검증하기

    가시에 정통으로 피격된 마린은 살아남고, 가시 사이에 낀 마린들은 20*2의 데미지를 입어 죽는 모습이다.

    매달린 포인터 (dangling pointer)

    -- 차차 작성하기

    가비지 콜렉터

    메모리 할당기

    lazy free / nullify

    참고자료 및 출처

    [Youtube #01]러커의 발악데미지 그 강함은 어디까지? by Bono

    댓글