「말포이가 나보고 책임지래」가 숫자와 화면으로 어떻게 돌아가는지 적은 문서예요. 플레이어는 해리 포터로 고정이고, 이름 입력 화면은 없어요. 「처음부터」를 누르면 바로 1화 대연회장 아침이 시작돼요.
이야기 비트와 선택지 문구는 03 시나리오, 그림은 05 아트에 있어요. 여기서는 그 값들을 엔진이 어떻게 읽는지, 플레이어한테 뭘 보여 주고 뭘 숨기는지를 정해요.
엔진(engine.js)·화면(index.html)·스타일(style.css)은 1판 것을 그대로 써요. 1판에서 이미 끝까지 돌아가는 걸 확인했기 때문에 v2 는 상수 몇 개와 「처음부터」 흐름만 바꿔요(아래 08장). 스크립트 형식도 1판과 한 글자도 다르지 않아요. 바뀐 건 내용이에요 — 성배 해체가 해독약 재료로, 오리지널 주인공이 해리로 바뀌었어요.
| 구성 요소 | 파일 | v2 에서 바뀌나 | 이 문서의 장 |
|---|---|---|---|
| 변수·플래그·인물·엔딩 정의 | game/story/meta.json | 새로 씀(바이블 6-2 원문) | 02 · 03 |
| 챕터 스크립트 5개 | game/story/ch1.json ~ ch5.json | 새로 씀, 형식은 같음 | 04 |
| 스크립트 실행기·시작 검사 | game/engine.js | 상수만(08장) | 04 · 08 |
| 화면·메뉴 | game/index.html · game/style.css | 이름 입력 섹션과 타이틀 고지문을 뺌 | 05 · 06 · 09 |
| 저장 데이터 | 브라우저 localStorage, 접두사 dracots2_ | 접두사만 바뀜 | 07 |
서버는 없어요. 저장은 localStorage 만 쓰고, 외부 스크립트·폰트·추적 코드·measure.js 는 불러오지 않아요(바이블 8-1).
보이는 건 aff(하트)와 stage(해독약 재료) 둘이에요. 말포이 속을 재는 pride·honest 는 숨겨요. 자존심 수치가 화면에 뜨면 플레이어가 말포이 대사가 아니라 숫자를 보고 고르게 돼요.
| 이름 | 뜻 | 범위 | 시작 | 화면 표시 |
|---|---|---|---|---|
aff | 말포이가 해리한테 가진 호감·신뢰 | 0~100 | 10 | 보여요 — 수첩 하트 5칸, 채운 칸 = floor(aff/20), 숫자는 숨김 |
pride | 말포이의 자존심·가문 체면 집착 | 0~100 | 60 | 숨김 |
honest | 말포이가 자기 상태·마음을 말로 인정하는 정도 | 0~100 | 0 | 숨김 |
stage | 해독약 재료 | 0~7 | 0 | 보여요 — 수첩에 「해독약 재료 n/7」과 들어간 재료 이름 |
값을 바꾸는 규칙은 하나예요. set 줄과 선택지 vars 의 숫자는 더하는 양(+n/−n)이고, 한 번 적용할 때마다 범위 안으로 잘라요(clamp). pride 가 0에 붙어 있을 때 −4를 받으면 0에 머물고, 그다음 +2를 받으면 2가 돼요. 그래서 누적합과 실제 값이 다를 수 있어요.
증감 숫자는 1판 최종값과 같은 자리, 같은 값이에요(바이블 3-1). 선택지 문구와 의미만 해리 시점으로 바꿨어요. 숫자를 그대로 둔 덕분에 1판에서 맞춰 둔 엔딩 비율이 출발점이 돼요.
수첩에는 아래 이름이 들어간 순서대로 찍혀요. 엔진 상수 STAGES 와 같은 순서예요.
| n | 수첩 이름 | 들어가는 곳 | 고정/선택 | 근거 표시 |
|---|---|---|---|---|
| 1 | 이각수 뿔 | ch1_s4 슬러그혼 창고 | 고정 +1 | 폴리주스 재료 [원작 CS] |
| 2 | 풀잠자리 | ch2_s4 마법약 교실 | 고정 +1 | 21일 고는 재료 [원작 CS] |
| 3 | 붐슬랭 껍질 | ch2_s5, 선택 2-4 B·C | 선택 +1 | 폴리주스 재료 [원작 CS], 블레이즈 조달은 IF |
| 4 | 머리카락 한 올 | ch3_s4a(헤르미온느, 사과 성립) | 선택 +1 | 재료 규칙은 IF |
| 5 | 프린스의 메모 | ch3_s6a(해리가 출처를 털어놓음) | 선택 +1 | 혼혈 왕자 교과서 [원작 HBP], 재료 쓰임은 IF |
| 6 | 악마의 불 재 | ch4_s4, 선택 4-3 A·C | 선택 +1 | 악마의 불 [원작 DH], 재료 쓰임은 IF |
| 7 | 보름달 마무리 | ch5_s6 천문탑 | 해독약 경로면 고정 +1, brewed | 보름달 규칙은 폴리주스에서 빌림 [원작 CS], 나머지 IF |
재료 2는 ch1 에 불에 올려 둔 걸 ch2 에 건지는 흐름이라, 1화 날짜(9월 3일)와 2화 날짜(10월 24일) 사이가 21일보다 길어요. 날짜끼리 어긋나지 않아요.
하트는 20점마다 한 칸이에요. 시작값 10이면 빈 하트로 시작해요. 판정 문턱이 하트 칸 경계와 일부러 어긋나 있어서, 하트만 보고 엔딩을 정확히 맞히긴 어려워요.
aff | 채운 하트 | 이 구간에 걸린 판정 |
|---|---|---|
| 0~19 | 0칸 | 시작값 10이 여기예요 |
| 20~39 | 1칸 | 35 이상이면 E2 조건 하나가 맞아요 |
| 40~59 | 2칸 | 40 이상 E3 조건 · 45 이상이면 ch4_s5 에서 말포이가 처음 「해리」라고 불러요(called_name) · 50 이상이면 E5·E6 를 피해요 · 55 이상이 E1 조건 |
| 60~79 | 3칸 | 새로 걸리는 판정 없음 |
| 80~99 | 4칸 | 새로 걸리는 판정 없음 |
| 100 | 5칸 | 상한 |
챕터마다 고를 수 있는 선택지를 전부 한쪽으로 몰았을 때의 범위예요. 자르기 전 합이에요.
| 챕터 | aff | pride | honest | stage | 선택지 수 | 줄 목표 |
|---|---|---|---|---|---|---|
| 시작값 | 10 | 60 | 0 | 0 | — | — |
| ch1 1화 — 솥이 터졌다 | −5 ~ +15 | −8 ~ +6 | 0 ~ +10 | +1 | 5 | 170 |
| ch2 2화 — 포터, 빗자루 빌려줄까 | −13 ~ +19 | −12 ~ +10 | 0 ~ +14 | +1 ~ +2 | 5 | 180 |
| ch3 3화 — 슬러그 클럽 크리스마스 | −3 ~ +21 | −15 ~ +11 | 0 ~ +24 | 0 ~ +2 | 6 | 200 |
| ch4 4화 — 호그스미드, 그리고 필요의 방 | +2 ~ +22 | −18 ~ +12 | 0 ~ +24 | 0 ~ +1 | 6 | 200 |
| ch5 5화 — 보름달 뜨는 밤 | +3 ~ +15 | −4 ~ +6 | 0 ~ +16 | 0 ~ +1 | 5 (lost_brew 경로 4) | 270 |
| 합 | 0 ~ 100 | 3 ~ 100 | 0 ~ 88 | 2 ~ 7 | 27 | 1,020 |
lost_brew 경로에서 선택지가 하나 줄어드는 건 5-4(젓는 손이 떨리는 말포이)가 해독약이 있는 천문탑 씬(ch5_s6)에만 있기 때문이에요. 해독약이 성 뭉고로 간 경로는 ch5_s6x 로 빠져서 그 선택이 안 나와요.
챕터 안의 if 분기는 다섯 곳이에요. 앞 챕터까지 쌓인 값으로 「이번 장면이 열리나」를 정해요.
| 씬 | 식 | 참이면 | 거짓이면 | 그 앞에서 필요한 선택 |
|---|---|---|---|---|
| ch3_s3b | honest>=10 | ch3_s4a 사과 성립 — 재료 4, apol_herm | ch3_s4b 사과 불발 | 3-3 B(둘이 얘기하게 밖에 나가 있는다) |
| ch4_s2b | honest>=25 | ch4_s3a 론한테 고맙다고 함 — ron_thanks | ch4_s3b 화제 돌림 | 4-2 B(말포이가 말하게 둔다) |
| ch4_s5 | aff>=45 | ch4_s5a 처음 「해리」 — called_name | ch4_s5b 「포터, 먼저 나가.」 | 없음(누구나 지나감) |
| ch4_s6m | honest>=30 | ch4_s7a 답장을 직접 씀 — wrote_home | ch4_s7b 편지를 서랍에 | 4-4 A(답장, 네 말로 써) |
| ch5_s7 | honest>=40 | ch5_s7a 마음을 똑바로 말함 | ch5_s7b 돌려 말함 | 없음 |
엔딩은 ch5_judge 씬의 if 여섯 줄로만 정해요. 위에서부터 처음 맞는 줄로 가요. meta.json 의 cond 는 갤러리와 검사기가 읽는 사본이고, 엔진이 판정에 쓰지는 않아요(바이블 6-2).
| 순서 | id | 이름 | 종류 | cond 원문 | 가는 씬 | CG | 비율 목표 |
|---|---|---|---|---|---|---|---|
| 1 | E5 | 성 뭉고행 마차 | 배드 | pride>=65 && aff<50 | ch5_e5 | cg_e5 | 15% |
| 2 | E6 | 해독약은 성 뭉고에 | 배드 | flag:lost_brew && aff<50 | ch5_e6 | 없음 | 10% |
| 3 | E1 | 포터, 책임져 | 트루 | flag:brewed && stage>=7 && aff>=55 && honest>=45 && flag:called_name && flag:said_either | ch5_e1 | cg_e1 | 8% |
| 4 | E3 | 이대로 졸업한다 | 굿 | aff>=40 && honest>=20 && flag:said_stay | ch5_e3 → e3a/e3b → e3t | cg_e3 | 18% |
| 5 | E2 | 원래대로 돌아왔는데 | 굿 | flag:brewed && stage>=6 && aff>=35 | ch5_e2 | cg_e2 | 22% |
| 6 | E4 | 8학년 끝 | 노멀 | aff>=0 (항상 참) | ch5_e4 → e4a/e4b → e4t | 없음 | 27% |
aff<50 이 붙어 있어서, 하트를 두 칸 넘게 채운 플레이어는 배드로 안 빠져요.said_stay)를 고르고 관계가 충분하면, 말포이가 지금 몸으로 졸업하는 쪽을 골라요. 플레이어의 마지막 말이 해독약 유무보다 먼저 읽혀요.null 을 돌려 아무것도 안 고르고 진행된 적이 있어서, 엔진이 시작할 때 이 줄이 있는지 검사해요(04장 검사 7).E3·E4 는 해독약이 제대로 나왔는지(flag:brewed && stage>=6)에 따라 앞 장면만 바뀌고 뒤는 같아요.
| 엔딩 | 참일 때 | 거짓일 때 | 공통 뒤 |
|---|---|---|---|
| E3 | ch5_e3a — 약병을 열지 않은 채 달이 짐 | ch5_e3b — 해독약 없이 달이 짐 | ch5_e3t — 학기 마지막 날 호숫가 |
| E4 | ch5_e4a — 약을 마시고 돌아감 | ch5_e4b — 지금 몸으로 굳음 | ch5_e4t — 슬러그혼이 기록에 「종결」 |
E2 는 said_* 셋 중 뭘 골랐어도 나올 수 있어요. 그래서 E2 대사는 「말포이가 스스로 마시기로 했다」로 쓰고, 해리의 마지막 말을 깔고 가지 않아요.
node tools/validate.mjs(시드 20031014, 선택지 균등 무작위 10,000회)로 v2 스크립트를 쟀어요. 오류 0건 · 경고 2건으로 통과했고, 씬 83개 모두 어떤 경로로든 들러요. 결과는 E5 27.0% · E6 9.4% · E1 0.2%(10,000회 중 20회) · E3 18.4% · E2 12.6% · E4 32.5% 예요. 목표 대비로는 E5 +12.0%p · E6 −0.6%p · E1 −7.8%p · E3 +0.4%p · E2 −9.4%p · E4 +5.5%p 라서 E5 가 ±10%p 를 넘어요. validate 가 이걸 경고로 띄우고, 문턱을 바꿀지는 메인이 정해요(바이블 3-3). 1판 실측(E5 21.3% · E6 10.7% · E1 0.1% · E3 19.5% · E2 12.8% · E4 35.5%)과도 크게 다르지 않아요. 같은 값을 03 시나리오의 「v2 실측」 칸에도 적었어요.
E1 은 0.2%로 바이블 3-3 목표 「무작위 1% 안팎」보다 낮아요. 그런데 바이블 3-3 이 1순위 안으로 든 honest>=45 → honest>=40 은 지금 meta 의 E1 cond 에 이미 honest>=40 으로 들어가 있어요. 다음 조정안은 메인이 정해요.
무작위로 고르면 E1 이 거의 안 나오는 건 정상이에요. 트루 엔딩은 말포이한테 계속 솔직하게 굴고, 사과와 고백 장면을 다 열어야 나와요.
챕터 파일 하나가 씬 배열이고, 씬 하나가 줄 배열이에요. 엔진은 줄을 하나씩 읽어 실행해요. 형식은 1판과 같고 바이블 6-1 원문 그대로예요.
story/meta.json: {"title","vars":{"이름":{"min","max","start"}},"flags":[...],"chars":{"id":{"name","color","faces":[...]}},"endings":{"E1":{"name","kind","cond","cg"}},"chapters":["ch1",...,"ch5"]}
story/chN.json: {"id":"chN","title":"...","scenes":[{"id":"chN_s1","bg":"bg_x","lines":[ 줄... ]}]}
| t | 형식 | 뜻 | 이 게임에서 쓰는 법 |
|---|---|---|---|
narr | {"t":"narr","text"} | 서술 | 해리 1인칭 한다체 과거형. 「나는 솥을 봤다.」 말포이는 대명사 없이 「말포이」 |
say | {"t":"say","who","face","text"} | 대사 | 해리는 "who":"pc","face":"". 이름표는 meta 의 name(해리·말포이·론…) |
think | {"t":"think","text"} | 주인공 속마음 | 해리의 츳코미 한 줄, 반말, 30자 안팎. 챕터 줄 수의 15% 이하 |
show | {"t":"show","who","face","pos":"left|center|right"} | 인물 카드 표시 | 동시에 최대 2명. 해리 카드는 없음 |
hide | {"t":"hide","who"} | 인물 카드 숨김 | — |
bg | {"t":"bg","id"} | 씬 도중 배경 교체 | 12장 중에서만 |
cg | {"t":"cg","id"} | CG 표시 | 8장. 예: ch1_s3 솥이 터지는 순간 cg_cauldron |
cgoff | {"t":"cgoff"} | CG 닫기 | — |
set | {"t":"set","vars":{"x":+n},"flags":["f"]} | 변수 더하기·플래그 켜기 | 고정 재료(stage +1)와 분기 씬의 고정 증감 |
choice | {"t":"choice","prompt","options":[{"text","vars":{},"flags":[],"goto"?}]} | 선택지 | 27개, 모두 보기 셋. 문구 30자 이하 |
if | {"t":"if","cond":"식","goto"} | 참이면 goto, 거짓이면 다음 줄 | 중간 판정 다섯 곳 + 플래그 분기 + ch5_judge |
goto | {"t":"goto","scene"} | 같은 챕터 안 씬으로 | — |
ending | {"t":"ending","id"} | 엔딩 도달 | E1~E6 |
chapter_end | {"t":"chapter_end"} | 다음 챕터로 | 챕터 마지막 씬 끝. ch5 는 ch5_e6 의 ending 다음 줄 |
>= <= > < == !=, 정수만), flag:이름, &&, ||, ! 이에요. 괄호는 없어요. 이 게임의 cond 는 전부 && 만 써요.goto 가 없으면 배열의 다음 씬으로 가요. 그래서 씬 순서는 바이블 4장 표 순서와 같아야 해요.goto·if 는 같은 챕터 안에서만 움직여요. 챕터를 건너는 점프는 없어요.show 를 다시 써야 보여요.{name} 치환은 엔진에 남아 있지만 이 게임에선 늘 「해리」예요. 집필에선 {name} 대신 「해리」를 직접 써요(바이블 6-1 v2 덧붙임).게임을 열면 엔진이 스크립트 전체를 한 번 훑어요. 하나라도 틀리면 콘솔에 오류를 남기고 타이틀에 빨간 줄 하나를 띄워요. 플레이어가 중간에 멈춰 버리는 것보다 시작 화면에서 바로 보이는 쪽이 고치기 쉬워요.
| # | 검사 | v2 에서 걸리기 쉬운 곳 |
|---|---|---|
| 1 | say/show 의 who 가 meta.chars 에 있고 face 가 그 faces 안에 있음(pc 는 "") | 1판 인물(판지·나르시사)이 남은 줄. 나르시사는 v2 에서 편지로만 나와서 say 가 있으면 안 돼요 |
| 2 | 모든 bg·cg id 가 prompts.json items 에 있음 | 1판 배경 id(저택·감정실 계열)가 남은 씬 |
| 3 | 모든 goto 가 같은 챕터 씬 id | 새로 생긴 분기 씬 이름 오타 |
| 4 | 각 챕터 마지막 씬이 chapter_end 로 끝남 | ch5_e6 뒤 줄 빠뜨림 |
| 5 | set·option 의 vars 키가 meta.vars 에, flags 가 meta.flags 에 있음 | 1판 플래그 이름이 남은 줄 |
| 6 | cond 가 문법대로 파싱됨 | 괄호를 쓴 식 |
| 7 | ch5_judge 마지막 줄이 항상 참인 aff>=0 | 판정 줄 순서를 바꾸다 빠뜨림 |
검사기 tools/validate.mjs 가 v2 를 읽으려면 인물 접두사 정규식과 금지어 목록을 고쳐야 해요(바이블 9-3). 그건 메인 몫이에요.
게임은 game/index.html 한 페이지 안에서 화면을 바꿔 가며 보여 줘요. 페이지 이동이 없어서 뒤로 가기를 눌러도 게임이 안 끊겨요. 1판에 있던 이름 입력 화면과 타이틀 고지 창은 없앴어요.
| 화면 | 들어오는 길 | 보이는 것 | 나가는 길 |
|---|---|---|---|
| 타이틀 | 처음 열기 · 엔딩 뒤 · 메뉴의 「타이틀로」 | 제목·부제·메뉴만(09장). 시작 검사가 실패하면 빨간 한 줄 | 각 메뉴. 「이어하기」는 dracots2_auto 가 없으면 흐리게 |
| 본편 | 「처음부터」(바로 ch1_s1) · 이어하기 · 불러오기 | 배경, 인물 반신 카드 최대 2명, 대사창(이름표·본문), 메뉴 줄(수첩·백로그·자동·스킵·저장·설정). CG 중엔 CG 와 흐린 같은 그림 여백 | 메뉴 버튼, 선택지, 엔딩 |
| 수첩 | 본편 메뉴 「수첩」 · N 키 | 제목 「말포이와의 사이」 하트 5칸, 「해독약 재료 n/7」과 들어간 재료 이름, 오늘 날짜(08장 DAYS), 끝 문구 「기한은 6월 보름 밤이에요.」 숨은 변수 둘은 안 보여요 | 닫기 → 본편 같은 줄 |
| 백로그 | 본편 메뉴 「백로그」 · L · ↑ · PageUp | 최근 300줄(이름표 + 본문), 고른 선택지 문구는 다른 색 한 줄. think 줄은 이름표 없이 기울임 | 닫기 → 본편 같은 줄. 되감기 없음 |
| 세이브/불러오기 | 본편 메뉴 「저장」 · 타이틀 「불러오기」 | 수동 6칸 + 자동 1칸. 칸마다 챕터 제목과 저장 시각, 썸네일 없음. 타이틀에서 열면 불러오기만 | 불러오기 → 그 씬·순번. 닫기 → 원래 화면 |
| 설정 | 타이틀 · 본편 메뉴 | 글자 속도 슬라이더 10~100 + 「즉시」, 자동 진행, 스킵 범위 안내, 세이브 내보내기/불러오기(JSON 텍스트), 그 아래 「브라우저가 저장 데이터를 지울 수 있어요」 한 줄(타이틀에서 옮겨 옴) | 닫기 → 원래 화면. 바꾸면 바로 dracots2_settings 에 저장 |
| 엔딩 갤러리 | 타이틀 | CG 8칸(cg_cauldron · cg_pitch · cg_hands · cg_ash · cg_e1 · cg_e2 · cg_e3 · cg_e5) + CG 없는 E4·E6 이름 카드 2장. 안 본 칸은 잠김 | 칸을 누르면 크게 보기 → 닫기 |
| 엔딩 목록 | 갤러리 안 탭 | 엔딩 6개를 E1~E6 순으로. 본 엔딩은 이름·종류, 안 본 엔딩은 종류만(이름은 「???」) | 닫기 → 타이틀 |
| 기획서 | 타이틀 메뉴 「기획서」 | plan/index.html 로 링크(게임 밖 페이지) | 브라우저 뒤로 가기 |
갤러리 잠금은 저장 키를 늘리지 않고 판정해요. cg 줄의 「씬id:순번」이 dracots2_read 에 있으면 그 CG 가 열리고, E4·E6 카드는 dracots2_endings 로 봐요(1판 방식 그대로, 이 문서 제안).
| 요소 | 가로 화면 | 세로 화면 |
|---|---|---|
| 화면 높이 | 100dvh — 주소창이 들어가고 나와도 대사창이 안 가려져요 | |
| 대사창 | 화면 아래 26% | 화면 아래 30% |
| 인물 카드 | 높이 56vh, 4:5 둥근 모서리 | 폭 62vw, 같은 모양 |
| 카드 위치 | left/center/right = 22% / 50% / 78%. 최대 2명. 말하는 인물 밝기 100%, 나머지 70% | |
| 카드 안 그림 | object-fit:cover; object-position:50% 20% — 정사각 그림에서 얼굴 있는 위쪽을 살려요 | |
| 배경 | 위아래가 잘림 | 좌우가 잘림 |
| CG | object-fit:contain, 여백엔 같은 그림을 흐리게. CG 동안 인물 카드 숨김 | |
해리가 말할 때는 카드가 없어요. 이름표만 「해리」로 바뀌고, 말포이 카드가 떠 있으면 말포이가 70% 밝기로 내려가요. 해리 얼굴은 CG 에만 나오고, 거기서도 뒷모습·옆모습·손 위주예요(바이블 5-3). 플레이어가 해리 눈으로 보는 게임이라 정면 얼굴을 자주 보여 줄 이유가 없어요.
진행 입력(탭·Space·Enter)은 바이블에서 정했고, 나머지 키는 1판 engine.js 의 onKey() 에 이미 들어 있는 걸 2026-10-14 코드로 확인해 옮겼어요. 키보드가 없어도 화면 버튼으로 같은 일을 할 수 있어요.
| 입력 | 본편 | 선택지가 떠 있을 때 | 창이 열렸을 때 | 근거 |
|---|---|---|---|---|
| 화면 탭 / 클릭 | 글자가 찍히는 중이면 전부 표시, 다 찍혔으면 다음 줄 | 선택지 버튼을 눌러야 고름(빈 곳 탭은 무시) | 창 안 버튼만 | 바이블 8-5 |
| Space · Enter | 탭과 같음 | Enter 는 초점이 간 선택지를 고름 | 초점이 간 버튼 | 바이블 8-5 |
| 1 ~ 9 | — | 그 번호 선택지를 바로 고름(이 게임은 3까지) | — | engine.js |
| L · ↑ · PageUp | 백로그 열기 | 백로그 열기 | — | engine.js |
| A | 자동 진행 켜고 끄기 | 자동 진행은 여기서 멈춰 있음 | — | engine.js |
| S | 스킵 켜고 끄기(읽은 줄만) | 스킵은 여기서 멈춰 있음 | — | engine.js |
| N | 수첩 열기 | — | — | engine.js |
| Esc | — | — | 창 닫기 | engine.js |
| Tab | 브라우저 기본 | 선택지 사이 초점 이동 | 창 안에서만 초점이 돎(빠져나가지 않음) | engine.js |
e.isComposing 이면 키를 안 받아요. 설정 창의 세이브 붙여넣기 칸에서 한글을 치다가 게임이 넘어가는 일을 막아요.dracots2_read 에 있어요. 엔딩 여섯 개를 다 보려면 2회차부터 이 표시가 길잡이가 돼요.같은 도메인의 다른 페이지와 저장소를 나눠 쓰니까 이 게임 키는 모두 dracots2_ 로 시작해요. 1판은 dracots_ 였어요. 씬 id 는 1판과 같은데 플래그 이름이 달라서, 1판 세이브를 읽으면 변수·플래그가 엉켜요. 그래서 접두사를 바꾸고 1판 세이브는 아예 안 읽어요(바이블 8-3).
| 키 | 내용 | 쓰는 때 | 지워지는 때 |
|---|---|---|---|
dracots2_save_1 ~ dracots2_save_6 | 수동 세이브 6칸 | 저장 칸을 누를 때 | 덮어쓰기 · 브라우저 정리 |
dracots2_auto | 자동 세이브 1칸 | 씬에 들어갈 때마다 | 다음 씬 진입 · 「처음부터」 |
dracots2_read | 읽은 줄(씬id:순번)·고른 선택지 — 회차 공통 | 줄 표시 · 선택 | 브라우저 정리만 |
dracots2_endings | 본 엔딩 id 목록 — 세이브와 별개 | ending 줄 도착 | 브라우저 정리만 |
dracots2_settings | 설정(글자 속도·자동 진행) | 설정을 바꿀 때 | 브라우저 정리만 |
형식은 1판과 같아요: {"v":1,"ch","scene","idx","vars","flags","name","shown","bg","cg","at"}
| 필드 | 뜻 | 예 (3화 밤 병동, 해리가 혼혈 왕자 얘기를 막 꺼낸 자리) |
|---|---|---|
v | 세이브 형식 버전 | 1 |
ch | 챕터 id | "ch3" |
scene | 씬 id | "ch3_s6a" |
idx | 씬 안 줄 순번(0부터) | 12 |
vars | 변수 넷 | {"aff":48,"pride":41,"honest":28,"stage":4} |
flags | 켜진 플래그 | ["blaise_ok","apol_herm"] |
name | 주인공 이름 — 늘 같음 | "해리" |
shown | 떠 있는 인물 카드 | [{"who":"draco","face":"surprised","pos":"center"}] |
bg | 지금 배경 | "bg_wing" |
cg | 지금 CG, 없으면 null | null |
at | 저장 시각 — 칸에 보여 줄 값 | 저장한 순간의 실제 시각 |
위 예의 vars 숫자는 설명용으로 지은 값이에요(어떤 경로에서 정확히 이 값이 나오는지는 계산하지 않았어요). stage 4는 고정 재료 둘에 붐슬랭 껍질과 머리카락 한 올이 들어간 상태라는 뜻이에요. ch3_s6a 의 set 줄을 지나면 5가 되고 scar_told 가 켜져요.
name 칸은 이름 입력이 없어져서 쓸모가 줄었지만 지우지 않아요. 형식을 1판과 똑같이 두는 쪽이 엔진을 안 건드려도 돼서예요.
dracots2_ 로 시작하는 것만 받아요. 세이브의 scene 이 스크립트에 없으면 그 칸은 버리고 알려 줘요(이 문서 제안).| 항목 | 값 | Ren'Py 기본값과 비교 |
|---|---|---|
| 진행 | 화면 탭 · Space · Enter. 글자가 찍히는 중이면 첫 탭은 전부 표시 | — |
| 글자 속도 | 기본 초당 40자, 슬라이더 10~100 + 「즉시」 | text_cps 0(즉시)이 기본 — 이 게임은 찍히는 쪽이 기본 |
| 자동 진행 | 기본 꺼짐. 대기 = 글자 수 × 50ms + 1,200ms | afm_enable False — 같음 |
| 스킵 | 읽은 줄만. 선택지에서 멈춤 | skip_unseen False — 같음 |
| 백로그 | 최근 300줄, 고른 선택지 포함 | GUI 기본 history_length 250 — 50줄 더 김 |
| 되감기 | 없음(백로그로 대신) | rollback_length 128 — 안 넣음 |
| 이미 고른 선택지 | ✓ 표시 | — |
| 수첩 | 하트 5칸(floor(aff/20)) · 「해독약 재료 n/7」 · 날짜 | — |
| 화면 높이 | 100dvh. 세로 화면 대사창 30%, 가로 26% | — |
| 이미지 | 다음 씬 bg·등장 인물 표정을 씬 진입 때 미리 받고 decode() 뒤 교체 | predict_statements 32문장 앞까지 미리 불러오기 — 씬 단위로 같은 효과 |
v2 의 권장 줄 길이는 15~50자, 상한 90자예요(바이블 4-0). 1판보다 권장 길이가 짧아졌어요 — 대사가 끌고 가는 웹소설 호흡으로 바꾸면서 한 줄을 짧게 끊기로 했거든요. python3 으로 계산했고, 자동 진행 대기는 글자가 다 찍힌 뒤부터 센다고 봤어요(이 문서의 해석 — 바이블은 시작 시점을 안 정했어요).
| 줄 길이 | 다 찍히는 시간(초당 40자) | 자동 진행 대기 | 예 |
|---|---|---|---|
| 15자(권장 최소) | 0.375초 | 1,950ms | 「포터, 칼 그렇게 잡지 마.」 정도 |
| 50자(권장 최대) | 1.25초 | 3,700ms | 대사 한 줄 + 짧은 행동 묘사 |
| 90자(상한) | 2.25초 | 5,700ms | 편지 인용처럼 길게 가야 하는 줄만 |
한 회차 약 45~65분은 추정이에요 — 읽는 줄 약 860줄(2026-10-14 실측 평균 862줄) × 줄당 3~4.5초(바이블 1-1). 줄당 초는 가정값이고, 한국어 비주얼 노벨을 분당 몇 자 읽는지는 찾지 못해서 미확인이에요.
| 상수/문구 | 1판 | v2 |
|---|---|---|
P(저장 접두사) | dracots_ | dracots2_ |
DEFAULT_NAME | 로빈 | 해리 |
| 「처음부터」 흐름 | 이름 입력 화면 → 시작 | 바로 시작(newGame('해리')) |
STAGES | 해독약 재료 이름 7개 | 이각수 뿔 · 풀잠자리 · 붐슬랭 껍질 · 머리카락 한 올 · 프린스의 메모 · 악마의 불 재 · 보름달 마무리 |
DAYS | N일째 · 2003년 날짜 | ch1 1998년 9월 3일(목) · ch2 1998년 10월 24일(토) · ch3 1998년 12월 18일(금) · ch4 1999년 2월 13일(토) · ch5 1999년 6월, 학기 마지막 주 보름 |
| 수첩 하트 제목 / aria | 드레이코와의 사이 / 드레이코의 신뢰 | 말포이와의 사이 / 말포이의 신뢰 |
| 수첩 단계 제목 | 성배 해체 n/7 | 해독약 재료 n/7 |
| 수첩 끝 문구 | 2003년 날짜가 박힌 기한 문구 | 기한은 6월 보름 밤이에요. |
5화 날짜를 숫자로 안 박는 건 1999년 6월 보름이 정확히 며칠인지 확인하지 못해서예요. 평균 삭망월로 계산하면 6월 28일 무렵이라는 추정만 있어요(바이블 1-2). 화면에는 「학기 마지막 주 보름」까지만 써요.
수첩 하트 제목이 「드레이코」가 아니라 「말포이」인 건 해리 시점이라서예요. 해리는 E1 마지막 대사 한 번 말고는 말포이를 성으로 불러요. 이름표도 같은 이유로 「말포이」예요.
1판 타이틀에는 제목 밑에 한 줄 소개, 긴 고지문 상자, 「제작:」 줄, 저장 경고가 쌓여 있었어요. 주인이 이걸 보고 반려했어요. v2 타이틀엔 제목·부제·메뉴만 둬요.
| 요소 | 내용 |
|---|---|
| 제목 | 말포이가 나보고 책임지래 |
| 부제 | 8학년 마법약 사고 수습 중 |
| 메뉴 | 이어하기 · 처음부터 · 불러오기 · 엔딩 갤러리 · 설정 · 기획서 |
| 없앤 것 | 고지문 상자, 「제작: …」 줄, 한 줄 소개 문단, 「브라우저가 저장 데이터를 지울 수 있어요」 줄(설정 화면 세이브 칸 아래로 옮김), 이름 입력 화면 |
| 「처음부터」 | 누르면 바로 ch1 시작 — newGame('해리') |
<title> | 말포이가 나보고 책임지래 — 해리 포터 팬 미연시 |
| meta description | 슬러그혼 수업에서 솥이 터졌고, 말포이가 여자가 됐어요. 같은 조였던 해리는 해독약이 나올 때까지 옆에 붙어 있어야 해요. |
탭 제목과 meta description 은 화면이 아니라 검색·공유 카드에 쓰이는 글이라 「팬 미연시」 표기를 남겨요. 고지문을 뺀 결정으로 생기는 위험은 06 위험·운영의 고지 정책표에 따로 적었어요.
모바일 세로 화면에서 제목이 두 줄을 넘지 않는지는 실제 화면으로 확인해야 해요. 제목 후보 셋 중 이걸 고른 이유 하나가 「모바일 타이틀에서 덜 꺾인다」였거든요(바이블 1-1). 확인은 미확인 — v2 타이틀을 아직 띄워 보지 않았어요.
fangame/draco-ts/game/engine.js 의 onKey()(1판 코드, 2026-10-14 열어 확인).tools/validate.mjs, 시드 20031014, 무작위 10,000회(바이블 3-3 에 옮겨 둔 값).