크로스파이어 총기 밸런스 기획

장성환·2024년 12월 26일
post-thumbnail

개요와 데이터셋 정리

크로스파이어는 한국에서 2020년 서비스를 종료해서 관련 데이터를 찾기 힘들었다.

https://en.namu.wiki/w/%ED%81%AC%EB%A1%9C%EC%8A%A4%ED%8C%8C%EC%9D%B4%EC%96%B4(FPS)/%EB%AC%B4%EA%B8%B0/%EB%8F%8C%EA%B2%A9%EC%86%8C%EC%B4%9D
나무위키 영어 사이트에서 부족하지만 무기 정보를 구했다.

복붙해서 이런 데이터 셋을 만들었다.
총기 갯수는 일단 돌격소총만 37개다.

파이썬 코드로 데이터셋을 보기 좋게 정리했다.

import pandas as pd

# CSV 파일 경로
file_path = 'C:/Users/Jang/Desktop/크로스파이어 밸런스 기획/crossfire_weapon.CSV'

# CSV 파일 읽기
df = pd.read_csv(file_path, encoding='cp949', header=None)

# 열 이름 정의
columns = ['총기명', 'Power', 'Weight', 'Accuracy', 'Tanjong', 'Caliber', 'Price',
           'Rate of Fire', 'Rebound', 'Number of Bullets', 'Nationality', 'Note']

guns = []

for i in range(0, len(df), 3):  # 3행 단위로 처리
    gun_name = df.iloc[i, 0]  # 첫 번째 행의 첫 번째 값은 총기명
    first_row = df.iloc[i + 1].dropna().tolist()  # 첫 번째 정보 행
    second_row = df.iloc[i + 2].dropna().tolist()  # 두 번째 정보 행

    # 속성값 병합
    gun_info = [gun_name]
    gun_info.extend(first_row[1::2])  # 첫 번째 행의 값만 추출
    gun_info.extend(second_row[1::2])  # 두 번째 행의 값만 추출

    # 열 개수 조정: 부족한 열은 None으로 채우기
    if len(gun_info) < len(columns):
        gun_info.extend([None] * (len(columns) - len(gun_info)))

    # 데이터 추가
    guns.append(gun_info)

# DataFrame 생성
guns_df = pd.DataFrame(guns, columns=columns)

# 데이터 출력
print(guns_df)

# CSV로 저장
guns_df.to_csv('C:/Users/Jang/Desktop/크로스파이어 밸런스 기획/formatted_gun_data_fixed.csv', index=False, encoding='cp949')

아래와 같이 깔끔하게 정리가 됐다.

아쉽게도 소총, 기관단총 일부만 나와있어서 이 두 종류의 총들로 기획을 진행해보아야 할 것 같다.

데미지 계산

게임 내 무기의 총 공격력(유효 데미지)을 대략 계산해보자.
유저가 많다고 가정하면 동 레벨대의 유저들은 실력이 비슷비슷할 것이므로 개인의 에임같은 변수는 고려하지 않고 오로지 총기의 정보만을 고려해보자.

데미지에 플러스가 되는 요소는 power, accuracy, Rate of Fire, Number of Bullets가 있겠고,
마이너스가 되는 요소는 Weight, Rebound가 있다.

결정력

FPS에서 각 신체부위에 따라 적용되는 데미지가 다르므로 적절한 계산식의 도입으로 각 총기의 성능을 수치화 해야 한다. 따라서 이 프로젝트에서는 각 총기의 성능을 수치화한 '결정력'을 도출 할 것이다.

아래 식들에서 n은 적 플레이어가 사망하기까지 발사 탄 수 이다. 따라서, n+1을 결정력으로 정의한다.

헤드샷

100%데미지가 들어간다.

power 0.01 Accuracy + power 0.01 Accuracy 0.01 Rate of Fire (100- LN(Rebound)) 0.01 * n

몸통샷

50%데미지가 들어간다.
0.5(power 0.01 Accuracy + power 0.01 Accuracy 0.01 Rate of Fire (100- LN(Rebound)) 0.01 n)

팔다리샷

25%데미지가 들어간다.

0.25(power 0.01 Accuracy + power 0.01 Accuracy 0.01 Rate of Fire (100- LN(Rebound)) 0.01 n)

위 식을 정리하면,

결정력 = (100/각 부위별 데미지 비율 - power Accuracy 0.01) / (power Accuracy 0.01 Rate of Fire 0.01 (100- LN(Rebound)) 0.01) + 1

위처럼 계산식이 적용된다. 반동이 결정력에 주는 영향을 감소시키기 위해 LN로그를 적용했다. 식을 액셀시트에 적용하면

VZ.58은 헤드샷으로 1.15발, 몸통샷으로 2.91발, 팔다리 6.42발을 적중해야 상대를 쓰러뜨릴 수 있다.
실제 게임과는 차이가 많이 날 수 있다. 데이터의 적절한 수정과 식의 수정으로 인게임과 유사하게끔 만들어야한다.

신규 총기의 도입시 밸런싱

상위 10개의 총기를 유저들이 주로 사용한다고 가정하고, 결정력을 토대로 새 총기의 적절한 수치를 배분해보자.

시트 2에 레드팀과 블루팀을 나눠 랜덤으로 총기를 배치한다.

총기명 셀 수식

=INDEX(소총!A2:A12, RANDBETWEEN(1, ROWS(소총!A2:A12)))

위 식은 결정력 상위 10개의 총기중 랜덤으로 표시한다.

결정력 셀 수식

=INDEX(소총!P2:P12, MATCH(C3, 소총!A2:A12, 0))

위 식은 랜덤으로 선택된 총기에 맞게 결정력을 표시해준다.

신규 총기 도입

최근에 전역한 예비역 유저들의 요구에 힘입어, K2C1총기를 새로 출시해야 하는 상황이라고 가정해보자.

아래는 나무위키의 제원 부분을 캡쳐한 사진이다.

상위 10개 총기중 같은 5.56*45탄을 쓰는 G3A3, Beretta AR-70와 비교해가며 총기의 수치를 설계해보자.

실제 총기의 제원과 게임 내 수치를 비교해가며 K2C1의 수치를 설계해보자.

보통 탄속이 빠를수록 치명적이므로, power과 연결되는 수치이다. 하지만 실제 탄속이 Beretta AR-70가 더 빠르지만 인게임 수치상으로는 G3A3이 더 높게 책정되어있다. 이는 게임내의 조정일 수 도, 혹은 총탄의 규격이 같아도 제조사에 따라 다른 성능을 낼 수 있는 이유로 추정한다.

K2C1은 이 둘의 사이인 90으로 먼저 설정해보자.

다른 수치도 실제 총의 정보를 참고하여 적절히 수치를 배분했다.
총열 길이는 보통 명중률에 영향을 준다. 실제로 총열이 길수록 총알이 더 똑바로 나아갈 수 있기 때문이다. (그래서 보통 저격총의 총열이 길다.)
반동은 발사 속도가 빠르고 총의 무게가 가벼우니 두 총보다 조금 높게 잡는다.

이렇게 완성된 k2c1의 프로토타입을 인게임에 배치하면 어떻게 될지 확인하자.

블루팀의 플레이어 5에 K2C1을 적용해보자.

두 팀의 결정력 차이가 높진 않아서, 적절한 밸런스로 총기를 설계하였다고 볼 수 있다.
랜덤으로 총기 배치를 20회가량 변동하여도, 결정력 차이가 3미만이었고, K2C1의 도입 전에도 같은 정도의 차이를 보였다.
따라서 K2C1의 수치 설계와 도입은 성공적이라 할 수 있다.

마치며

크로스파이어를 직접 플레이 해보며 각 무기의 성능을 직접 확인할 수 없어 자제적으로 밸런싱 작업을 진행하였다.
각 수치들을 해석하는 방식과 식에 적용하는 방법이 실제 게임의 결과와 다를것이라 예상한다. 아마도 현재 크로스파이어의 메타에는 다른 총기들이 자리하고 있을 것이다.

하지만 식을 약간 손보고, 실제 게임에 적용되는 방식으로 수치들을 적용하면 적절한 밸런싱을 수행할 수 있을것이다.

profile
홍익대학교 게임소프트웨어전공, 산업공학전공

0개의 댓글