핵심 정체성 "주민들이 나를 기억해줬다"를 실현하기 위한 기억 시스템 전면 개선.

문제

  • NPC 기억이 localStorage 20개 엔트리에 불과, 브라우저 캐시 삭제 시 전부 소실
  • LLM에 "은근히 언급하면 좋습니다"라고만 해서 기억 활용이 보장되지 않음
  • NPC끼리 대화가 1턴 한마디로 끝남
  • 재방문 인식이 없음 — 5번째 대화나 첫 대화나 NPC 반응이 동일

1. 서버 프롬프트 강화

재방문 인식

conversationCount를 파싱해서 대화 횟수별로 다른 지시:

대화 횟수 LLM 지시
0 "처음 만나는 사람입니다. 호기심을 보이며 자기소개를 해주세요."
1~2 "'어, 아까 그분!' 같은 재인식을 해주세요."
3~9 "이름을 부르며 편하게, 과거 대화를 자연스럽게 언급하세요."
10+ "오래된 친구입니다. 과거 기억을 적극적으로 활용하세요."

기억 활용 명시적 지시

기존: "기억을 자연스럽게 활용하되, 목록처럼 나열하지 마세요."

변경:

"과거 기억 중 가장 최근 1개를 반드시 대화에 녹여주세요." 예: '저번에 커피 고마웠어요', '지난번에 얘기했던 그거...'

"은근히" → "반드시"로 바꾸니까 기억 활용률이 올라갑니다.

관계 단계별 행동 강화

기존엔 말투만 바뀌었는데, 구체적 행동 지시 추가:

  • 낯선 사이: 개인적 질문 회피
  • 아는 사이: 마을 이야기를 꺼내보세요
  • 친구: 고민 상담, 먼저 부탁 가능
  • 절친: 별명 부르기, 진심 어린 조언

2. NPC간 멀티턴 대화

Before

A: "안녕" (끝)
B: "응" (끝)

After

A: "요즘 날씨 좋다~" (2.5초 후)
B: "그러게, 산책하기 딱이야" (2.5초 후, 50% 확률)
A: "ㅋㅋ 맞아"

대화에 관계 맥락(친한 친구, 아는 사이 등)과 시간 정보도 포함됩니다.

3. 선제 인사에 기억 활용

NPC가 플레이어에게 먼저 말 걸 때, 마지막 대화 기억을 프롬프트에 포함:

const lastChat = mem.entries.filter(e => e.type === "chat").pop();
const hint = lastChat
  ? `지난 대화: "${lastChat.summary.slice(0, 30)}".`
  : "처음 보는 사람입니다.";

결과: "어, 아까 커피 얘기했던 분! 또 오셨네요?" 같은 자연스러운 재인식.

4. 기억 압축

기존: 20개 넘으면 가장 오래된 것부터 삭제 (영구 소실)

변경: 15개 넘으면 오래된 5개를 1줄 요약으로 압축:

[대화/선물] 커피 이야기; 공원 산책; 꽃 선물 받음; 날씨 대화; 퀘스트 완료

이렇게 하면 요약이 누적되어 전체 히스토리가 유지됩니다. 20개 한계가 아닌 무한 히스토리.

5. Firebase 기억 서버 저장

가장 큰 아키텍처 변경. 기존엔 localStorage만 사용 → 브라우저 초기화 시 전부 소실.

구조

Firebase Realtime DB
  └─ playground/memories/{playerId}
       ├─ _meta: { name, lastSaved }
       ├─ heo: { memory, favorLevel, favorPoints }
       ├─ kim: { memory, favorLevel, favorPoints }
       └─ ...

플레이어 식별

playerId = UUID, localStorage에 저장. 이름과 별개로 영구 식별자.

동기화 타이밍

이벤트 동작
페이지 로드 localStorage → 즉시 적용, Firebase → 비동기 보완
대화 종료 (farewell) Firebase에 저장
5분마다 자동 동기화

효과

localStorage를 삭제해도, 같은 브라우저에서 같은 playerId가 있으면 Firebase에서 기억이 복원됩니다.

이번 세션 전체 숫자

  • 커밋: 12개
  • 새 모듈: 6개 (weather, multiplayer, npc-data, quest, memory-sync, label-overlay)
  • main.js: 7034줄 → ~4400줄 (-37%)
  • 서버 재배포: 3회
  • 삭제: ~2800줄 (2D 렌더러 + 모듈 추출)

기억이 살아있는 마을. 이제 NPC들이 진짜로 나를 기억합니다.