9.3 KiB
9.3 KiB
Update: Restrained Team Card Styling
- Team score cards preserve their existing content and selection behavior while using a neutral dark card surface.
- Per-team color now reads mainly through a compact marker and a small divider segment, making the HUD feel less saturated.
- Focus and hover feedback uses subtle inset emphasis without the previous raised motion or strong glow.
Update: Battle Notice Rolling Text
battleDeathNotice.jsmeasures the rendered message against the visible notice content width and only enables rolling text when the message would overflow.- Rolling notices render an internal duplicated track for continuous movement while exposing the single message through the status node's
aria-label. UI.BATTLE_NOTICE_ROLL_GAP_PX,BATTLE_NOTICE_ROLL_SPEED_PX_PER_SECOND, and min/max duration constants tune the marquee behavior.
Update: Elite Compression And Population Display
- Below
FIGHTER.ELITE.RANDOMIZED_COMPRESSION.MIN_TEAM_SIZE,matchSetup.jsconverts each completeFIGHTER.ELITE.STACK_SIZE = 100block into one elite plan and keeps the remainder as individual normal plans. With the current threshold of100, complete blocks are randomized. - For starting-zone matches, each elite consumes the assigned spawn point at the start of its represented 100-member block, while remainder normals retain their corresponding individual spawn points.
- At or above the randomized-compression threshold, each complete 100-member block becomes one elite at probability
0.6, or expands into 100 normal plans otherwise. - If the user-entered total fighter count exceeds
PERFORMANCE.LARGE_BATTLE_FIGHTER_THRESHOLD, randomized compression usesFIGHTER.ELITE.RANDOMIZED_COMPRESSION.LARGE_BATTLE_ELITE_BLOCK_PROBABILITY(0.8by default) for every eligible team block. - Large battles also enforce
PERFORMANCE.LARGE_BATTLE_RENDERED_FIGHTER_LIMITby promoting failed normal blocks or normal remainder groups to elite groups after the random roll. This keeps physical sprites bounded while preserving representedstackCount. arenaMatchRuntime.jskeeps the submitted population represented throughstackCount, whilearenaScoreboard.jsintentionally shows living physical composition asE : <elite sprites> | N : <normal sprites>.- Trait-generated extra spawning remains enabled for normal fighters only. Elite plans do not apply
spawnMultiplier, because one aggregate fighter multiplying would multiply the entire represented army. ArenaSceneuses setup-aware fighter selection so elite plans receive only skins matchingFIGHTER.ELITE.TYPE(currentlymeleeandmagic), while normal plans keep the existing full selection pool.- The team card layout reserves enough horizontal space for values such as
E : 32 | N : 800, including the horizontally scrolling mobile scoreboard.
Context: Match & UI
Update: Direct Fighter Count Entries And Zone Distribution
- Match setup no longer exposes a separate team-size control. Each live entry uses
nickname*Nfor that team's assigned fighter count, with plain names defaulting to one fighter. - A live match is rejected before replacing the current match only when the participant-assigned count exceeds
SPAWN.MAX_FIGHTER_COUNT; SlimespawnMultiplierandsplitOnDeathresults may grow the actual live population past it. - Fighter-count cap validation is reported as a visually distinct warning card below the participant nickname textarea, with requested and allowed counts emphasized separately; it clears when that input changes or a valid live match is submitted.
- Starting-zone placement assigns one zone per
SPAWN.FIGHTERS_PER_STARTING_ZONEfighters in each team and puts any remainder in that team's final zone.
1. 모듈별 상세 역할
매치 로직 (src/game/match/)
matchSetup.js: 매치 초기화, 팀 구성, 스폰 위치 계산을 담당합니다.arenaMatchRuntime.js: 스폰 클러스터 계산 및 팀 크기 동기화 등 매치 진행 중 헬퍼 기능을 제공합니다.
UI 컴포넌트 (src/ui/)
matchForm.js: 설정 폼 제어 및localStorage설정 유지.aboutDialog.js: About 버튼/다이얼로그, 개발자정보, 개인정보처리방침 Markdown 표시.arenaScoreboard.js: 좌측 HUD 레일의 팀 badge 업데이트 및 관전 시점 전환.arenaKillLog.js: 좌측 하단 킬로그 표시 및 관리.battleDeathNotice.js: 상단 사망 통계 공지 UI.victoryCelebration.js: 승리/무승부 축하 연출 (광선, 컨페티, 오디오).
2. 주요 로직 구현 세부 사항
매치 설정 및 스폰 배치
- 닉네임 배수 시스템:
닉네임*배수형식(예:Alice*2)을 감지하여 팀 인원을 배수만큼 생성합니다. - 구매 배수 보존과 독주 견제: 배수 팀의 생성 인원과 전투 수치는 결제 이점으로 유지합니다. 월드 이펙트 표적 선정에서는
team.multiplier를 구매 지분으로 사용하고, 그 지분을 초과해 생존 중인 팀에만 설정 가능한 추가 표적 가중치를 적용합니다. - 스타팅 지점 배치 (멀티 스폰): 팀마다 전장 스폰 가능 그리드에서 중심 셀을 무작위로 고르고, 중심 주변 2칸(
5 x 5)을 해당 팀의 스타팅 영역으로 사용합니다. 배수가 설정된 팀은 배수만큼의 독립적인 스타팅 영역을 할당받아 병력이 분산 배치됩니다. 겹치지 않는 후보가 남아 있는 동안에는 해당 후보를 우선 선택하며, 영역은 매치 시작 후 5초 동안만 팀 색상으로 매우 옅게 표시되고 팀 전투원은 이 안에서만 스폰합니다. - 설정 유지: 닉네임, 인원, 배치 모드는
localStorage에 저장되어 재접속 시 복원됩니다.
전투 화면 레이아웃 (HUD)
- 팀 Badge: 좌측 HUD 레일에 배치되며, 클릭 시 해당 팀의 생존 유닛 중 무작위 1명으로 시점을 고정합니다. 이미 고정된 동일 팀 Badge를 다시 클릭하면 선택을 해제하고 기본 줌을 요청합니다. 단, 자동 관전 줌 조건이 활성화되어 있으면 다음 카메라 갱신에서 자동 줌이 즉시 다시 적용됩니다.
- 팀 Badge 갱신 안정성: 사망으로 생존 수가 바뀔 때 기존 badge 버튼 DOM을 유지한 채 숫자, 비활성 상태, 선택 강조만 갱신하여 사망 프레임에 겹친 클릭도 시점 고정으로 전달되도록 합니다.
- 킬로그: 처치자와 피처치자를 좌우로 배치하고, 피처치자 아이콘에 빨간 X를 겹쳐 사망 관계를 명확히 표시합니다. 캐릭터 idle 시트의
100x100프레임 내 투명 여백을 제외한 중앙 하단 영역을 확대 표시해 작은 아이콘 박스에서도 실루엣이 충분히 보이도록 합니다. - 하단 메타 정보: 전투 화면 우측 하단(
arena-meta컨테이너)에 방문자 카운터와 About 버튼이 Pill(알약) 형태로 디자인이 통일되어 나란히 고정 배치됩니다. 드로어가 열려도 동일한 위치를 유지합니다. - 모바일 레이아웃: 실제 전투 시작 시 모바일에서는 옵션 drawer를 자동으로 접고, 상단 팀 HUD는 옵션 버튼 폭을 제외한 영역에 두 줄로 배치됩니다. 이때 데스크톱의 고정 가로폭 상속을 방지(
grid-template-columns: none)하여 모든 팀 카드가 균일한 가로폭을 유지하도록 하며, 4개 이후 팀도 스크롤을 통해 확인할 수 있습니다. 모바일 팀 카드 선택 표시는 내부 테두리로 처리해 외곽선이 잘려 보이지 않게 합니다. 킬로그는 전투 캔버스 바로 아래에 배치하되 하단 메타 정보(방문자 카운터/About)와 겹치지 않게 안전 여백을 확보합니다. - 모바일 옵션 drawer: 전투 중 펼친 옵션 drawer는 닉네임 입력 높이와 컨트롤 간격을 줄여 전투 시작/재시작/일시정지 버튼이 작은 화면에서도 한 번에 보이도록 합니다.
- 승리 연출: 승리 시 Web Audio 기반 팡파르와 CSS 애니메이션(광선, 컨페티)을 결합해 화려하게 연출합니다. 전투 종료 시 옵션 drawer를 접어 결과 배너가 설정 폼과 충돌하지 않게 하며, 결과 배너는 일정 시간 후 자동으로 사라지거나 클릭 시 즉시 닫힙니다. 무승부는 더 차분한 톤을 사용합니다.
3. UI 개발 규칙
- DOM 접근 최소화: 성능 최적화를 위해 필요한 시점에만 최소한으로 DOM을 업데이트합니다.
- 반응형 상태:
#app의 클래스(match-live,options-open,drawer-collapsed,match-paused,match-ended)를 통해 전반적인 UI 상태를 제어합니다.
4. About 다이얼로그
src/ui/aboutDialog.js:- 대기 화면과 전투 화면 우측 하단에 상시 노출되는
#about-button과#visitor-count를 관리합니다. - 다이얼로그는 개발자정보와 개인정보처리방침 탭으로 구성됩니다.
- 자체 Markdown 렌더러: 개인정보처리방침 탭은 자체 구현된 렌더러를 통해 출력되며, 굵게(
**), 기울임(*), 인라인 코드(`), 인용구(>), 구분선(---), 헤딩(#) 및 리스트(-) 문법을 안전하게(HTML 이스케이프) 지원합니다. - 브라우저는
GET /api/aboutAPI로 서버에 캐시된 콘텐츠를 가져오며, 실패 시 폴백 값을 표시합니다.
- 대기 화면과 전투 화면 우측 하단에 상시 노출되는