diff --git a/docs/assets/elder-choice.jpg b/docs/assets/elder-choice.jpg new file mode 100644 index 0000000..0eaf911 Binary files /dev/null and b/docs/assets/elder-choice.jpg differ diff --git a/docs/assets/journal-after.jpg b/docs/assets/journal-after.jpg new file mode 100644 index 0000000..45b1b3c Binary files /dev/null and b/docs/assets/journal-after.jpg differ diff --git a/docs/assets/journal-before.jpg b/docs/assets/journal-before.jpg new file mode 100644 index 0000000..bdb4975 Binary files /dev/null and b/docs/assets/journal-before.jpg differ diff --git a/docs/en.md b/docs/en.md new file mode 100644 index 0000000..0603771 --- /dev/null +++ b/docs/en.md @@ -0,0 +1,81 @@ +# Quests Engine — quests, their steps and the journal + +Quests Engine keeps track of the player's tasks. A quest has a name and a numbered list of steps; scenarios start it, move it to the next step, mark things with tags and finish it. The **Journal** panel shows the quests the player has taken, and the game saves their state. + +It is used by Cthangover (the prologue's awakening and the old house) and by RPG Plus (the woodland quests). + +## The journal + +Open it with the journal icon on the toolbar. Before the player has taken any quest, it is empty: + +![The Journal in RPG Plus at the start: Active and Completed tabs, "No quests" on both pages.](assets/journal-before.jpg) + +In RPG Plus the elder of the village gives the first quest. Ask him where to look: + +![The elder's house: the hero in front of the elder, two answers on the right — "Can a wolf put out lamps?" and "Where do I find it?".](assets/elder-choice.jpg) + +After the answer the quest is in the journal: + +![The Journal after the talk: "A light on the ledger" in the Active list; on the right "Entry II of V", the first step struck through and the current step "Defeat the wolf by the cave in the eastern forest. Find the amber heart."](assets/journal-after.jpg) + +- **Active** lists quests in progress, **Completed** the finished ones. Quests not yet started never appear. +- The right page shows the selected quest: steps already done are struck through, the current step is marked, and later steps stay hidden, so the journal never gives the story away. +- Tags the quest has earned are shown as small gold labels under the entry. + +## A quest definition + +Quests are JSON files of kind `quest` in a mod's `quests/` folder. This is the quest from the pictures (from RPG Plus): + +```json +{ + "Kind": "quest", + "Items": [ + { + "Id": "woodland_ward", + "Name": "rpg_plus/quest/ward/name", + "StatusToDescription": { + "0": "rpg_plus/quest/ward/0", + "1": "rpg_plus/quest/ward/1", + "2": "rpg_plus/quest/ward/2", + "3": "rpg_plus/quest/ward/3", + "4": "rpg_plus/quest/ward/4" + } + } + ] +} +``` + +`Name` and every step are translation keys. The numbers are the quest's **step**: step 1 shows the text of `1` as current and `0` struck through — "Entry II of V" in the picture. + +## Moving a quest from a scenario + +The elder's answer in RPG Plus starts the quest and puts it on step 1: + +```scenario +action quest.set_status quest_id=woodland_ward status=Progress +action quest.set_data_status quest_id=woodland_ward level=1 +``` + +- `quest.set_status` — the quest's state: `NotStarted`, `Progress` (active) or `End` (completed). +- `quest.set_data_status` — the current step, `level` is its number. +- `quest.add_tag` / `quest.remove_tag` with `tag=…` — remember something that happened, for example which item the player took first. +- `quest.send_notification` — shows the player a notification about the quest; changing a quest does not do this by itself. + +## Checking a quest + +Quest checks work wherever the game takes a condition: `when`, answer conditions, scene conditions and map events. + +```scenario +when "woodland_ward.DataStatus >= 2" -> :lantern +``` + +- `.IsActive` — the quest is in progress; +- `.Status` — `0` not started, `1` in progress, `2` completed; +- `.DataStatus` — the current step; +- `.hasTag("tag")`, `.notHasTag("tag")` — Cthangover uses these to pick which scenario of a scene plays, for example `AwakeningQuest.hasTag("book_taken")`. + +## If something goes wrong + +1. **The quest is not in the journal.** Its state must be `Progress` (or `End` for the Completed tab); setting only the step is not enough. +2. **The journal shows a key instead of text.** Add the step's key to the mod's `locale` files. +3. **A condition is always false.** The quest id is spelled differently from the `Id` in the quest file; the log warns about an unknown quest. diff --git a/docs/es.md b/docs/es.md new file mode 100644 index 0000000..6340bd9 --- /dev/null +++ b/docs/es.md @@ -0,0 +1,81 @@ +# Quests Engine — misiones, sus pasos y el diario + +Quests Engine lleva la cuenta de las tareas del jugador. Una misión tiene un nombre y una lista de pasos numerados; los escenarios la inician, la llevan al paso siguiente, le ponen etiquetas y la completan. El panel **Diario** muestra las misiones que el jugador ha tomado, y el juego guarda su estado. + +Lo usan Cthangover (el despertar del prólogo y la casa vieja) y RPG Plus (las misiones del bosque). + +## El diario + +Se abre con el icono del diario en la barra de herramientas. Mientras el jugador no haya tomado ninguna misión, está vacío: + +![El diario de RPG Plus al empezar: pestañas Activas y Completadas, «No hay misiones» en ambas páginas.](assets/journal-before.jpg) + +En RPG Plus, el anciano del pueblo da la primera misión. Pregúntale dónde buscar: + +![La casa del anciano: el héroe frente al anciano, dos respuestas a la derecha — «¿Puede un lobo apagar faroles?» y «¿Dónde lo encuentro?».](assets/elder-choice.jpg) + +Tras la respuesta, la misión aparece en el diario: + +![El diario tras la charla: «Una luz en el libro de cuentas» en la lista de activas; a la derecha «Entrada II de V», el primer paso tachado y el paso actual «Vence al lobo de la cueva del bosque del este. Encuentra el corazón de ámbar».](assets/journal-after.jpg) + +- **Activas** reúne las misiones en curso y **Completadas** las terminadas. Las misiones aún no empezadas no aparecen nunca. +- La página derecha muestra la misión seleccionada: los pasos hechos van tachados, el paso actual queda marcado y los futuros siguen ocultos, así el diario no adelanta la historia. +- Las etiquetas que la misión ha ganado se muestran como pequeñas placas doradas bajo la entrada. + +## Una definición de misión + +Las misiones son archivos JSON de tipo `quest` en la carpeta `quests/` de un mod. Esta es la misión de las imágenes (de RPG Plus): + +```json +{ + "Kind": "quest", + "Items": [ + { + "Id": "woodland_ward", + "Name": "rpg_plus/quest/ward/name", + "StatusToDescription": { + "0": "rpg_plus/quest/ward/0", + "1": "rpg_plus/quest/ward/1", + "2": "rpg_plus/quest/ward/2", + "3": "rpg_plus/quest/ward/3", + "4": "rpg_plus/quest/ward/4" + } + } + ] +} +``` + +`Name` y cada paso son claves de traducción. Los números son el **paso** de la misión: en el paso 1 se muestra el texto de `1` como actual y el de `0` tachado — «Entrada II de V» en la imagen. + +## Mover una misión desde un escenario + +La respuesta del anciano en RPG Plus inicia la misión y la pone en el paso 1: + +```scenario +action quest.set_status quest_id=woodland_ward status=Progress +action quest.set_data_status quest_id=woodland_ward level=1 +``` + +- `quest.set_status` — el estado de la misión: `NotStarted`, `Progress` (activa) o `End` (completada). +- `quest.set_data_status` — el paso actual; `level` es su número. +- `quest.add_tag` / `quest.remove_tag` con `tag=…` — recordar algo que ocurrió, por ejemplo qué objeto cogió primero el jugador. +- `quest.send_notification` — muestra al jugador un aviso sobre la misión; cambiar una misión no lo hace por sí solo. + +## Comprobar una misión + +Las comprobaciones de misiones funcionan dondequiera que el juego admita una condición: `when`, condiciones de respuesta, condiciones de escena y eventos de mapa. + +```scenario +when "woodland_ward.DataStatus >= 2" -> :lantern +``` + +- `.IsActive` — la misión está en curso; +- `.Status` — `0` no empezada, `1` en curso, `2` completada; +- `.DataStatus` — el paso actual; +- `.hasTag("tag")`, `.notHasTag("tag")` — Cthangover las usa para elegir qué escenario de una escena se reproduce, por ejemplo `AwakeningQuest.hasTag("book_taken")`. + +## Si algo falla + +1. **La misión no está en el diario.** Su estado debe ser `Progress` (o `End` para la pestaña de completadas); fijar solo el paso no basta. +2. **El diario muestra una clave en vez de texto.** Añade la clave del paso a los archivos `locale` del mod. +3. **Una condición siempre es falsa.** El id de la misión está escrito distinto del `Id` del archivo de la misión; el registro avisa de una misión desconocida. diff --git a/docs/ja.md b/docs/ja.md new file mode 100644 index 0000000..3a89eb1 --- /dev/null +++ b/docs/ja.md @@ -0,0 +1,81 @@ +# Quests Engine — クエスト、そのステップ、ジャーナル + +Quests Engine はプレイヤーのタスクを管理します。クエストには名前と番号付きのステップ一覧があり、シナリオがクエストを開始し、次のステップへ進め、タグを付け、完了させます。**ジャーナル**パネルにはプレイヤーが受けたクエストが表示され、その状態はゲームのセーブに保存されます。 + +Cthangover(プロローグの目覚めと古い家)と RPG Plus(森のクエスト)がこれを使っています。 + +## ジャーナル + +ツールバーのジャーナル・アイコンで開きます。プレイヤーがまだクエストを一つも受けていなければ、空です。 + +![RPG Plus の開始時点のジャーナル: 進行中と完了のタブ、どちらのページにも「クエストはありません」。](assets/journal-before.jpg) + +RPG Plus では村の長老が最初のクエストを出します。どこへ探しに行けばいいか尋ねてみましょう。 + +![長老の家: 長老を前にした主人公、右側に二つの選択肢「狼に灯を消せるのか?」と「どこで探せばいい?」。](assets/elder-choice.jpg) + +答えると、クエストがジャーナルに現れます。 + +![会話後のジャーナル: 進行中の一覧に「台帳に載った灯り」。右側は「項目 II / V」で、最初のステップは打ち消し線、現在のステップは「東の森の洞窟のそばの狼を倒し、琥珀の心臓を見つけよう」。](assets/journal-after.jpg) + +- **進行中**には進行中のクエスト、**完了**には終わったクエストが並びます。まだ始めていないクエストは決して表示されません。 +- 右のページには選んだクエストが出ます。済んだステップには打ち消し線、現在のステップには印が付き、先のステップは隠れたまま。ジャーナルが物語を先にばらすことはありません。 +- クエストが獲得したタグは、項目の下に小さな金色の札として表示されます。 + +## クエストの定義 + +クエストは、mod の `quests/` フォルダーに入る kind `quest` の JSON ファイルです。こちらは画像のクエスト(RPG Plus のもの)です。 + +```json +{ + "Kind": "quest", + "Items": [ + { + "Id": "woodland_ward", + "Name": "rpg_plus/quest/ward/name", + "StatusToDescription": { + "0": "rpg_plus/quest/ward/0", + "1": "rpg_plus/quest/ward/1", + "2": "rpg_plus/quest/ward/2", + "3": "rpg_plus/quest/ward/3", + "4": "rpg_plus/quest/ward/4" + } + } + ] +} +``` + +`Name` と各ステップは翻訳キーです。番号がクエストの**ステップ**になります。ステップ 1 では `1` のテキストが現在のステップとして表示され、`0` には打ち消し線が付きます。画像でいう「項目 II / V」です。 + +## シナリオからクエストを進める + +RPG Plus で長老の答えがクエストを開始し、ステップ 1 に置きます。 + +```scenario +action quest.set_status quest_id=woodland_ward status=Progress +action quest.set_data_status quest_id=woodland_ward level=1 +``` + +- `quest.set_status` — クエストの状態。`NotStarted`、`Progress`(進行中)、`End`(完了)。 +- `quest.set_data_status` — 現在のステップ。`level` がその番号です。 +- `quest.add_tag` / `quest.remove_tag` と `tag=…` — 起こったことを記録します。たとえばプレイヤーがどのアイテムを先に取ったか。 +- `quest.send_notification` — クエストについての通知をプレイヤーに表示します。クエストを変えただけでは通知は出ません。 + +## クエストの確認 + +クエストの判定は、ゲームが条件を受け付ける場所ならどこでも機能します。`when`、選択肢の条件、シーンの条件、マップイベントです。 + +```scenario +when "woodland_ward.DataStatus >= 2" -> :lantern +``` + +- `.IsActive` — クエストが進行中。 +- `.Status` — `0` 未開始、`1` 進行中、`2` 完了。 +- `.DataStatus` — 現在のステップ。 +- `.hasTag("tag")`、`.notHasTag("tag")` — Cthangover はこれでシーンのどのシナリオを再生するか決めます。例は `AwakeningQuest.hasTag("book_taken")`。 + +## うまく動かないとき + +1. **クエストがジャーナルに出ない。** 状態が `Progress`(完了タブに出すなら `End`)である必要があります。ステップだけ設定しても足りません。 +2. **ジャーナルがテキストではなくキーを表示する。** ステップのキーを mod の `locale` ファイルに追加してください。 +3. **条件が常に偽になる。** クエスト id のつづりがクエストファイルの `Id` と違います。ログには未知のクエストの警告が出ます。 diff --git a/docs/ko.md b/docs/ko.md new file mode 100644 index 0000000..c515cc1 --- /dev/null +++ b/docs/ko.md @@ -0,0 +1,81 @@ +# Quests Engine — 퀘스트, 단계, 그리고 저널 + +Quests Engine은 플레이어의 과제를 관리합니다. 퀘스트는 이름과 번호가 붙은 단계 목록을 가지며, 시나리오가 퀘스트를 시작하고 다음 단계로 진행하고 태그를 달고 완료합니다. **저널** 패널은 플레이어가 수락한 퀘스트를 보여 주고, 게임은 그 상태를 저장합니다. + +Cthangover(프롤로그의 각성과 낡은 집)와 RPG Plus(숲의 퀘스트)가 이를 사용합니다. + +## 저널 + +툴바의 저널 아이콘으로 엽니다. 플레이어가 아직 퀘스트를 하나도 수락하지 않았다면 비어 있습니다. + +![RPG Plus 시작 시점의 저널: 진행 중과 완료 탭, 두 페이지 모두 "퀘스트가 없습니다".](assets/journal-before.jpg) + +RPG Plus에서는 마을 원로가 첫 퀘스트를 줍니다. 어디를 찾아야 하는지 물어 보세요. + +![원로의 집: 원로 앞에 선 주인공, 오른쪽의 두 선택지 "늑대가 등불을 끌 수 있나요?"와 "어디서 찾죠?".](assets/elder-choice.jpg) + +답을 고르면 퀘스트가 저널에 나타납니다. + +![대화 후의 저널: 진행 중 목록의 "장부에 오른 등불"; 오른쪽은 "항목 II / V", 첫 단계는 취소선, 현재 단계는 "동쪽 숲 동굴의 늑대를 물리치고, 호박 심장을 찾으세요".](assets/journal-after.jpg) + +- **진행 중**에는 진행 중인 퀘스트가, **완료**에는 끝난 퀘스트가 들어갑니다. 아직 시작하지 않은 퀘스트는 결코 나타나지 않습니다. +- 오른쪽 페이지는 선택한 퀘스트를 보여 줍니다. 끝낸 단계에는 취소선이, 현재 단계에는 표시가 붙고, 이후 단계는 감춰져 있어 저널이 이야기를 미리 까발리지 않습니다. +- 퀘스트가 얻은 태그는 항목 아래에 작은 금색 꼬리표로 표시됩니다. + +## 퀘스트 정의 + +퀘스트는 mod의 `quests/` 폴더에 있는 kind `quest` JSON 파일입니다. 사진 속 퀘스트(RPG Plus 것)입니다. + +```json +{ + "Kind": "quest", + "Items": [ + { + "Id": "woodland_ward", + "Name": "rpg_plus/quest/ward/name", + "StatusToDescription": { + "0": "rpg_plus/quest/ward/0", + "1": "rpg_plus/quest/ward/1", + "2": "rpg_plus/quest/ward/2", + "3": "rpg_plus/quest/ward/3", + "4": "rpg_plus/quest/ward/4" + } + } + ] +} +``` + +`Name`과 각 단계는 번역 키입니다. 숫자가 퀘스트의 **단계**입니다. 단계 1에서는 `1`의 텍스트가 현재 단계로 표시되고 `0`에는 취소선이 그려집니다. 사진으로 말하면 "항목 II / V"입니다. + +## 시나리오에서 퀘스트 진행하기 + +RPG Plus에서 원로의 대답이 퀘스트를 시작하고 단계 1에 놓습니다. + +```scenario +action quest.set_status quest_id=woodland_ward status=Progress +action quest.set_data_status quest_id=woodland_ward level=1 +``` + +- `quest.set_status` — 퀘스트의 상태: `NotStarted`, `Progress`(진행 중) 또는 `End`(완료). +- `quest.set_data_status` — 현재 단계, `level`이 그 번호입니다. +- `quest.add_tag` / `quest.remove_tag`와 `tag=…` — 일어난 일을 기억합니다. 예를 들어 플레이어가 어떤 아이템을 먼저 가져갔는지. +- `quest.send_notification` — 퀘스트에 대한 알림을 플레이어에게 보여 줍니다. 퀘스트를 바꾸는 것만으로는 알림이 뜨지 않습니다. + +## 퀘스트 확인하기 + +퀘스트 판정은 게임이 조건을 받아들이는 곳이라면 어디서든 작동합니다. `when`, 선택지 조건, 장면 조건, 맵 이벤트입니다. + +```scenario +when "woodland_ward.DataStatus >= 2" -> :lantern +``` + +- `.IsActive` — 퀘스트가 진행 중. +- `.Status` — `0` 시작 안 함, `1` 진행 중, `2` 완료. +- `.DataStatus` — 현재 단계. +- `.hasTag("tag")`, `.notHasTag("tag")` — Cthangover는 이것으로 장면의 어떤 시나리오를 재생할지 고릅니다. 예: `AwakeningQuest.hasTag("book_taken")`. + +## 문제가 생겼을 때 + +1. **퀘스트가 저널에 없습니다.** 상태가 `Progress`(완료 탭이라면 `End`)여야 합니다. 단계만 설정해서는 부족합니다. +2. **저널이 텍스트 대신 키를 보여 줍니다.** 단계의 키를 mod의 `locale` 파일에 추가하세요. +3. **조건이 항상 거짓입니다.** 퀘스트 id의 철자가 퀘스트 파일의 `Id`와 다릅니다. 로그에 알 수 없는 퀘스트 경고가 기록됩니다. diff --git a/docs/ru.md b/docs/ru.md new file mode 100644 index 0000000..f1659dd --- /dev/null +++ b/docs/ru.md @@ -0,0 +1,81 @@ +# Quests Engine — задания, их шаги и журнал + +Quests Engine ведёт счёт задачам игрока. У задания есть название и нумерованный список шагов; сценарии берут его в работу, переводят на следующий шаг, отмечают тегами и завершают. Панель **Журнал** показывает задания, которые взял игрок, а их состояние игра сохраняет. + +Его используют Cthangover (пробуждение в прологе и старый дом) и RPG Plus (лесные задания). + +## Журнал + +Открывается иконкой журнала на панели инструментов. Пока игрок не взял ни одного задания, журнал пуст: + +![Журнал в RPG Plus на старте: вкладки «Активные» и «Завершённые», на обеих страницах «Заданий нет».](assets/journal-before.jpg) + +В RPG Plus первое задание даёт староста деревни. Спросите его, куда идти: + +![Дом старосты: герой перед старостой, справа два варианта — «Волк умеет гасить фонари?» и «Где его искать?».](assets/elder-choice.jpg) + +После ответа задание появляется в журнале: + +![Журнал после разговора: «Свет по ведомости» в списке активных; справа «Запись II из V», первый шаг зачёркнут, текущий шаг — «Прогони волка у пещеры на востоке леса. Найди янтарное сердце».](assets/journal-after.jpg) + +- **Активные** — список заданий в работе, **Завершённые** — законченных. Ещё не начатые задания не появляются никогда. +- Правая страница показывает выбранное задание: выполненные шаги зачёркнуты, текущий отмечен, а будущие скрыты — журнал не раскрывает сюжет заранее. +- Заработанные заданием теги показаны под записью маленькими золотыми метками. + +## Описание задания + +Задания — это JSON-файлы вида `quest` в папке `quests/` мода. Вот задание с картинок (из RPG Plus): + +```json +{ + "Kind": "quest", + "Items": [ + { + "Id": "woodland_ward", + "Name": "rpg_plus/quest/ward/name", + "StatusToDescription": { + "0": "rpg_plus/quest/ward/0", + "1": "rpg_plus/quest/ward/1", + "2": "rpg_plus/quest/ward/2", + "3": "rpg_plus/quest/ward/3", + "4": "rpg_plus/quest/ward/4" + } + } + ] +} +``` + +`Name` и каждый шаг — ключи перевода. Числа — это **шаги** задания: на шаге 1 текст `1` показан как текущий, а `0` — зачёркнутым; на картинке это «Запись II из V». + +## Как сценарий двигает задание + +Ответ старосты в RPG Plus запускает задание и ставит его на шаг 1: + +```scenario +action quest.set_status quest_id=woodland_ward status=Progress +action quest.set_data_status quest_id=woodland_ward level=1 +``` + +- `quest.set_status` — состояние задания: `NotStarted`, `Progress` (активно) или `End` (завершено). +- `quest.set_data_status` — текущий шаг, `level` — его номер. +- `quest.add_tag` / `quest.remove_tag` с `tag=…` — запомнить случившееся, например, какой предмет игрок взял первым. +- `quest.send_notification` — показывает игроку уведомление о задании; само по себе изменение задания уведомления не даёт. + +## Как проверить задание + +Проверки задания работают везде, где игра принимает условие: в `when`, в условиях ответов, условиях сцен и событиях карты. + +```scenario +when "woodland_ward.DataStatus >= 2" -> :lantern +``` + +- `.IsActive` — задание в работе; +- `.Status` — `0` не начато, `1` в работе, `2` завершено; +- `.DataStatus` — текущий шаг; +- `.hasTag("tag")`, `.notHasTag("tag")` — так Cthangover выбирает, какой сценарий сцены играть, например `AwakeningQuest.hasTag("book_taken")`. + +## Если что-то пошло не так + +1. **Задания нет в журнале.** Его состояние должно быть `Progress` (или `End` для вкладки завершённых); одной установки шага мало. +2. **Журнал показывает ключ вместо текста.** Добавьте ключ шага в файлы `locale` мода. +3. **Условие всегда ложно.** Идентификатор задания написан иначе, чем `Id` в файле задания; в логе будет предупреждение о неизвестном задании. diff --git a/docs/vi.md b/docs/vi.md new file mode 100644 index 0000000..98862bb --- /dev/null +++ b/docs/vi.md @@ -0,0 +1,81 @@ +# Quests Engine — nhiệm vụ, các bước và nhật ký + +Quests Engine quản lý các việc người chơi phải làm. Một nhiệm vụ có tên và danh sách các bước được đánh số; kịch bản khởi đầu nhiệm vụ, đưa nó sang bước tiếp, gắn thẻ và kết thúc nó. Bảng **Nhật ký** hiển thị những nhiệm vụ người chơi đã nhận, và game lưu trạng thái của chúng. + +Cthangover (tỉnh dậy trong prologue và ngôi nhà cũ) và RPG Plus (các nhiệm vụ trong rừng) đều dùng mod này. + +## Nhật ký + +Mở bằng biểu tượng nhật ký trên thanh công cụ. Khi người chơi chưa nhận nhiệm vụ nào, nhật ký còn trống: + +![Nhật ký của RPG Plus lúc đầu: hai thẻ Đang làm và Đã xong, cả hai trang đều ghi "Chưa có nhiệm vụ".](assets/journal-before.jpg) + +Trong RPG Plus, trưởng làng giao nhiệm vụ đầu tiên. Hỏi ông xem nên đi tìm ở đâu: + +![Nhà trưởng làng: anh hùng đứng trước trưởng làng, hai lựa chọn bên phải — "Sói tắt được đèn sao?" và "Tìm nó ở đâu?".](assets/elder-choice.jpg) + +Sau câu trả lời, nhiệm vụ xuất hiện trong nhật ký: + +![Nhật ký sau cuộc trò chuyện: "Ngọn đèn trên sổ sách" nằm trong danh sách đang làm; bên phải là "Mục II trên V", bước đầu đã bị gạch, bước hiện tại là "Đánh bại con sói bên hang trong rừng phía đông. Tìm trái tim hổ phách".](assets/journal-after.jpg) + +- **Đang làm** liệt kê nhiệm vụ đang tiến hành, **Đã xong** liệt kê nhiệm vụ hoàn thành. Nhiệm vụ chưa bắt đầu không bao giờ hiện ra. +- Trang bên phải hiển thị nhiệm vụ đang chọn: các bước đã làm bị gạch ngang, bước hiện tại được đánh dấu, các bước sau còn ẩn — nhật ký không tiết lộ trước câu chuyện. +- Các thẻ nhiệm vụ đã giành được hiện dưới mục nhỏ, dạng nhãn vàng nhỏ. + +## Định nghĩa nhiệm vụ + +Nhiệm vụ là tệp JSON kind `quest` trong thư mục `quests/` của mod. Đây là nhiệm vụ trong các hình trên (thuộc RPG Plus): + +```json +{ + "Kind": "quest", + "Items": [ + { + "Id": "woodland_ward", + "Name": "rpg_plus/quest/ward/name", + "StatusToDescription": { + "0": "rpg_plus/quest/ward/0", + "1": "rpg_plus/quest/ward/1", + "2": "rpg_plus/quest/ward/2", + "3": "rpg_plus/quest/ward/3", + "4": "rpg_plus/quest/ward/4" + } + } + ] +} +``` + +`Name` và từng bước đều là khóa dịch. Các con số chính là **bước** của nhiệm vụ: ở bước 1, văn bản của `1` hiện là bước hiện tại và `0` bị gạch ngang — tức "Mục II trên V" trong hình. + +## Đưa nhiệm vụ đi từ kịch bản + +Câu trả lời của trưởng làng trong RPG Plus khởi đầu nhiệm vụ và đặt nó ở bước 1: + +```scenario +action quest.set_status quest_id=woodland_ward status=Progress +action quest.set_data_status quest_id=woodland_ward level=1 +``` + +- `quest.set_status` — trạng thái nhiệm vụ: `NotStarted`, `Progress` (đang làm) hoặc `End` (hoàn thành). +- `quest.set_data_status` — bước hiện tại, `level` là số của nó. +- `quest.add_tag` / `quest.remove_tag` kèm `tag=…` — ghi nhớ chuyện đã xảy ra, chẳng hạn người chơi lấy vật phẩm nào trước. +- `quest.send_notification` — hiện thông báo về nhiệm vụ cho người chơi; thay đổi nhiệm vụ thì tự nó không thông báo. + +## Kiểm tra nhiệm vụ + +Phép kiểm nhiệm vụ dùng được ở mọi nơi game nhận điều kiện: `when`, điều kiện lựa chọn, điều kiện cảnh và sự kiện bản đồ. + +```scenario +when "woodland_ward.DataStatus >= 2" -> :lantern +``` + +- `.IsActive` — nhiệm vụ đang tiến hành; +- `.Status` — `0` chưa bắt đầu, `1` đang làm, `2` đã hoàn thành; +- `.DataStatus` — bước hiện tại; +- `.hasTag("tag")`, `.notHasTag("tag")` — Cthangover dùng chúng để chọn kịch bản nào của cảnh sẽ chạy, ví dụ `AwakeningQuest.hasTag("book_taken")`. + +## Khi có trục trặc + +1. **Nhiệm vụ không có trong nhật ký.** Trạng thái của nó phải là `Progress` (hoặc `End` để vào thẻ đã xong); chỉ đặt bước là chưa đủ. +2. **Nhật ký hiện khóa thay vì văn bản.** Thêm khóa của bước vào các tệp `locale` của mod. +3. **Điều kiện luôn sai.** Id nhiệm vụ viết khác với `Id` trong tệp nhiệm vụ; log sẽ cảnh báo về nhiệm vụ lạ. diff --git a/docs/zh.md b/docs/zh.md new file mode 100644 index 0000000..14c2afe --- /dev/null +++ b/docs/zh.md @@ -0,0 +1,81 @@ +# Quests Engine — 任务、任务步骤与日志 + +Quests Engine 替玩家记账。每个任务都有名称和编号的步骤列表;剧本负责开启任务、推进到下一步、打上标记并完成任务。**日志**面板显示玩家已领取的任务,游戏会保存它们的状态。 + +Cthangover(序章的苏醒和旧宅)与 RPG Plus(森林任务)都用到了它。 + +## 日志 + +用工具栏上的日志图标打开。玩家还没领取任何任务时,日志是空的: + +![RPG Plus 开局时的日志:「进行中」和「已完成」两个页签,两页都写着「暂无任务」。](assets/journal-before.jpg) + +在 RPG Plus 里,村庄的长老给出第一个任务。向他问问去哪里找: + +![长老的家:主角站在长老面前,右侧有两个选项——「狼会熄灯吗?」和「去哪儿找它?」。](assets/elder-choice.jpg) + +回答之后,任务就出现在日志里: + +![对话后的日志:「账簿上的一盏灯」出现在进行中列表;右侧是「第 II 条,共 V 条」,第一步已划掉,当前步骤为「击退东部森林洞窟旁的狼。找到琥珀之心」。](assets/journal-after.jpg) + +- **进行中**列出正在做的任务,**已完成**列出做完的。还没开始的任务永远不会出现。 +- 右页显示选中的任务:已完成的步骤划掉,当前步骤做了标记,后续步骤保持隐藏——日志不会剧透后面的故事。 +- 任务获得的标记会以小小的金色标签显示在条目下方。 + +## 任务的定义 + +任务是 mod 的 `quests/` 文件夹里类型为 `quest` 的 JSON 文件。这就是截图中的任务(来自 RPG Plus): + +```json +{ + "Kind": "quest", + "Items": [ + { + "Id": "woodland_ward", + "Name": "rpg_plus/quest/ward/name", + "StatusToDescription": { + "0": "rpg_plus/quest/ward/0", + "1": "rpg_plus/quest/ward/1", + "2": "rpg_plus/quest/ward/2", + "3": "rpg_plus/quest/ward/3", + "4": "rpg_plus/quest/ward/4" + } + } + ] +} +``` + +`Name` 和每个步骤都是翻译键。数字就是任务的**步骤**:在第 1 步时,`1` 的文本显示为当前步骤,`0` 则划掉——即截图中的「第 II 条,共 V 条」。 + +## 从剧本推进任务 + +RPG Plus 中长老的回答会开启任务并把它放到第 1 步: + +```scenario +action quest.set_status quest_id=woodland_ward status=Progress +action quest.set_data_status quest_id=woodland_ward level=1 +``` + +- `quest.set_status` — 任务的状态:`NotStarted`、`Progress`(进行中)或 `End`(已完成)。 +- `quest.set_data_status` — 当前步骤,`level` 是它的编号。 +- `quest.add_tag` / `quest.remove_tag` 配合 `tag=…` — 记下发生过的事,比如玩家先拿了哪个物品。 +- `quest.send_notification` — 向玩家弹出任务通知;改变任务本身不会触发通知。 + +## 检查任务 + +凡是游戏接受条件的地方都能用任务检查:`when`、选项条件、场景条件和地图事件。 + +```scenario +when "woodland_ward.DataStatus >= 2" -> :lantern +``` + +- `.IsActive` — 任务正在进行; +- `.Status` — `0` 未开始,`1` 进行中,`2` 已完成; +- `.DataStatus` — 当前步骤; +- `.hasTag("tag")`、`.notHasTag("tag")` — Cthangover 用它们决定场景播放哪段剧本,例如 `AwakeningQuest.hasTag("book_taken")`。 + +## 出问题时 + +1. **任务不在日志里。** 它的状态必须是 `Progress`(或在「已完成」页签显示则用 `End`);只设置步骤是不够的。 +2. **日志显示的是键而不是文本。** 把步骤的键加进 mod 的 `locale` 文件。 +3. **条件永远为假。** 写的任务 id 与任务文件里的 `Id` 不一致;日志会警告存在未知任务。 diff --git a/locale/en.properties b/locale/en.properties index 7b03299..4823f34 100644 --- a/locale/en.properties +++ b/locale/en.properties @@ -1,4 +1,4 @@ mod_quests_base_name = Quests Engine -mod_quests_base_desc = Engine quests subsystem: the quest factory and runtime state, the IQuestService implementation, quest scenario actions, quest scene conditions and the quest journal UI. +mod_quests_base_desc = Quests engine: quests with numbered steps that scenarios start, advance and finish, and the journal panel that shows them. ui/journal/new = New journal entry ui/journal/updated = Quest updated diff --git a/locale/es.properties b/locale/es.properties index 43b1f33..aed7f4c 100644 --- a/locale/es.properties +++ b/locale/es.properties @@ -1,4 +1,4 @@ mod_quests_base_name = Motor de misiones -mod_quests_base_desc = Subsistema de misiones del motor: la fábrica de misiones y su estado en ejecución, la implementación de IQuestService, acciones de escenario de misiones, condiciones de escena de misiones y la interfaz del diario. +mod_quests_base_desc = Motor de misiones: misiones con pasos numerados que los escenarios inician, avanzan y completan, y el panel del diario que las muestra. ui/journal/new = Nueva entrada en el diario ui/journal/updated = Misión actualizada diff --git a/locale/ja.properties b/locale/ja.properties index 06b7606..f909a29 100644 --- a/locale/ja.properties +++ b/locale/ja.properties @@ -1,4 +1,4 @@ mod_quests_base_name = クエストエンジン -mod_quests_base_desc = エンジンのクエストサブシステム:クエストファクトリーと実行時の状態、IQuestService の実装、クエストのシナリオアクション、クエストのシーン条件、クエスト日誌の UI。 +mod_quests_base_desc = クエストエンジン: シナリオが開始・進行・完了させる番号付きステップのクエストと、それらを表示するジャーナルパネル。 ui/journal/new = 日誌に新しい記録 ui/journal/updated = クエストが更新されました diff --git a/locale/ko.properties b/locale/ko.properties index 2d9dc13..9bb9297 100644 --- a/locale/ko.properties +++ b/locale/ko.properties @@ -1,4 +1,4 @@ mod_quests_base_name = 퀘스트 엔진 -mod_quests_base_desc = 엔진 퀘스트 하위 시스템: 퀘스트 팩토리와 실행 상태, IQuestService 구현, 퀘스트 시나리오 액션, 퀘스트 장면 조건, 퀘스트 일지 UI. +mod_quests_base_desc = 퀘스트 엔진: 시나리오가 시작하고 진행하고 완료하는 번호 붙은 단계의 퀘스트와 이를 보여 주는 저널 패널. ui/journal/new = 새 일지 항목 ui/journal/updated = 퀘스트 갱신됨 diff --git a/locale/ru.properties b/locale/ru.properties index 9fcd6fe..b8b7174 100644 --- a/locale/ru.properties +++ b/locale/ru.properties @@ -1,4 +1,4 @@ mod_quests_base_name = Движок квестов -mod_quests_base_desc = Подсистема квестов движка: фабрика квестов и их состояние, реализация IQuestService, сценарные действия, условия квестов в сценах и журнал квестов. +mod_quests_base_desc = Движок заданий: задания с пронумерованными шагами, которые сценарии запускают, ведут дальше и завершают, и панель журнала, где они видны. ui/journal/new = Новая запись в журнале ui/journal/updated = Задание обновлено diff --git a/locale/vi.properties b/locale/vi.properties index f48b9a4..f9e92dd 100644 --- a/locale/vi.properties +++ b/locale/vi.properties @@ -1,4 +1,4 @@ mod_quests_base_name = Engine nhiệm vụ -mod_quests_base_desc = Hệ thống con nhiệm vụ của engine: factory nhiệm vụ và trạng thái khi chạy, triển khai IQuestService, hành động kịch bản nhiệm vụ, điều kiện cảnh nhiệm vụ và giao diện nhật ký nhiệm vụ. +mod_quests_base_desc = Engine nhiệm vụ: các nhiệm vụ có bước đánh số mà kịch bản khởi đầu, đưa tiến và kết thúc, cùng bảng nhật ký hiển thị chúng. ui/journal/new = Mục nhật ký mới ui/journal/updated = Nhiệm vụ đã cập nhật diff --git a/locale/zh.properties b/locale/zh.properties index e1f5006..42c68d2 100644 --- a/locale/zh.properties +++ b/locale/zh.properties @@ -1,4 +1,4 @@ mod_quests_base_name = 任务引擎 -mod_quests_base_desc = 引擎任务子系统:任务工厂和运行时状态、IQuestService 实现、任务剧本动作、任务场景条件以及任务日志界面。 +mod_quests_base_desc = 任务引擎:由剧本开启、推进并完成的分步任务,以及展示它们的日志面板。 ui/journal/new = 新的日志条目 ui/journal/updated = 任务已更新 diff --git a/manifest.json b/manifest.json index 8d071be..6b45335 100644 --- a/manifest.json +++ b/manifest.json @@ -3,7 +3,7 @@ "name": "Quests Engine", "version": "1.0.0", "author": "ct", - "description": "Engine quests subsystem: the quest factory and runtime state (QuestFactory, QuestBase/QuestData), the IQuestService implementation, quest scenario actions, quest scene conditions with the QuestParser leaf parser and the quest journal UI. Replaces the former Core/Quests state, Core/Actions quest services and actions, Core/Scenes quest conditions and Core/UI/Quests - QuestsModInitializer publishes the kernel contract (IQuestService via QuestServiceRegistry), registers the quest leaf parser and the new-game resettable; QuestsSaveable persists quest state through the generic mod save slot.", + "description": "Quests engine: quests with numbered steps that scenarios start, advance and finish, and the journal panel that shows them.", "category": "engine, library", "sources": [ "src/**/*.cs"