Files
maplecontest/docs/superpowers/specs/2026-06-06-card-image-slot-design.md
2026-06-06 08:12:16 +09:00

3.5 KiB
Raw Blame History

카드 슬롯에 이미지 카드 적용 설계

  • 날짜: 2026-06-06
  • 브랜치: feature/sts2-combat-layout
  • 대상: ui/DefaultGroup.ui, tools/gen-cardhand.mjs
  • 원본 이미지: C:\Users\jaeoh\Desktop\workspace\source\images\maple\invincible belief.png

목표

하단 손패 5장 중 5번 자리(현재 강타) 의 카드 외형을 invincible belief.png(완성된 세로형 카드 이미지 "리부트 프로토콜")로 교체한다.

배경

해당 PNG는 단순 아트가 아니라 코스트·이름·타입·등급·아트·설명·플레이버까지 포함한 완성된 카드 한 장 전체(세로 약 2:3 비율)다. 따라서 슬롯의 외형 전체를 이 이미지로 대체하고, 그 슬롯에는 우리가 생성하던 텍스트 오버레이(코스트/이름/설명)를 넣지 않는다(이미지에 이미 포함 → 겹치면 중복/지저분).

범위

포함

  • PNG를 MSW 계정 sprite 리소스로 업로드 → RUID 발급
  • 생성기에 카드별 선택적 image(RUID) 데이터 추가
  • image가 있는 카드: 단색 배경 대신 해당 RUID 스프라이트(틴트 흰색)로 렌더, 텍스트 자식(Cost/Name/Desc) 생성 안 함
  • 5번 카드 크기를 이미지 비율에 맞춰 180×270 으로 조정(가로 유지, 세로만 +20), 행 중앙 정렬 유지
  • 나머지 4장은 기존 단색 목업 유지

제외 (YAGNI)

  • 나머지 4장의 이미지화
  • 카드 클릭/효과/실제 전투 로직
  • 이미지 카드의 동적 데이터 연동

구현 방식

1. 에셋 업로드 (asset_create_account_resource_storage_item, 2단계)

  • 1차 호출: category=sprite, subcategory=etc, name/description 지정, contentLength=파일 바이트 수, fileUrl 생략 → presignedUrl 수신
  • presignedUrl로 PNG를 HTTP PUT(raw 바이너리)
  • 2차 호출: fileUrl=presignedUrl → 리소스 생성 완료, 응답에서 RUID(DataId) 확보
  • 업로드 결과 RUID는 재현 가능하도록 생성기 스크립트에 하드코딩한다.

2. 생성기 변경 (tools/gen-cardhand.mjs)

  • cards[4](강타 슬롯)에 image: '<RUID>' 필드 추가. (이름/코스트/설명 데이터는 남겨두되 image가 있으면 렌더에 사용하지 않음)
  • 카드 빌드 루프 수정:
    • 카드 배경 스프라이트: image가 있으면 sprite({ dataId: image, color: {1,1,1,1}, type: 0 }), 없으면 기존 sprite({ color: tint, type: 1 })
    • 카드 크기: image가 있으면 180×270, 없으면 180×250
    • 텍스트 자식(Cost/Name/Desc): image가 없을 때만 생성
  • 멱등성/줄바꿈 보존/splice 로직은 그대로 유지

3. 형상관리

  • 이미지는 MSW 클라우드 리소스로 저장되고, .ui·스크립트에는 RUID 문자열만 포함. PNG 원본은 slaymaple 저장소에 커밋하지 않는다(원본은 workspace/source/images/maple/에 유지).

검증

  1. 업로드 응답에서 유효한 RUID 수신 확인
  2. 생성기 재실행 → JSON 유효, 5번 카드가 image 스프라이트 + 텍스트 자식 없음, 나머지 4장 불변
  3. Maker refresh_workspaceplayscreenshot로 5번 자리에 "리부트 프로토콜" 카드 이미지가 왜곡 없이 표시되는지 확인
  4. (커밋 전) 디스크 무결성 확인 후 커밋

리스크

  • 업로드한 sprite가 SpriteGUIRenderer에서 곧바로 렌더되는지(서브카테고리 무관 가정) — 검증 단계에서 확인, 안 되면 subcategory를 item 등으로 재시도
  • 카드 크기 180×270이 행 정렬에서 약간 위로 솟음 — 의도된 허용 범위