← 모듈 공장 리스트

서사-연출-이야기-추진

risum 모듈 — RISU modules[] — 기능 확장

🗒️ 제작자 게시글

자료원문 보기 ↗

조회 1753 · 2026-07-15

제작자 의도 — 본문 전문 (1,851자)
※ 본 소개글은 라이트모드에 최적화되어 있습니다.
POCKETRISU UTILITY MODULE
서사 연출
·
이야기 추진
멈춘 장면에는 다음 단서를, 느슨해진 흐름에는 새로운 사건을.
필요한 순간에만 이야기를 한 칸 앞으로 움직이는 포켓리수 모듈입니다.
FORMAT
RISUM
─
SCOPE
CHAT
─
MODE
2 TYPES
01
CASE BOARD
이야기가 막혔을 때만 꺼내 쓰는 전개 도구
항상 이야기를 흔드는 자동 이벤트기가 아닙니다. 최근 대화와 미해결 흐름을 살핀 뒤, 사용자가 버튼을 누른 바로 다음 응답에만 짧은 전개 지시를 더합니다.
THREE CASE TYPES
세 가지 방식으로 다음 장면을 정리합니다
CASE 01
자연스러운
전개
이미 쌓인 긴장, 목표, 감정선과 미해결 단서를 이어 다음 장면의 방향을 잡습니다.
CASE 02
무작위
사건
설정과 연속성을 해치지 않는 범위에서 도착, 발견, 위험, 기회 같은 변수를 끼워 넣습니다.
CASE 03
비밀
서사
채팅별 장기 흐름을 별도 상태로 관리하고, 설정한 간격마다 현재 대화에 맞춰 갱신합니다.
비밀 서사는 어떻게 작동하나요?
눌러서 자세히 보기
매 메시지에 붙이는 요약이 아닙니다.
비밀 서사는 대화문과 분리된
채팅별 숨은 상태
로 저장됩니다. 화면이나 메시지 기록에는 나타나지 않으며, 평소 응답마다 전체 내용을 다시 만들거나 전송하지 않습니다.
평소 대화
저장된 비밀 서사는 그대로 대기합니다. 설정한 갱신 간격에 도달하지 않았다면 비밀 서사 관리용 추가 호출은 일어나지 않습니다.
갱신 시점
선택한 응답 횟수에 도달하면, 이전에 저장된 비밀 서사와 설정한 수만큼의 최근 대화만 관리용 LLM에 보냅니다. 새 장기 흐름을 받으면 기존 상태를 새 내용으로 덮어씁니다.
이야기 추진
버튼을 누르면 저장된 비밀 서사와 최근 대화를 꺼내 다음 장면의 방향을 한 번 설계합니다. 만들어진 방향은 다음 응답에만 반영되고, 비밀 서사 원문 자체가 채팅에 출력되지는 않습니다.
초기화
비밀 서사 초기화를 누르면 현재 채팅에 저장된 장기 흐름과 갱신 기록만 비워집니다. 다른 채팅의 비밀 서사에는 영향을 주지 않습니다.
한 줄 요약
· 기억은 채팅방에 보관하고, 갱신하거나 이야기를 추진할 때만 필요한 부분을 꺼내 씁니다.
▾
settings/
// 필요한 만큼만 조절
설정
역할
전개 방식
자연스러운 전개 또는 무작위 사건을 선택합니다.
비밀 서사 유지
채팅별 장기 흐름을 자동으로 관리할지 결정합니다.
갱신 간격
3, 5, 8, 12, 20회 중 하나를 선택합니다.
최근 메시지 수
전개 계획에 참고할 최근 문맥의 범위를 정합니다.
OPERATION FLOW
버튼 한 번, 다음 응답 한 번
버튼을 누른 상태는 다음 입력에서 먼저 소비됩니다. 보조 호출이 실패하거나 형식 검증을 통과하지 못해도 본 응답 생성은 막히지 않습니다.
1
모듈을 활성화하고 서사 연출 사용을 켭니다.
2
원하는 전개 방식과 문맥 범위를 선택합니다.
3
최근 메시지 아래 이야기 추진을 누르고 평소처럼 다음 입력을 보냅니다.
PERMISSION NOTICE
이 모듈은 스크립트와 보조 모델 호출 기능을 사용합니다. 가져오기 과정에서 권한 확인이 표시되면 내용을 확인한 뒤 허용해 주세요.
ATTACHED FILE
POCKETRISU MODULE
서사-연출-이야기-추진.risum
게시글에 첨부된 파일을 내려받아 포켓리수의 모듈 관리 화면에서 가져오면 됩니다.
참고 게시글
HTML Guide v6.4.md - 아카라이브 HTML 작성 가이드
ps. 장기챗에서 서사 진행 안 될때 쓰면 효과가 좀 있는데 자주 쓰면 체감 효과 떨어지지 싶음
나는 대화 500개 넘은 장기챗에서 함 써봤어
ONE CLICK ─ ONE RESPONSE ─ ONE STEP FORWARD

정체

🧰 프롬프트·올인원기술분류 PROMPT슬롯 prompt서사 연출 · 이야기 추진

설명

다음 응답의 전개를 한 번 추진하고, 채팅별 비밀 서사를 자동으로 관리합니다.
파싱된 모듈 전체 (8,618자)
{
 "id": "981e90d9-ca0a-5138-b126-6b1062346348",
 "namespace": "pocketrisu-story-progression",
 "name": "서사 연출 · 이야기 추진",
 "description": "다음 응답의 전개를 한 번 추진하고, 채팅별 비밀 서사를 자동으로 관리합니다.",
 "lowLevelAccess": true,
 "hideIcon": false,
 "lorebook": [],
 "regex": [
  {
   "comment": "최근 메시지 서사 작업",
   "in": "$",
   "out": "{{#when::{{chat_index}}::>=::{{lastmessageid}}}}<span role=\"button\" risu-btn=\"prs-story-advance\" title=\"다음 응답에서 이야기 전개를 한 번 추진합니다\">🎬 이야기 추진</span> <span role=\"button\" risu-btn=\"prs-story-reset\" title=\"이 채팅의 비밀 서사를 초기화합니다\">🗑 비밀 서사 초기화</span>{{/when}}",
   "type": "editdisplay",
   "ableFlag": false
  }
 ],
 "customModuleToggle": "=서사 연출=group\nstory_enabled=서사 연출 사용\nstory_mode=전개 방식=select=자연스러운 전개,무작위 사건\nstory_secret_plot_enabled=비밀 서사 유지\nstory_secret_plot_interval=비밀 서사 갱신 간격=select=3,5,8,12,20\nstory_context_depth=참고할 최근 메시지 수=select=4,8,12,20\nstory_debug=진단 로그\n==groupEnd",
 "trigger": [
  {
   "comment": "응답 전개 계획",
   "type": "input",
   "conditions": [],
   "effect": [
    {
     "type": "triggerlua",
     "code": "\nlocal PREFIX = \"prs_story_\"\n\nlocal function global(tid, key, fallback)\n  local value = getGlobalVar(tid, \"toggle_story_\" .. key)\n  if value == nil or value == \"\" or value == \"null\" then return fallback end\n  return value\nend\n\nlocal function chat(tid, key, fallback)\n  local value = getChatVar(tid, PREFIX .. key)\n  if value == nil or value == \"\" or value == \"null\" then return fallback end\n  return value\nend\n\nlocal function put(tid, key, value)\n  setChatVar(tid, PREFIX .. key, tostring(value or \"\"))\nend\n\nlocal function debugLog(tid, message)\n  if global(tid, \"debug\", \"0\") == \"1\" then\n    print(\"[서사 연출] \" .. tostring(message))\n  end\nend\n\nlocal function selectedNumber(tid, key, options, fallback)\n  local raw = global(tid, key, \"\")\n  local index = tonumber(raw)\n  if index ~= nil and options[index + 1] ~= nil then return options[index + 1] end\n  return fallback\nend\n\nlocal function extractObject(text)\n  if type(text) ~= \"string\" then return nil end\n  local fenced = text:match(\"\\96\\96\\96[Jj][Ss][Oo][Nn]%s*(.-)%s*\\96\\96\\96\")\n  local candidate = fenced or text:match(\"(%b{})\")\n  if not candidate then return nil end\n  local ok, decoded = pcall(json.decode, candidate)\n  if not ok or type(decoded) ~= \"table\" then return nil end\n  return decoded\nend\n\nlocal function callAux(tid, messages)\n  local ok, result = pcall(function()\n    return axLLM(tid, messages, false)\n  end)\n  if not ok then return nil end\n  local text = type(result) == \"table\" and result.result or result\n  if type(text) ~= \"string\" or text == \"\" then return nil end\n  return extractObject(text)\nend\n\nlocal function collectContext(tid, depth)\n  local length = tonumber(getChatLength(tid) or 0) or 0\n  local assistantCount = 0\n  local recent = {}\n  local startIndex = math.max(0, length - depth)\n  for index = 0, length - 1 do\n    local ok, message = pcall(json.decode, getChatMain(tid, index))\n    if ok and type(message) == \"table\" then\n      if message.role == \"char\" then assistantCount = assistantCount + 1 end\n      if index >= startIndex then\n        recent[#recent + 1] = tostring(message.role or \"unknown\") .. \": \" .. tostring(message.data or \"\")\n      end\n    end\n  end\n  return table.concat(recent, \"\\n\"), assistantCount\nend\n\nonInput = async(function(tid)\n  setChatVar(tid, \"prs_story_request_injection\", \"\")\n  if global(tid, \"enabled\", \"0\") ~= \"1\" then\n    setChatVar(tid, \"prs_story_advance_pending\", \"0\")\n    return\n  end\n\n  local intervalOptions = {3, 5, 8, 12, 20}\n  local contextOptions = {4, 8, 12, 20}\n  local interval = selectedNumber(tid, \"secret_plot_interval\", intervalOptions, 8)\n  local contextDepth = selectedNumber(tid, \"context_depth\", contextOptions, 12)\n  interval = math.max(1, math.floor(interval))\n  contextDepth = math.max(1, math.floor(contextDepth))\n\n  local recentContext, assistantCount = collectContext(tid, contextDepth)\n  local existingPlot = chat(tid, \"secret_plot\", \"\")\n  local lastAttempt = tonumber(chat(tid, \"last_maintenance_attempt_assistant_count\", \"0\")) or 0\n  local lastMaintained = tonumber(chat(tid, \"last_maintained_assistant_count\", \"0\")) or 0\n  local maintenanceDue = global(tid, \"secret_plot_enabled\", \"0\") == \"1\"\n    and assistantCount > lastAttempt\n    and (existingPlot == \"\" or assistantCount - lastMaintained >= interval)\n\n  if maintenanceDue then\n    put(tid, \"last_maintenance_attempt_assistant_count\", assistantCount)\n    local maintenanceMessages = {\n      {\n        role = \"system\",\n        content = [[You are a story progression planner maintaining a hidden long-term arc for this roleplay. Use the established scenario, characters, persona, and recent conversation. Preserve an active mystery unless the actual story materially changes or resolves it. If the prior arc is resolved, return it with completed=true; on a later pass create a related successor arc. Keep the plan spoiler-safe and useful. Do not write scene prose, dialogue, or exact character actions. Do not decide the user's actions. Return only valid JSON: {\"overarchingArc\":{\"description\":\"2-4 sentence arc\",\"protagonistArc\":\"1-2 sentence growth trajectory\",\"characterArc\":\"optional supporting-character trajectory\",\"completed\":false}}.]],\n      },\n      {\n        role = \"user\",\n        content = \"Previous hidden plot:\\n\" .. existingPlot .. \"\\n\\nRecent conversation:\\n\" .. recentContext,\n      },\n    }\n    local maintained = callAux(tid, maintenanceMessages)\n    local arc = maintained and maintained.overarchingArc or nil\n    if type(arc) == \"table\" and type(arc.description) == \"string\" and arc.description ~= \"\"\n      and type(arc.protagonistArc) == \"string\" and type(arc.completed) == \"boolean\" then\n      local encoded = json.encode(arc)\n      setChatVar(tid, \"prs_story_secret_plot\", encoded)\n      put(tid, \"last_maintained_assistant_count\", assistantCount)\n      existingPlot = encoded\n      debugLog(tid, \"비밀 서사를 갱신했습니다\")\n    else\n      debugLog(tid, \"비밀 서사 검증에 실패하여 이전 내용을 유지합니다\")\n    end\n  end\n\n  if chat(tid, \"advance_pending\", \"0\") ~= \"1\" then return end\n  setChatVar(tid, \"prs_story_advance_pending\", \"0\")\n\n  local mode = global(tid, \"mode\", \"0\") == \"1\" and \"RANDOM_EVENT\" or \"NATURAL\"\n  local directionMessages = {\n    {\n      role = \"system\",\n      content = [[You are a story progression planner. Return one concise direction for the next main response. In NATURAL mode, advance existing tension, goals, consequences, character motives, and unresolved threads. In RANDOM_EVENT mode, create a surprising but plausible interruption, complication, arrival, reveal, danger, or opportunity. Preserve continuity and the established setting. Use hidden plot context without revealing spoilers, rushing resolution, or making events feel forced. Do not write scene prose, dialogue, or the finished response. Do not decide the user's actions. Return only valid JSON: {\"direction\":\"brief actionable instruction for the next response\"}.]],\n    },\n    {\n      role = \"user\",\n      content = \"Mode: \" .. mode .. \"\\nHidden plot: \" .. existingPlot .. \"\\nRecent conversation:\\n\" .. recentContext,\n    },\n  }\n  local directed = callAux(tid, directionMessages)\n  if directed and type(directed.direction) == \"string\" and directed.direction ~= \"\" then\n    put(tid, \"request_injection\", \"<story_direction>\\n\" .. directed.direction .. \"\\n</story_direction>\")\n    debugLog(tid, \"이야기 추진 지시를 반영했습니다\")\n  else\n    debugLog(tid, \"이야기 추진 지시 검증에 실패하여 반영하지 않습니다\")\n  end\nend)\n\nonButtonClick = async(function(tid, code)\n  if code == \"prs-story-advance\" then\n    setChatVar(tid, \"prs_story_advance_pending\", \"1\")\n    alertNormal(tid, \"다음 응답에서 이야기 추진을 한 번 실행합니다.\")\n    return\n  end\n  if code == \"prs-story-reset\" then\n    setChatVar(tid, \"prs_story_secret_plot\", \"\")\n    setChatVar(tid, \"prs_story_last_maintained_assistant_count\", \"0\")\n    setChatVar(tid, \"prs_story_last_maintenance_attempt_assistant_count\", \"0\")\n    setChatVar(tid, \"prs_story_advance_pending\", \"0\")\n    setChatVar(tid, \"prs_story_request_injection\", \"\")\n    alertNormal(tid, \"이 채팅의 비밀 서사를 초기화했습니다.\")\n  end\nend)\n"
    },
    {
     "type": "v2SystemPrompt",
     "location": "promptend",
     "value": "prs_story_request_injection",
     "valueType": "var",
     "indent": 0
    }
   ]
  }
 ],
 "assets": []
}

🔗 이것과 비슷한 인기 자산

🍉서리 프롬프트 for Gemini v12.1
🍉서리 프롬프트 for Gemini v12.1
👍162 ·
🍉서리 프롬프트 for Gemini v10-5 bug fixed
🍉서리 프롬프트 for Gemini v10 5 bug fixed
👍159 ·
🍉서리 프롬프트 for Claude v8-1
🍉서리 프롬프트 for Claude 8 1
👍125 ·
🍉서리 프롬프트 for Claude v8-1 alt
🍉서리 프롬프트 for Claude 8 1 alt
👍86 ·
🐞 W2 · /city/asset