Files
ProjectSS/client/src/core/engine/symbols.js
T
kyoung5seoandClaude Sonnet 5 20207ff23c 라운드 접수량 버그 수정 + 토큰→코인 용어 통일 + 외부 배포(NAS)
플레이 피드백 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>
2026-09-18 23:20:22 +09:00

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 ?? '혼합';