플레이 피드백 4건(주목도 미차감, 상점 빈 상품, 상점 UX 오해, 재화 명칭)을 검토해 방향이 확정된 항목만 반영하고, 외부 테스터에게 링크를 공유할 수 있게 시놀로지 NAS 배포까지 준비했다. ## 게임 로직 - 라운드 접수량 크리티컬 버그 수정: 합본을 반복하면 라운드가 안 끝나던 문제. deskCards에서 파생시키던 값을 순수 누적 카운터(roundIntake)로 교체 — 결정 노트: 2026-09-18-라운드-접수량-누적카운터 - DeskBar/CoreSwipeCard 정보 역할 분리: "이번 라운드 접수량/한도"는 결재 화면 전담, DeskBar는 책상에 쌓인 것(총 주목도·축별 분포)만 표시 - 토큰 → 코인 용어 일괄 변경: core/ 전체(식별자·CSS·주석·UI)와 기획서 SSOT 동기화, lucide Coins 아이콘 추가 ## 배포 - vite base를 상대 경로로 변경 (Web Station 서브패스 서빙 시 asset 404 방지) - 모바일 100vh → 100dvh (주소창 노출 시 하단 버튼 가림 방지) - 빌드 식별자 표시, 타이틀/테마색/description 정리 - deploy.sh + npm run deploy — SSH 키 권한 문제(777 → StrictModes 거부)와 NAS rsync 게이트를 scp -O로 우회해 실제 배포까지 검증 완료 → https://play.mint-grape.duckdns.org/projectss/ Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
71 lines
2.7 KiB
JavaScript
71 lines
2.7 KiB
JavaScript
// 기호 체계 (ProjectSS_코어시스템_기획서.md §3) — 모든 카드가 공유하는 단일 기호 언어.
|
|
// 스와이프 판단은 텍스트가 아니라 이 기호(축 인장 + 기밀 등급)만으로 0.5초 내에 이루어져야 한다.
|
|
// 색상만으로 구분하지 말 것 — 아이콘 형태(실루엣) 자체가 축을 구분해야 한다 (§3.1).
|
|
//
|
|
// 2026-09-15 결정 반영: 기밀 등급 1~4 → 1~10 확장, 점(●) 표기 폐기.
|
|
// 카드 중앙에 큰 숫자, 축 인장은 모서리에 작게 — 트럼프 랭크+슈트 레이아웃 (§3.2).
|
|
// 코인은 1종으로 통합됐으므로(§8.2, §19) 축은 더 이상 코인 종류를 결정하지 않는다.
|
|
// 축이 결정하는 것은 "명분 종류"(질)뿐이고, 코인 양(양)은 등급 합계가 결정한다 (§7.2).
|
|
|
|
export const AXES = ['axis_threat', 'axis_hr', 'axis_pr', 'axis_external'];
|
|
|
|
// 인장(아이콘)은 lucide-react의 Tornado/Hand/Megaphone/Stamp를 그대로 쓴다.
|
|
// 실제 아이콘 컴포넌트 매핑은 SymbolBadge.jsx에서 담당 — 여기는 축의 이름·게이지·명분 매핑만.
|
|
export const AXIS_META = {
|
|
axis_threat: {
|
|
name: '위협',
|
|
sealName: '소용돌이',
|
|
gauge: 'entropy',
|
|
gaugeName: '엔트로피',
|
|
justification: '위기',
|
|
},
|
|
axis_hr: {
|
|
name: '인사',
|
|
sealName: '손',
|
|
gauge: 'resistance',
|
|
gaugeName: '조직 저항',
|
|
justification: '내부',
|
|
},
|
|
axis_pr: {
|
|
name: '공보',
|
|
sealName: '확성기',
|
|
gauge: 'panic',
|
|
gaugeName: '대중 공황',
|
|
justification: '여론',
|
|
},
|
|
axis_external: {
|
|
name: '대외',
|
|
sealName: '도장',
|
|
gauge: 'risk',
|
|
gaugeName: '위험 수용 계수',
|
|
justification: '절차',
|
|
},
|
|
};
|
|
|
|
export const GRADE_MIN = 1;
|
|
export const GRADE_MAX = 10;
|
|
|
|
// 등급 범위 명칭 (§3.2). 서사·문체용 라벨일 뿐이며, 합본 판정·주목도 계산 등
|
|
// 모든 게임 로직은 항상 원 숫자(1~10)를 쓴다.
|
|
const GRADE_BANDS = [
|
|
{ max: 2, name: '일반' },
|
|
{ max: 4, name: '대외비' },
|
|
{ max: 6, name: '2급 기밀' },
|
|
{ max: 8, name: '1급 기밀' },
|
|
{ max: 10, name: '특급 기밀' },
|
|
];
|
|
|
|
export const gradeBandName = (grade) => {
|
|
const g = clampGrade(grade);
|
|
return GRADE_BANDS.find((b) => g <= b.max)?.name ?? '일반';
|
|
};
|
|
|
|
export const clampGrade = (grade) =>
|
|
Math.max(GRADE_MIN, Math.min(GRADE_MAX, Math.round(grade || GRADE_MIN)));
|
|
|
|
// 명분 +1 보너스 기준 등급 (§7.1: "등급 8 이상(1급 기밀 이상) 카드가 포함되면 +1")
|
|
export const TOP_SECRET_THRESHOLD = 8;
|
|
|
|
export const gaugeOf = (axis) => AXIS_META[axis]?.gauge ?? null;
|
|
export const justificationOf = (axis) => AXIS_META[axis]?.justification ?? '혼합';
|