fix: 버리기-뽑기 카드 미선언 prop 추가 (no such field 크래시) #95

Merged
gahusb merged 1 commits from fix/discard-draw-props into main 2026-06-29 17:51:52 +09:00
Owner

증상

버리기 계열 카드를 내면 [CLIENT] cannot set DiscardPostDraw, no such field 런타임 에러로 카드 처리가 중단되고, 이후 공중제비(방어+카드 2장 뽑기)를 포함한 모든 카드 클릭이 '2장 버리기' 선택으로 처리되며 아무 동작도 하지 않는 멈춤 버그.

근본 원인

DiscardPostDraw·DiscardDrawPerPickcb/hand.mjs(BeginDiscardSelection·AutoDiscardHand·FinishDiscardSelection·SelectDiscardSlot)에서 self.X = 대입되는데 gen-slaydeck.mjs의 prop 목록에 선언되지 않음. MSW는 미선언 필드 대입 시 cannot set X, no such field로 메서드를 중단시킴.

  • BeginDiscardSelectionDiscardPostDraw 대입(801행) 직전에 DiscardSelectRemaining/Total을 이미 set → 에러로 중단되면 게임이 버리기-선택 모드에 갇힘 → 이후 모든 카드 입력이 버리기 픽으로 오인됨.
  • 형제 prop DiscardPostShiv·DiscardShivPerPick(표창 변형)는 선언돼 있었으나, draw 변형 2개가 누락된 단순 빠뜨림(codex의 '버린 만큼 뽑기' 메커니즘 추가 시).

공중제비 자체는 discard 필드가 없어 직접 에러를 내지 않지만, 위 멈춤 상태 때문에 증상이 공중제비에서 관찰됨. 영향받는 카드: 생존자·곡예·숨겨진 단검·단검 투척·예비·텔레포트·계산된 도박·강철의 폭풍·그림자 걸음 등 버리기 계열 전부.

수정

gen-slaydeck.mjs prop 목록에 DiscardPostDraw·DiscardDrawPerPick 선언 추가(형제 패턴과 나란히). 게임 규칙 변경 없음 — 선언 누락만 보완.

신규 회귀 가드

tools/verify/cbprops.mjs: cb의 self.X = 대입을 선언 prop과 대조해 미선언 = no such field 후보를 정적 검출. 수정 전 2개 누락(exit 1) → 수정 후 0(exit 0).

검증

  • cbprops 미선언 0 · codeblock에 두 prop 반영(JSON 유효) · cbgap GAP 0 · node --test 93/93
  • 메이커 플레이테스트(버리기 카드→버리기 정상 완료, 공중제비→카드 2장 뽑힘)는 사용자 확인 권장
## 증상 버리기 계열 카드를 내면 `[CLIENT] cannot set DiscardPostDraw, no such field` 런타임 에러로 카드 처리가 중단되고, 이후 **공중제비(방어+카드 2장 뽑기)를 포함한 모든 카드 클릭이 '2장 버리기' 선택으로 처리되며 아무 동작도 하지 않는** 멈춤 버그. ## 근본 원인 `DiscardPostDraw`·`DiscardDrawPerPick`가 `cb/hand.mjs`(BeginDiscardSelection·AutoDiscardHand·FinishDiscardSelection·SelectDiscardSlot)에서 `self.X = ` 대입되는데 **`gen-slaydeck.mjs`의 prop 목록에 선언되지 않음**. MSW는 미선언 필드 대입 시 `cannot set X, no such field`로 메서드를 중단시킴. - `BeginDiscardSelection`은 `DiscardPostDraw` 대입(801행) **직전에** `DiscardSelectRemaining/Total`을 이미 set → 에러로 중단되면 게임이 **버리기-선택 모드에 갇힘** → 이후 모든 카드 입력이 버리기 픽으로 오인됨. - 형제 prop `DiscardPostShiv`·`DiscardShivPerPick`(표창 변형)는 선언돼 있었으나, draw 변형 2개가 누락된 단순 빠뜨림(codex의 '버린 만큼 뽑기' 메커니즘 추가 시). 공중제비 자체는 discard 필드가 없어 직접 에러를 내지 않지만, 위 멈춤 상태 때문에 증상이 공중제비에서 관찰됨. 영향받는 카드: 생존자·곡예·숨겨진 단검·단검 투척·예비·텔레포트·계산된 도박·강철의 폭풍·그림자 걸음 등 버리기 계열 전부. ## 수정 `gen-slaydeck.mjs` prop 목록에 `DiscardPostDraw`·`DiscardDrawPerPick` 선언 추가(형제 패턴과 나란히). 게임 규칙 변경 없음 — 선언 누락만 보완. ## 신규 회귀 가드 `tools/verify/cbprops.mjs`: cb의 `self.X =` 대입을 선언 prop과 대조해 **미선언 = no such field 후보**를 정적 검출. 수정 전 2개 누락(exit 1) → 수정 후 0(exit 0). ## 검증 - `cbprops` 미선언 0 · codeblock에 두 prop 반영(JSON 유효) · `cbgap` GAP 0 · `node --test` 93/93 - 메이커 플레이테스트(버리기 카드→버리기 정상 완료, 공중제비→카드 2장 뽑힘)는 사용자 확인 권장
gahusb added 1 commit 2026-06-27 02:44:47 +09:00
`DiscardPostDraw`·`DiscardDrawPerPick`가 hand.mjs(BeginDiscardSelection·
AutoDiscardHand·FinishDiscardSelection·SelectDiscardSlot)에서 대입되는데
gen-slaydeck.mjs prop 목록에 선언되지 않아 런타임 "cannot set DiscardPostDraw,
no such field"로 BeginDiscardSelection이 중단됨. 그 직전 DiscardSelectRemaining/
Total이 이미 set되어 게임이 버리기-선택 모드에 갇혀, 이후 모든 카드(공중제비 포함)
클릭이 버리기 픽으로 처리됨("2장 버린다 표시 + 동작 없음").

근본 원인: 형제 prop DiscardPostShiv·DiscardShivPerPick는 선언됐으나
draw 변형 2개가 누락. 선언만 추가(병렬 패턴).

신규 가드 tools/verify/cbprops.mjs: cb의 `self.X =` 대입 ↔ 선언 prop 대조,
미선언 = no such field 후보 검출. 수정 전 2개 누락→후 0.
검증: cbprops 0·cbgap GAP 0·테스트 93/93. 산출물(codeblock) 재생성 포함.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gahusb merged commit b4a4560678 into main 2026-06-29 17:51:52 +09:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gahusb/maplecontest#95