# 공격력·방어력 가정과 연계 자동 계산

검토일: 2026-10-14. 게임 파일 분석 기준: 클라이언트 v26.102.018.

## 이번에 변경한 기능

① 내 전투 조건에 내 공격력과 적 방어력을 추가했다. 새 가정의 기본값은 공격력 10,000, 방어력 1,000이다. 계산 결과는 ‘가정 DPS’와 ‘가정 피해’로 표시한다. 도술 카드의 피해 계수는 공격력·방어 환산 전 값이며, 결과와 비교 표는 공통 전투 가정으로 환산한다.

일반 보정 메뉴에서 화염분출 증가율, 낙뢰 피해 환산 증가율, 두 연계의 적용·소비 체크박스를 제거했다. 선택한 도술의 사건과 같은 대상의 조건 표시가 살아 있는 시간을 따라 자동으로 발동한다. 기존 브라우저의 증가율 0이나 임의 피해 환산값은 새 계산에 적용하지 않는다. 변경 전 입력은 백업한다.

결과에 ‘내 덱에서 자동 적용한 연계’를 추가했다. 표시를 만드는 도술, 발동 도술, 전투 중 발동 횟수를 보여 준다. 도술을 넣었더라도 조건 표시가 없거나 만료됐다면 효과를 얻지 못한다. 확인된 두 경로에 한정하며 다른 도술의 미복원 효과까지 적용했다고 주장하지 않는다.

## 리버스 엔지니어링에서 확인한 데이터

기존에 확보된 분석 결과와 추출 파일을 재사용했다. 게임 원본과 baseline을 다시 읽거나 변경하지 않았다.

### 조건 표시와 연계 효과

| 항목 | 추출 설정 | 근거 |
| --- | --- | --- |
| 파쇄 | 5초, 최대 1중첩, 갱신 정책 | fbdatabuff.bytes, ID 120009003 |
| 관통 | 5초, 최대 1중첩, 갱신 정책 | fbdatabuff.bytes, ID 120009007 |
| 받는 피해 증가 | 10초, 교체 갱신, 최대 1중첩, DamageDown −500 | fbdatabuff.bytes ID 120009102 / fbdatabuffaffect.bytes 행 14500 |
| 방어력 감소 | 10초, 교체 갱신, 최대 1중첩, DefencePer −500 | fbdatabuff.bytes ID 120009100 / 대응 fbdatabuffaffect.bytes |
| 속성 환산 | DefencePer와 DamageDown의 CorrValue 약 0.0001 | fbdataattributelist.bytes |

원시 −500과 환산값으로 표시상 5%를 해석한다. 소수 저장 오차를 정리해 모델에서 0.05를 사용한다. 피해 증가를 별도 ×1.05로 취급하는 결합식 자체는 후보이며 서버 공식으로 검증되지 않았다.

새 `combat-data.js`는 이 선별 설정과 출처를 보관한다. 지속시간과 효과 크기를 각 입력창의 임의 값으로 대체하지 않는다. 생성기는 `prepare_combat_data.py`이고, 입력은 이미 확보한 추출표다.

### 추가로 복원한 전투 설정

`fbdatacombatconfig.bytes` 86행과 `fbdatapvpconfig.bytes` 16행을 읽었다. 기존 스킬 설정 전체 행과 동일한 3필드 구조가 일치하는지 먼저 확인하고, 전투 설정은 같은 구조의 후보로 복원했다.

| 키 | 값 | 전투 설정 파일의 행 / 값 필드 위치 |
| --- | --- | --- |
| DefenceMin_Val | 1 | 4324 / 4336 |
| DamageMin_Val | 0.001 | 3072 / 3084 |
| FinalDamageMin_Val | 1 | 2100 / 2112 |
| AttackExponent | 1.0 | 1064 / 1076 |
| PvPAttackExponent | 0.9 | 476 / 488 |
| PenetrationPerMin_Val | 0 | 5024 / 5036 |
| PenetrationPerMax_Val | 0.9999 | 5084 / 5096 |

이 상수들이 존재하지만 적용 위치·순서·분기·반올림 구현은 확인하지 못했다. 예를 들어 PvP 공격 지수 0.9가 어떤 단계에 적용되는지는 알 수 없으므로 임의로 공격력에 거듭제곱을 적용하지 않았다. 방어력 최소값 역시 최종 계산의 어느 단계에서 보정되는지 미확인이며 비교 가정에는 자동 이식하지 않는다.

### 몬스터 공격력·방어력 항목

`fbdataattributemonster.bytes`에서 796행을 복원했다. 속성 키 벡터와 값 벡터에 Attack·Defence가 있으며, 전 행의 두 벡터 길이와 유한한 수치를 검사했다.

첫 정수 슬롯의 접근자는 확보하지 못했다. 나머지 Key·속성명 벡터·Single 값 벡터·CombatPoint는 선언 순서와 실제 데이터 형식에 맞춰 복원했다. 이 구조상 한계는 기록했고, 첫 정수를 확인된 몬스터 ID로 공개하지 않았다. 표에는 테스트용 항목도 있으며, 특정 보스의 인게임 최종 방어력으로 바로 사용할 수는 없다. 몬스터 종류·레벨·서버 보정 및 실제 속성 변환의 대조가 더 필요하다.

원시 복원 결과는 `output/resources/defense-review-tables.json`, 요약은 `output/combat-defense-summary.json`이다. 원시 전체 표와 바이너리는 사이트에 게시하지 않는다.

### 피해 계산 함수 단서와 REA 사용

메타데이터에 `CalculateDamageFrom`(.hho, Dokkaebi.Client.Game.dll, 인덱스 131775, 위치 0xa66770, Int32 반환)과 `TryCalculateDamage`(.qyl, Dokkaebi.Common.dll, 인덱스 237975, 위치 0xda4270, Boolean 반환)가 있다. 이 위치는 메타데이터 안의 위치이며 실행 함수 주소가 아니다.

REA에서 working/client/GameAssembly.dll과 기존 분석 스냅샷을 열고, 분석된 함수 이름 및 정의된 문자열에서 피해·방어 관련 검색을 실행했다. 두 검색은 일치 항목 0이었다. 이 결과는 해당 분석 목록의 검색 결과이며, 바이너리 전체나 서버에 해당 기능이 없다는 뜻이 아니다. 관리 코드의 이름과 네이티브 함수 본문을 연결하지 못했고 최종 방어 환산식은 복원되지 않았다. 기존 보호된 영역의 정적 복원 한계도 해소되지 않았다.

REA 재사용 대상 SHA-256은 e89481847ff44b4d2786412bb6f0c518992df99cfae038545d0538875bee5a82로 기존 working 식별값과 일치한다. 검색 근거는 `output/rea/defense-query-evidence.json`, 종료 시 저장한 스냅샷은 `output/rea/defense-review-snapshot.json`이다. 게임 프로세스에 연결하지 않았다.

## 비교용 방어 계산 가정

임의 공격력과 방어력만으로는 환산식을 정할 수 없다. 따라서 서버 공식과 구분해서 다음 비교용 감쇠식을 선택했다.

```
피해 = 공격력 × 도술 피해 계수 × K / (K + 적용 방어력) × 받는 피해 증가 배율
```

K의 기본값 1,000은 분석자가 비교를 위해 정한 값이며 게임에서 추출한 방어 상수가 아니다. 고급 설정에서 변경할 수 있고, 방어 미반영 모드도 선택할 수 있다. 방어력 감소가 유지되는 대상은 적용 방어력을 `입력 방어력 × 0.95`로 계산한다. 같은 대상의 신규 증가 효과는 발동 타격 뒤에 적용하는 후보다. 지속시간 종료와 같은 시각의 타격은 효과가 없는 것으로 처리한다.

계수 1, 공격력 10,000, K=1,000의 예:

| 상황 | 방어력 1,000 | 방어력 500 |
| --- | --- | --- |
| 연계 없음 | 5,000 | 약 6,666.67 |
| 방어력 5% 감소 유지 | 약 5,128.21 · +2.56% | 약 6,779.66 · +1.69% |
| 받는 피해 증가 5% 유지 | 5,250 | 7,000 |
| 두 효과 모두 유지 | 약 5,384.62 | 약 7,118.64 |

피해 5% 증가와 방어력 5% 감소는 다른 계산이다. 방어력 0의 비교 상황에서는 방어 감소로 얻는 피해 증가가 없다. 공격력을 두 배로 하면 이 모형에서는 같은 덱의 피해와 DPS가 두 배가 된다. 게임의 실제 공격력·방어 공식이 이런 관계라는 뜻은 아니다.

연계 발동이 가능하려면 덱 안의 생성 도술이 대상에게 표시를 부여하고, 표시 5초가 끝나기 전에 발동 도술이 적중해야 한다. 효과는 10초 유지되며 재부여하면 갱신한다. 같은 효과를 여러 번 부여해도 단순히 5%씩 합산하지 않는다. 현재 모델은 외부 파티원, 서로 다른 방어력의 적, 치명타, 방어 관통, 미복원 효과와 최종 반올림을 포함하지 않는다.

## 검증·복원·재개

자동 검사는 원래의 시전·성장·돌파·충전·궁극기·효과 경계 검사를 유지한다. 공격력 10,000 / 방어력 1,000 및 500, 방어 0, 표시 만료, 효과 만료, 발동 타격과 후속 타격 구분, 두 연계 결합, 폐기한 도술별 보정값의 비적용, 피해/DPS 단위를 추가 검사했다. 이전 설정을 먼저 백업하고 형식 6으로 복원하는 검사도 포함한다.

브라우저에서 전용 증가율 입력이 없어졌는지, 연계 예시가 조건과 시간에 따라 발동하는지, 방어력 500에서 설명과 DPS가 바뀌는지, 공격력 두 배에 결과가 두 배가 되는지, 작업 스레드의 사용 순서 탐색이 동작하는지 확인했다. 375px 모바일 결과의 페이지 너비는 360px이고 외부 가로 넘침이 없었다. 공개 배포와 최종 화면 검증은 progress.md의 배포 기록에 보관한다.

웹 변경 전 파일은 `backup/web-v11-before-defense-model`, 브라우저 형식 5 입력은 `dokkaebi-build-before-defense-v6` 키에 한 번 보관한다. 해당 백업 문자열을 JSON 파일로 보관해 ‘설정 파일 불러오기’에서 읽으면 이전 도술·성장·배치를 복원할 수 있다. 과거 도술별 증가율 보정은 새 자동 계산에서 사용하지 않으므로 이전 코드의 동일 계산을 원하면 공개 버전 11의 소스 커밋 cc1d1ea567e66bdf0c8f06acf906dfcd2f40729b도 필요하다.

재개 시 이 보고서와 progress.md 최신 절, 현재 웹 소스를 읽는다. 기존 설치·원본 복사·전체 Ghidra 분석을 반복하지 않는다. 방어 공식은 일반 플레이에서 같은 공격·계수·대상으로 방어 감소 전후의 피해를 대조하고, 몬스터 속성과 전투 상수의 적용 위치를 추가 확인해야 한다. 현재 허용 범위인 정적 분석을 유지하고 프로세스 연결·보안 우회·패킷 변조는 하지 않는다.
