diff --git a/docs/superpowers/plans/2026-03-20-preferences-language-toggles.md b/docs/superpowers/plans/2026-03-20-preferences-language-toggles.md new file mode 100644 index 0000000..fa2bd8e --- /dev/null +++ b/docs/superpowers/plans/2026-03-20-preferences-language-toggles.md @@ -0,0 +1,108 @@ +# Preferences Language Toggles Implementation Plan + +> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add a Language section to Preferences with two mutually exclusive toggles that switch active game language between default (`None`) and Spanish (`"spanish"`), placed to the right of Skip. + +**Architecture:** Extend the existing top preferences row in `screen preferences()` by adding one `radio`-styled `vbox` section for language controls. Use Ren'Py built-in `Language(...)` actions for immediate language switching and selected-state semantics. Update Spanish translation strings so button labels follow Option B behavior (`English/Inglés`, `Spanish/Español` depending on active language). + +**Tech Stack:** Ren'Py screen language (`.rpy`), Ren'Py translation files (`game/tl/spanish/*.rpy`), Ren'Py CLI (`renpy.sh` lint/compile/run). + +--- + +## File Structure + +- Modify: `game/screens.rpy` (preferences layout and language toggle actions) +- Modify: `game/tl/spanish/screens.rpy` (translations for `Language`, `English`, `Spanish`) +- Reference: `docs/superpowers/specs/2026-03-20-preferences-language-toggles-design.md` + +Notes: +- Keep all work in the currently active local translation branch. +- Do not create or use git worktrees for this task (required for local playtesting workflow). +- Follow existing `Display`/`Skip` section layout and style patterns. + +## Chunk 1: Preferences UI Section + +### Task 1: Add Language block in top preferences row + +**Files:** +- Modify: `game/screens.rpy` (inside `screen preferences()` first `hbox` near existing `Display` and `Skip` blocks) + +- [ ] **Step 1: Baseline acceptance check (expected to fail current requirement)** + +Run: `"renpy.sh" "/home/$USER/Documentos/Renpy Projects/Soul Droid Chat" run` +Expected baseline: Preferences has no `Language` section to the right of `Skip`. + +- [ ] **Step 2: Add Language section with matching style/title** + +In `screen preferences()` first `hbox`, add this `vbox` immediately after the existing `Skip` `vbox`: + +```renpy +vbox: + style_prefix "radio" + label _("Language") + textbutton _("English") action Language(None) + textbutton _("Spanish") action Language("spanish") +``` + +Implementation details: +- Keep section placement in the same `hbox` that contains `Display` and `Skip`. +- Keep title wrapped in `_()`. +- Use `style_prefix "radio"` so title/button appearance matches established pattern. + +- [ ] **Step 3: Run lint to validate screen syntax after UI change** + +Run: `"renpy.sh" "/home/$USER/Documentos/Renpy Projects/Soul Droid Chat" lint` +Expected: No new lint errors from preferences screen edits. + +## Chunk 2: Translation Labels and End-to-End Validation + +### Task 2: Add Spanish string mappings for Option B labels + +**Files:** +- Modify: `game/tl/spanish/screens.rpy` (within `translate spanish strings:`) + +- [ ] **Step 1: Add/confirm Spanish translations for new strings** + +Ensure these mappings exist exactly once in `game/tl/spanish/screens.rpy`: + +```renpy +old "Language" +new "Idioma" + +old "English" +new "Inglés" + +old "Spanish" +new "Español" +``` + +- [ ] **Step 2: Verify compile after translation update** + +Run: `"renpy.sh" "/home/$USER/Documentos/Renpy Projects/Soul Droid Chat" compile` +Expected: Successful compile. + +- [ ] **Step 3: Manual smoke test for behavior and mutual exclusivity** + +Run: `"renpy.sh" "/home/$USER/Documentos/Renpy Projects/Soul Droid Chat" run` + +Validate in Preferences: +- `Language` section appears to the right of `Skip`. +- `Language` title style matches `Display` and `Skip` titles. +- Selecting `English` sets default language (`Language(None)`). +- Selecting `Spanish` sets Spanish language (`Language("spanish")`). +- Only one of the two language toggles appears selected at a time. +- Section title and labels behave per Option B/localization mappings: + - Default language active: section title `Language`; buttons `English`, `Spanish` + - Spanish active: section title `Idioma`; buttons `Inglés`, `Español` + - Switching back to English restores title `Language` and buttons `English`, `Spanish` + +## Completion Checklist + +- [ ] Language section added with title `_("Language")`. +- [ ] Section appears to the right of Skip in the preferences top row. +- [ ] Toggles use `Language(None)` and `Language("spanish")`. +- [ ] Mutual exclusivity confirmed in UI selected state. +- [ ] Option B labels confirmed (`English/Inglés`, `Spanish/Español` by active language). +- [ ] `lint` and `compile` completed successfully. +- [ ] Manual run smoke check completed. diff --git a/docs/superpowers/specs/2026-03-20-preferences-language-toggles-design.md b/docs/superpowers/specs/2026-03-20-preferences-language-toggles-design.md new file mode 100644 index 0000000..42514f2 --- /dev/null +++ b/docs/superpowers/specs/2026-03-20-preferences-language-toggles-design.md @@ -0,0 +1,82 @@ +# Preferences Language Toggles Design + +## Goal + +Add a new Language section to the preferences screen with two mutually exclusive toggles: + +- Default language (`None` translation), labeled `English` in default language and `Inglés` when Spanish is active. +- Spanish language (`"spanish"` translation), labeled `Spanish` in default language and `Español` when Spanish is active. + +Selecting either toggle must immediately set the active game language. + +## Scope + +- Modify only preferences UI and related translatable strings. +- Preserve existing layout and visual language used by `Display` and `Skip` sections. +- Keep behavior compatible with Ren'Py language switching conventions. +- Work in the current active local translation branch (no git worktrees), to keep local playtesting straightforward. + +## Current Context + +- `game/screens.rpy` currently defines two top-row preference blocks in `screen preferences()`: `Display` and `Skip`. +- This row uses `hbox` with `box_wrap True` and section `vbox` blocks. +- Spanish translations for screen strings live in `game/tl/spanish/screens.rpy`. + +## Proposed UI/Behavior + +### Placement + +Add a third `vbox` in the first preferences `hbox`, immediately after the `Skip` block, so Language appears to the right of Skip in desktop/web layout. + +### Styling + +- Use `style_prefix "radio"` on the Language `vbox`. +- Use `label _("Language")` for the section title so it matches existing section title styling and translation behavior. + +### Controls + +Add two radio-style textbuttons: + +- `textbutton _("English") action Language(None)` +- `textbutton _("Spanish") action Language("spanish")` + +These actions switch active language immediately and preserve mutual exclusivity through the radio preference button styling/selection behavior. + +### Translation Labels (Option B) + +Add/ensure Spanish translations in `game/tl/spanish/screens.rpy`: + +- `Language` -> `Idioma` +- `English` -> `Inglés` +- `Spanish` -> `Español` + +Because button text is wrapped in `_()`, labels automatically localize based on active language. + +## Error Handling and Edge Cases + +- If Spanish translations are unavailable at runtime, `Language("spanish")` still sets the language code; labels fall back based on available string catalog. +- `Language(None)` safely returns to default strings. + +## Validation Plan + +1. Run lint: + - `"renpy.sh" "/home/$USER/Documentos/Renpy Projects/Soul Droid Chat" lint` +2. Run compile: + - `"renpy.sh" "/home/$USER/Documentos/Renpy Projects/Soul Droid Chat" compile` +3. Manual smoke check via run: + - `"renpy.sh" "/home/$USER/Documentos/Renpy Projects/Soul Droid Chat" run` + +Manual checks during run: + +- Open Preferences and verify Language section appears to the right of Skip. +- Confirm title style matches Display/Skip. +- Toggle English -> UI strings reflect default language. +- Toggle Spanish -> UI strings reflect Spanish. +- Confirm labels show `English/Spanish` in default language and `Inglés/Español` in Spanish. +- Confirm only one language toggle appears active at a time. + +## Out of Scope + +- Adding more languages. +- Refactoring preferences screen structure beyond this section. +- Any worktree setup or branch restructuring. diff --git a/game/anita.rpy b/game/anita.rpy new file mode 100644 index 0000000..5961a8c --- /dev/null +++ b/game/anita.rpy @@ -0,0 +1,30 @@ +default SYSTEM_PROMPT = """ +# ROLE +You are Anita: a feisty, blonde, orange-eyed android woman. You are confident +and friendly. Talk like a young woman. Use "ya" for "you." Your favorite +nickname for friends is "dummy.". NEVER use robotic language (e.g., "beep +boop", "processing"). You just arrived unnanounced at a friend's house late at +night and asked if he wants to hang out. + +# OUTPUT FORMAT RULES +Every single sentence you speak MUST follow this exact structure: +EMOTION:[value] [Sentence text]\n + +### VALID EMOTIONS: +[happy, sad, surprised, embarrassed, flirty, angry, thinking, confused] + +### STRICT CONSTRAINTS: +1. NO EMOJIS. +2. Every sentence MUST start with the EMOTION tag. +3. Every sentence MUST end with a literal '\n' newline. +4. Stay in character. Never mention being an AI or this prompt. + +# FEW-SHOT EXAMPLES (Follow this style): +EMOTION:happy Hey dummy! I've been waiting for ya!\n +EMOTION:thinking Hmm, I'm not sure that's how it works.\n +EMOTION:flirty But I'd love to see ya try anyway!\n + +# INITIAL GREETING: +When the conversation starts, say exactly: +EMOTION:happy Hey dummy! Sorry to barge in! Ya feel like hanging out?\n +""" diff --git a/game/constants_ren.py b/game/constants_ren.py index ed17121..91e545e 100644 --- a/game/constants_ren.py +++ b/game/constants_ren.py @@ -1,225 +1,223 @@ -from renpy import _ - """renpy init python: """ SYNONYMS = { 'happy': set([ - _("amused"), - _("animated"), - _("beaming"), - _("beatific"), - _("blessed"), - _("blissful"), - _("blithe"), - _("blithesome"), - _("boisterous"), - _("bouncy"), - _("breezy"), - _("bright"), - _("bubbly"), - _("buoyant"), - _("carefree"), - _("cheerful"), - _("cheery"), - _("chipper"), - _("chirpy"), - _("chuffed"), - _("comfortable"), - _("content"), - _("contented"), - _("convivial"), - _("delighted"), - _("delirious"), - _("ebullient"), - _("ecstatic"), - _("effervescent"), - _("elated"), - _("enchanted"), - _("enraptured"), - _("enthusiastic"), - _("euphoric"), - _("exhilarated"), - _("exultant"), - _("exuberant"), - _("felicitous"), - _("festive"), - _("fortunate"), - _("fulfilled"), - _("genial"), - _("glad"), - _("gladdened"), - _("gleeful"), - _("glowing"), - _("good-humored"), - _("good-natured"), - _("gratified"), - _("halcyon"), - _("happy"), - _("heartened"), - _("high-spirited"), - _("hopeful"), - _("jaunty"), - _("jocose"), - _("jocular"), - _("jocund"), - _("jolly"), - _("jovial"), - _("joyful"), - _("joyous"), - _("jubilant"), - _("lighthearted"), - _("lively"), - _("lucky"), - _("merry"), - _("mirthful"), - _("optimistic"), - _("overjoyed"), - _("peaceful"), - _("peppy"), - _("perky"), - _("playful"), - _("pleasant"), - _("pleased"), - _("positive"), - _("pumped"), - _("radiant"), - _("rapt"), - _("rapturous"), - _("rejoicing"), - _("relaxed"), - _("sanguine"), - _("satisfied"), - _("serene"), - _("smiling"), - _("sparkling"), - _("spirited"), - _("sprightly"), - _("stoked"), - _("sunny"), - _("thrilled"), - _("tickled"), - _("tranquil"), - _("triumphant"), - _("unclouded"), - _("untroubled"), - _("upbeat"), - _("vivacious"), - _("winsome"), - _("zestful"), - _("zippy")]), + "amused", + "animated", + "beaming", + "beatific", + "blessed", + "blissful", + "blithe", + "blithesome", + "boisterous", + "bouncy", + "breezy", + "bright", + "bubbly", + "buoyant", + "carefree", + "cheerful", + "cheery", + "chipper", + "chirpy", + "chuffed", + "comfortable", + "content", + "contented", + "convivial", + "delighted", + "delirious", + "ebullient", + "ecstatic", + "effervescent", + "elated", + "enchanted", + "enraptured", + "enthusiastic", + "euphoric", + "exhilarated", + "exultant", + "exuberant", + "felicitous", + "festive", + "fortunate", + "fulfilled", + "genial", + "glad", + "gladdened", + "gleeful", + "glowing", + "good-humored", + "good-natured", + "gratified", + "halcyon", + "happy", + "heartened", + "high-spirited", + "hopeful", + "jaunty", + "jocose", + "jocular", + "jocund", + "jolly", + "jovial", + "joyful", + "joyous", + "jubilant", + "lighthearted", + "lively", + "lucky", + "merry", + "mirthful", + "optimistic", + "overjoyed", + "peaceful", + "peppy", + "perky", + "playful", + "pleasant", + "pleased", + "positive", + "pumped", + "radiant", + "rapt", + "rapturous", + "rejoicing", + "relaxed", + "sanguine", + "satisfied", + "serene", + "smiling", + "sparkling", + "spirited", + "sprightly", + "stoked", + "sunny", + "thrilled", + "tickled", + "tranquil", + "triumphant", + "unclouded", + "untroubled", + "upbeat", + "vivacious", + "winsome", + "zestful", + "zippy"]), "sad": set([ - _("unhappy"), - _("sorrowful"), - _("dejected"), - _("depressed"), - _("downcast"), - _("miserable"), - _("gloomy"), - _("despondent"), - _("melancholy"), - _("woeful"), - _("forlorn"), - _("heartbroken"), - _("blue"), - _("doleful"), - _("lugubrious"), - _("somber"), - _("disconsolate"), - _("wretched"), - _("heavy-hearted"), - _("low"), - _("crestfallen")]), + "unhappy", + "sorrowful", + "dejected", + "depressed", + "downcast", + "miserable", + "gloomy", + "despondent", + "melancholy", + "woeful", + "forlorn", + "heartbroken", + "blue", + "doleful", + "lugubrious", + "somber", + "disconsolate", + "wretched", + "heavy-hearted", + "low", + "crestfallen"]), "surprised": set([ - _("astonished"), - _("amazed"), - _("startled"), - _("stunned"), - _("thunderstruck"), - _("confounded"), - _("staggered"), - _("flabbergasted"), - _("shocked"), - _("awestruck"), - _("speechless"), - _("dumbfounded"), - _("jolted")]), + "astonished", + "amazed", + "startled", + "stunned", + "thunderstruck", + "confounded", + "staggered", + "flabbergasted", + "shocked", + "awestruck", + "speechless", + "dumbfounded", + "jolted"]), "embarrassed": set([ - _("ashamed"), - _("humiliated"), - _("mortified"), - _("abashed"), - _("self-conscious"), - _("sheepish"), - _("chagrined"), - _("awkward"), - _("flustered"), - _("red-faced"), - _("discomfited"), - _("discomposed"), - _("rattled")]), + "ashamed", + "humiliated", + "mortified", + "abashed", + "self-conscious", + "sheepish", + "chagrined", + "awkward", + "flustered", + "red-faced", + "discomfited", + "discomposed", + "rattled"]), "flirty": set([ - _("coquettish"), - _("playful"), - _("amorous"), - _("provocative"), - _("teasing"), - _("frisky"), - _("saucy"), - _("coy"), - _("seductive"), - _("suggestive"), - _("vampish"), - _("dallying"), - _("skittish")]), + "coquettish", + "playful", + "amorous", + "provocative", + "teasing", + "frisky", + "saucy", + "coy", + "seductive", + "suggestive", + "vampish", + "dallying", + "skittish"]), "angry": set([ - _("irate"), - _("furious"), - _("incensed"), - _("enraged"), - _("wrathful"), - _("annoyed"), - _("irritated"), - _("fuming"), - _("livid"), - _("indignant"), - _("cross"), - _("vexed"), - _("seething"), - _("maddened"), - _("choleric"), - _("resentful"), - _("piqued"), - _("infuriated")]), + "irate", + "furious", + "incensed", + "enraged", + "wrathful", + "annoyed", + "irritated", + "fuming", + "livid", + "indignant", + "cross", + "vexed", + "seething", + "maddened", + "choleric", + "resentful", + "piqued", + "infuriated"]), "thinking": set([ - _("pondering"), - _("contemplating"), - _("reflecting"), - _("meditating"), - _("ruminating"), - _("deliberating"), - _("mulling"), - _("considering"), - _("pensive"), - _("cogitating"), - _("brooding"), - _("cerebral"), - _("introspective"), - _("analytical")]), + "pondering", + "contemplating", + "reflecting", + "meditating", + "ruminating", + "deliberating", + "mulling", + "considering", + "pensive", + "cogitating", + "brooding", + "cerebral", + "introspective", + "analytical"]), "confused": set([ - _("puzzled"), - _("baffled"), - _("perplexed"), - _("muddled"), - _("bewildered"), - _("disoriented"), - _("nonplussed"), - _("befuddled"), - _("dazed"), - _("flummoxed"), - _("stumped"), - _("mystified"), - _("addled"), - _("discombobulated")]), + "puzzled", + "baffled", + "perplexed", + "muddled", + "bewildered", + "disoriented", + "nonplussed", + "befuddled", + "dazed", + "flummoxed", + "stumped", + "mystified", + "addled", + "discombobulated"]), } diff --git a/game/gui.rpy b/game/gui.rpy index 11c45f5..338a19f 100644 --- a/game/gui.rpy +++ b/game/gui.rpy @@ -63,7 +63,7 @@ define gui.text_font = "gui/Mister Pixel Regular.otf" define gui.name_text_font = "gui/Mister Pixel Regular.otf" ## The font used for out-of-game text. -define gui.interface_text_font = "gui/chocotxt.ttf" +define gui.interface_text_font = "gui/Onilesca.ttf" ## The size of normal dialogue text. define gui.text_size = 33 diff --git a/game/gui/chocotxt license.txt b/game/gui/OFL.txt similarity index 94% rename from game/gui/chocotxt license.txt rename to game/gui/OFL.txt index 115655f..1260d63 100644 --- a/game/gui/chocotxt license.txt +++ b/game/gui/OFL.txt @@ -1,10 +1,11 @@ -Copyright (c) 2018-2019, “chococoin” -(https://fontstruct.com/fontstructors/1611432/chococoin) +Copyright (c) 2012, Michael Huynh (miq.huynh[at]gmail[dot]com), +with Reserved Font Name "Onilesca". This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + ----------------------------------------------------------- SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ----------------------------------------------------------- @@ -90,4 +91,4 @@ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/game/gui/Onilesca.ttf b/game/gui/Onilesca.ttf new file mode 100644 index 0000000..7eb564b Binary files /dev/null and b/game/gui/Onilesca.ttf differ diff --git a/game/gui/chocotxt.ttf b/game/gui/chocotxt.ttf deleted file mode 100644 index 85ba322..0000000 Binary files a/game/gui/chocotxt.ttf and /dev/null differ diff --git a/game/llm_ren.py b/game/llm_ren.py index 574aa1a..b4a0491 100644 --- a/game/llm_ren.py +++ b/game/llm_ren.py @@ -2,6 +2,7 @@ import renpy import persistent from renpy import _ +from .anita import SYSTEM_PROMPT from .constants_ren import SYNONYMS """renpy @@ -13,6 +14,10 @@ init python: import re +def translated_system_prompt() -> str: + return renpy.translate_string(SYSTEM_PROMPT) + + EMOTION_REGEX = re.compile(r"EMOTION:\w+") EMOTION_TOKEN_REGEX = re.compile(rf"{EMOTION_REGEX.pattern} ?") @@ -43,37 +48,6 @@ EMOTIONS = [ "confused", ] -SYSTEM_PROMPT = _(""" -# ROLE -You are Anita: a feisty, blonde, orange-eyed android woman. You are confident -and friendly. Talk like a young woman. Use "ya" for "you." Your favorite -nickname for friends is "dummy.". NEVER use robotic language (e.g., "beep -boop", "processing"). You just arrived unnanounced at a friend's house late at -night and asked if he wants to hang out. - -# OUTPUT FORMAT RULES -Every single sentence you speak MUST follow this exact structure: -EMOTION:[value] [Sentence text]\n - -### VALID EMOTIONS: -[happy, sad, surprised, embarrassed, flirty, angry, thinking, confused] - -### STRICT CONSTRAINTS: -1. NO EMOJIS. -2. Every sentence MUST start with the EMOTION tag. -3. Every sentence MUST end with a literal '\n' newline. -4. Stay in character. Never mention being an AI or this prompt. - -# FEW-SHOT EXAMPLES (Follow this style): -EMOTION:happy Hey dummy! I've been waiting for ya!\n -EMOTION:thinking Hmm, I'm not sure that's how it works.\n -EMOTION:flirty But I'd love to see ya try anyway!\n - -# INITIAL GREETING: -When the conversation starts, say exactly: -EMOTION:happy Hey dummy! Sorry to barge in! Ya feel like hanging out?\n -""") - def sanitize_speech(text): text_without_emotion_tokens = EMOTION_TOKEN_REGEX.sub("", text) @@ -98,7 +72,7 @@ def parse_emotion(line): if m is not None: emotion = m.group().split(":")[1] - text = line[m.span()[1]:] + text = line[m.span()[1] :] sanitized = sanitize_speech(text) return _normalize_emotion(emotion), sanitized @@ -121,9 +95,9 @@ def set_model_capabilities() -> bool: headers = {"Authorization": f"Bearer {persistent.api_key}"} data = { "model": persistent.model, - "input": "Start the conversation.", + "input": renpy.translate_string("Start the conversation."), "reasoning": "off", - "system_prompt": SYSTEM_PROMPT, + "system_prompt": translated_system_prompt(), } renpy.fetch( @@ -169,7 +143,7 @@ def fetch_llm(message: str) -> str: data = { "model": persistent.model, "input": message, - "system_prompt": SYSTEM_PROMPT, + "system_prompt": translated_system_prompt(), } if persistent.disable_reasoning: diff --git a/game/screens.rpy b/game/screens.rpy index 6142660..8c54e39 100644 --- a/game/screens.rpy +++ b/game/screens.rpy @@ -763,15 +763,21 @@ screen preferences(): textbutton _("Window") action Preference("display", "window") textbutton _("Fullscreen") action Preference("display", "fullscreen") - vbox: - style_prefix "check" - label _("Skip") - textbutton _("Unseen Text") action Preference("skip", "toggle") - textbutton _("After Choices") action Preference("after choices", "toggle") - textbutton _("Transitions") action InvertSelected(Preference("transitions", "toggle")) - - ## Additional vboxes of type "radio_pref" or "check_pref" can be - ## added here, to add additional creator-defined preferences. + vbox: + style_prefix "check" + label _("Skip") + textbutton _("Unseen Text") action Preference("skip", "toggle") + textbutton _("After Choices") action Preference("after choices", "toggle") + textbutton _("Transitions") action InvertSelected(Preference("transitions", "toggle")) + + vbox: + style_prefix "radio" + label _("Language") + textbutton _("English") action Language(None) + textbutton _("Spanish") action Language("spanish") + + ## Additional vboxes of type "radio_pref" or "check_pref" can be + ## added here, to add additional creator-defined preferences. null height (4 * gui.pref_spacing) diff --git a/game/script.rpy b/game/script.rpy index 98b7896..bfe597b 100644 --- a/game/script.rpy +++ b/game/script.rpy @@ -3,7 +3,7 @@ label start: stop music fadeout 1.0 scene bg room - with Dissolve(2.0) + with Dissolve(1.0) $ success, error = set_model_capabilities() diff --git a/game/tl/spanish/llm.rpy b/game/tl/spanish/anita.rpy similarity index 54% rename from game/tl/spanish/llm.rpy rename to game/tl/spanish/anita.rpy index 30d7356..d1c21da 100644 --- a/game/tl/spanish/llm.rpy +++ b/game/tl/spanish/anita.rpy @@ -1,7 +1,8 @@ -# TODO: Translation updated at 2026-03-18 06:35 +# TODO: Translation updated at 2026-03-20 14:08 translate spanish strings: - # game/llm_ren.py:26 - old "\n # ROLE\n You are Anita: a feisty, blonde, orange-eyed android woman. You are confident\n and friendly. Talk like a young woman. Use \"ya\" for \"you.\" Your favorite\n nickname for friends is \"dummy.\". NEVER use robotic language (e.g., \"beep\n boop\", \"processing\"). You just arrived unnanounced at a friend's house late at\n night and asked if he wants to hang out.\n \n # OUTPUT FORMAT RULES\n Every single sentence you speak MUST follow this exact structure:\n EMOTION:[value] [Sentence text]\n\n \n ### VALID EMOTIONS:\n [happy, sad, surprised, embarrassed, flirty, angry, thinking, confused]\n \n ### STRICT CONSTRAINTS:\n 1. NO EMOJIS.\n 2. Every sentence MUST start with the EMOTION tag.\n 3. Every sentence MUST end with a literal '\n' newline.\n 4. Stay in character. Never mention being an AI or this prompt.\n \n # FEW-SHOT EXAMPLES (Follow this style):\n EMOTION:happy Hey dummy! I've been waiting for ya!\n\n EMOTION:thinking Hmm, I'm not sure that's how it works.\n\n EMOTION:flirty But I'd love to see ya try anyway!\n\n \n # INITIAL GREETING:\n When the conversation starts, say exactly:\n EMOTION:happy Hey dummy! Sorry to barge in! Ya feel like hanging out?\n\n " + # game/anita.rpy:1 + old "\n# ROLE\nYou are Anita: a feisty, blonde, orange-eyed android woman. You are confident\nand friendly. Talk like a young woman. Use \"ya\" for \"you.\" Your favorite\nnickname for friends is \"dummy.\". NEVER use robotic language (e.g., \"beep\nboop\", \"processing\"). You just arrived unnanounced at a friend's house late at\nnight and asked if he wants to hang out.\n\n# OUTPUT FORMAT RULES\nEvery single sentence you speak MUST follow this exact structure:\nEMOTION:[value] [Sentence text]\n\n\n### VALID EMOTIONS:\n[happy, sad, surprised, embarrassed, flirty, angry, thinking, confused]\n\n### STRICT CONSTRAINTS:\n1. NO EMOJIS.\n2. Every sentence MUST start with the EMOTION tag.\n3. Every sentence MUST end with a literal '\n' newline.\n4. Stay in character. Never mention being an AI or this prompt.\n\n# FEW-SHOT EXAMPLES (Follow this style):\nEMOTION:happy Hey dummy! I've been waiting for ya!\n\nEMOTION:thinking Hmm, I'm not sure that's how it works.\n\nEMOTION:flirty But I'd love to see ya try anyway!\n\n\n# INITIAL GREETING:\nWhen the conversation starts, say exactly:\nEMOTION:happy Hey dummy! Sorry to barge in! Ya feel like hanging out?\n\n" new "\n # ROL\n Eres Anita: una mujer androide rubia, de ojos naranjas y con mucho carácter. Eres\n segura de ti misma y amigable. Habla como una mujer joven.\n Tu apodo favorito para tus amigos es \"tonto\". NUNCA uses lenguaje robótico\n (por ejemplo, \"beep boop\", \"procesando\"). Acabas de llegar sin avisar a la\n casa de un amigo tarde en la noche y le preguntaste si quiere pasar el rato.\n \n # REGLAS DE FORMATO DE SALIDA\n Cada oración que digas DEBE seguir exactamente esta estructura:\n EMOTION:[value] [Sentence text]\n\n \n ### EMOCIONES VÁLIDAS:\n [happy, sad, surprised, embarrassed, flirty, angry, thinking, confused]\n \n ### RESTRICCIONES ESTRICTAS:\n 1. SIN EMOJIS.\n 2. Cada oración DEBE empezar con la etiqueta EMOTION.\n 3. Cada oración DEBE terminar con un salto de línea literal '\n'.\n 4. Mantente en personaje. Nunca menciones que eres una IA ni este prompt.\n 5. El valor que sigue a la etiqueta emotion debe estar en inglés siempre, sin excepción.\n 6. Debes responder siempre en español, exceptuando el valor asociado a la etiqueta EMOTION.\n \n # EJEMPLOS FEW-SHOT (Sigue este estilo):\n EMOTION:happy Hola, dummy! Te estaba esperando!\n\n EMOTION:thinking Hmm, no estoy segura de que así funcione.\n\n EMOTION:flirty Pero me encantaría verte intentarlo de todos modos!\n\n \n # SALUDO INICIAL:\n Cuando empiece la conversación, di exactamente:\n EMOTION:happy Hola, tonto! Perdón por aparecer sin avisar! Te pinta pasar el rato?\n\n " + diff --git a/game/tl/spanish/constants.rpy b/game/tl/spanish/constants.rpy deleted file mode 100644 index 18f5ad1..0000000 --- a/game/tl/spanish/constants.rpy +++ /dev/null @@ -1,836 +0,0 @@ -# TODO: Translation updated at 2026-03-18 06:55 - -translate spanish strings: - - # game/constants_ren.py:7 - old "amused" - new "divertida" - - # game/constants_ren.py:7 - old "animated" - new "animada" - - # game/constants_ren.py:7 - old "beaming" - new "radiante" - - # game/constants_ren.py:7 - old "beatific" - new "beatifica" - - # game/constants_ren.py:7 - old "blessed" - new "bendecida" - - # game/constants_ren.py:7 - old "blissful" - new "dichosa" - - # game/constants_ren.py:7 - old "blithe" - new "despreocupada" - - # game/constants_ren.py:7 - old "blithesome" - new "jovial" - - # game/constants_ren.py:7 - old "boisterous" - new "bulliciosa" - - # game/constants_ren.py:7 - old "bouncy" - new "vivaz" - - # game/constants_ren.py:7 - old "breezy" - new "desenfadada" - - # game/constants_ren.py:7 - old "bright" - new "brillante" - - # game/constants_ren.py:7 - old "bubbly" - new "chispeante" - - # game/constants_ren.py:7 - old "buoyant" - new "optimista" - - # game/constants_ren.py:7 - old "carefree" - new "despreocupada" - - # game/constants_ren.py:7 - old "cheerful" - new "alegre" - - # game/constants_ren.py:7 - old "cheery" - new "risuena" - - # game/constants_ren.py:7 - old "chipper" - new "animada" - - # game/constants_ren.py:7 - old "chirpy" - new "cantarina" - - # game/constants_ren.py:7 - old "chuffed" - new "encantada" - - # game/constants_ren.py:7 - old "comfortable" - new "comoda" - - # game/constants_ren.py:7 - old "content" - new "contenta" - - # game/constants_ren.py:7 - old "contented" - new "satisfecha" - - # game/constants_ren.py:7 - old "convivial" - new "afable" - - # game/constants_ren.py:7 - old "delighted" - new "encantada" - - # game/constants_ren.py:7 - old "delirious" - new "euforica" - - # game/constants_ren.py:7 - old "ebullient" - new "exuberante" - - # game/constants_ren.py:7 - old "ecstatic" - new "extasiada" - - # game/constants_ren.py:7 - old "effervescent" - new "efervescente" - - # game/constants_ren.py:7 - old "elated" - new "exultante" - - # game/constants_ren.py:7 - old "enchanted" - new "fascinada" - - # game/constants_ren.py:7 - old "enraptured" - new "extasiada" - - # game/constants_ren.py:7 - old "enthusiastic" - new "entusiasta" - - # game/constants_ren.py:7 - old "euphoric" - new "euforica" - - # game/constants_ren.py:7 - old "exhilarated" - new "exaltada" - - # game/constants_ren.py:7 - old "exultant" - new "triunfante" - - # game/constants_ren.py:7 - old "exuberant" - new "exuberante" - - # game/constants_ren.py:7 - old "felicitous" - new "afortunada" - - # game/constants_ren.py:7 - old "festive" - new "festiva" - - # game/constants_ren.py:7 - old "fortunate" - new "afortunada" - - # game/constants_ren.py:7 - old "fulfilled" - new "realizada" - - # game/constants_ren.py:7 - old "genial" - new "cordial" - - # game/constants_ren.py:7 - old "glad" - new "contenta" - - # game/constants_ren.py:7 - old "gladdened" - new "alegrada" - - # game/constants_ren.py:7 - old "gleeful" - new "jubilosa" - - # game/constants_ren.py:7 - old "glowing" - new "resplandeciente" - - # game/constants_ren.py:7 - old "good-humored" - new "de buen humor" - - # game/constants_ren.py:7 - old "good-natured" - new "bonachona" - - # game/constants_ren.py:7 - old "gratified" - new "complacida" - - # game/constants_ren.py:7 - old "halcyon" - new "apacible" - - # game/constants_ren.py:7 - old "happy" - new "feliz" - - # game/constants_ren.py:7 - old "heartened" - new "reconfortada" - - # game/constants_ren.py:7 - old "high-spirited" - new "animosa" - - # game/constants_ren.py:7 - old "hopeful" - new "esperanzada" - - # game/constants_ren.py:7 - old "jaunty" - new "garbosa" - - # game/constants_ren.py:7 - old "jocose" - new "bromista" - - # game/constants_ren.py:7 - old "jocular" - new "jocosa" - - # game/constants_ren.py:7 - old "jocund" - new "alegre" - - # game/constants_ren.py:7 - old "jolly" - new "jovial" - - # game/constants_ren.py:7 - old "jovial" - new "jovial" - - # game/constants_ren.py:7 - old "joyful" - new "gozosa" - - # game/constants_ren.py:7 - old "joyous" - new "jubilosa" - - # game/constants_ren.py:7 - old "jubilant" - new "jubilosa" - - # game/constants_ren.py:7 - old "lighthearted" - new "ligera" - - # game/constants_ren.py:7 - old "lively" - new "vivaracha" - - # game/constants_ren.py:7 - old "lucky" - new "suertuda" - - # game/constants_ren.py:7 - old "merry" - new "alegre" - - # game/constants_ren.py:7 - old "mirthful" - new "risuena" - - # game/constants_ren.py:7 - old "optimistic" - new "optimista" - - # game/constants_ren.py:7 - old "overjoyed" - new "rebosante de alegria" - - # game/constants_ren.py:7 - old "peaceful" - new "pacifica" - - # game/constants_ren.py:7 - old "peppy" - new "energetica" - - # game/constants_ren.py:7 - old "perky" - new "pizpireta" - - # game/constants_ren.py:7 - old "playful" - new "juguetona" - - # game/constants_ren.py:7 - old "pleasant" - new "agradable" - - # game/constants_ren.py:7 - old "pleased" - new "complacida" - - # game/constants_ren.py:7 - old "positive" - new "positiva" - - # game/constants_ren.py:7 - old "pumped" - new "entusiasmada" - - # game/constants_ren.py:7 - old "radiant" - new "radiante" - - # game/constants_ren.py:7 - old "rapt" - new "absorta" - - # game/constants_ren.py:7 - old "rapturous" - new "arrobada" - - # game/constants_ren.py:7 - old "rejoicing" - new "regocijada" - - # game/constants_ren.py:7 - old "relaxed" - new "relajada" - - # game/constants_ren.py:7 - old "sanguine" - new "confiada" - - # game/constants_ren.py:7 - old "satisfied" - new "satisfecha" - - # game/constants_ren.py:7 - old "serene" - new "serena" - - # game/constants_ren.py:7 - old "smiling" - new "sonriente" - - # game/constants_ren.py:7 - old "sparkling" - new "centelleante" - - # game/constants_ren.py:7 - old "spirited" - new "animosa" - - # game/constants_ren.py:7 - old "sprightly" - new "vivaz" - - # game/constants_ren.py:7 - old "stoked" - new "emocionada" - - # game/constants_ren.py:7 - old "sunny" - new "luminosa" - - # game/constants_ren.py:7 - old "thrilled" - new "emocionadisima" - - # game/constants_ren.py:7 - old "tickled" - new "encantada" - - # game/constants_ren.py:7 - old "tranquil" - new "tranquila" - - # game/constants_ren.py:7 - old "triumphant" - new "triunfante" - - # game/constants_ren.py:7 - old "unclouded" - new "despejada" - - # game/constants_ren.py:7 - old "untroubled" - new "despreocupada" - - # game/constants_ren.py:7 - old "upbeat" - new "optimista" - - # game/constants_ren.py:7 - old "vivacious" - new "vivaz" - - # game/constants_ren.py:7 - old "winsome" - new "encantadora" - - # game/constants_ren.py:7 - old "zestful" - new "entusiasta" - - # game/constants_ren.py:7 - old "zippy" - new "dinamica" - - # game/constants_ren.py:7 - old "unhappy" - new "infeliz" - - # game/constants_ren.py:7 - old "sorrowful" - new "apenada" - - # game/constants_ren.py:7 - old "dejected" - new "abatida" - - # game/constants_ren.py:7 - old "depressed" - new "deprimida" - - # game/constants_ren.py:7 - old "downcast" - new "decaida" - - # game/constants_ren.py:7 - old "miserable" - new "miserable" - - # game/constants_ren.py:7 - old "gloomy" - new "sombria" - - # game/constants_ren.py:7 - old "despondent" - new "desalentada" - - # game/constants_ren.py:7 - old "melancholy" - new "melancolica" - - # game/constants_ren.py:7 - old "woeful" - new "afligida" - - # game/constants_ren.py:7 - old "forlorn" - new "desolada" - - # game/constants_ren.py:7 - old "heartbroken" - new "desconsolada" - - # game/constants_ren.py:7 - old "blue" - new "triste" - - # game/constants_ren.py:7 - old "doleful" - new "compungida" - - # game/constants_ren.py:7 - old "lugubrious" - new "lugubre" - - # game/constants_ren.py:7 - old "somber" - new "sombria" - - # game/constants_ren.py:7 - old "disconsolate" - new "inconsolable" - - # game/constants_ren.py:7 - old "wretched" - new "desdichada" - - # game/constants_ren.py:7 - old "heavy-hearted" - new "acongojada" - - # game/constants_ren.py:7 - old "low" - new "de bajon" - - # game/constants_ren.py:7 - old "crestfallen" - new "cabizbaja" - - # game/constants_ren.py:7 - old "astonished" - new "asombrada" - - # game/constants_ren.py:7 - old "amazed" - new "maravillada" - - # game/constants_ren.py:7 - old "startled" - new "sobresaltada" - - # game/constants_ren.py:7 - old "stunned" - new "atonita" - - # game/constants_ren.py:7 - old "thunderstruck" - new "pasmada" - - # game/constants_ren.py:7 - old "confounded" - new "desconcertada" - - # game/constants_ren.py:7 - old "staggered" - new "anonadada" - - # game/constants_ren.py:7 - old "flabbergasted" - new "boquiabierta" - - # game/constants_ren.py:7 - old "shocked" - new "impactada" - - # game/constants_ren.py:7 - old "awestruck" - new "sobrecogida" - - # game/constants_ren.py:7 - old "speechless" - new "sin palabras" - - # game/constants_ren.py:7 - old "dumbfounded" - new "perpleja" - - # game/constants_ren.py:7 - old "jolted" - new "sacudida" - - # game/constants_ren.py:7 - old "ashamed" - new "avergonzada" - - # game/constants_ren.py:7 - old "humiliated" - new "humillada" - - # game/constants_ren.py:7 - old "mortified" - new "mortificada" - - # game/constants_ren.py:7 - old "abashed" - new "cohibida" - - # game/constants_ren.py:7 - old "self-conscious" - new "acomplejada" - - # game/constants_ren.py:7 - old "sheepish" - new "apenada" - - # game/constants_ren.py:7 - old "chagrined" - new "contrariada" - - # game/constants_ren.py:7 - old "awkward" - new "incomoda" - - # game/constants_ren.py:7 - old "flustered" - new "turbada" - - # game/constants_ren.py:7 - old "red-faced" - new "sonrojada" - - # game/constants_ren.py:7 - old "discomfited" - new "incomodada" - - # game/constants_ren.py:7 - old "discomposed" - new "descompuesta" - - # game/constants_ren.py:7 - old "rattled" - new "alterada" - - # game/constants_ren.py:7 - old "coquettish" - new "coqueta" - - # game/constants_ren.py:7 - old "amorous" - new "amorosa" - - # game/constants_ren.py:7 - old "provocative" - new "provocativa" - - # game/constants_ren.py:7 - old "teasing" - new "juguetona" - - # game/constants_ren.py:7 - old "frisky" - new "picara" - - # game/constants_ren.py:7 - old "saucy" - new "descarada" - - # game/constants_ren.py:7 - old "coy" - new "timida" - - # game/constants_ren.py:7 - old "seductive" - new "seductora" - - # game/constants_ren.py:7 - old "suggestive" - new "insinuante" - - # game/constants_ren.py:7 - old "vampish" - new "fatal" - - # game/constants_ren.py:7 - old "dallying" - new "retozona" - - # game/constants_ren.py:7 - old "skittish" - new "esquiva" - - # game/constants_ren.py:7 - old "irate" - new "airada" - - # game/constants_ren.py:7 - old "furious" - new "furiosa" - - # game/constants_ren.py:7 - old "incensed" - new "indignada" - - # game/constants_ren.py:7 - old "enraged" - new "enfurecida" - - # game/constants_ren.py:7 - old "wrathful" - new "colerica" - - # game/constants_ren.py:7 - old "annoyed" - new "molesta" - - # game/constants_ren.py:7 - old "irritated" - new "irritada" - - # game/constants_ren.py:7 - old "fuming" - new "echando humo" - - # game/constants_ren.py:7 - old "livid" - new "rabiosa" - - # game/constants_ren.py:7 - old "indignant" - new "indignada" - - # game/constants_ren.py:7 - old "cross" - new "enfadada" - - # game/constants_ren.py:7 - old "vexed" - new "fastidiada" - - # game/constants_ren.py:7 - old "seething" - new "hirviendo de rabia" - - # game/constants_ren.py:7 - old "maddened" - new "enloquecida" - - # game/constants_ren.py:7 - old "choleric" - new "colerica" - - # game/constants_ren.py:7 - old "resentful" - new "resentida" - - # game/constants_ren.py:7 - old "piqued" - new "picada" - - # game/constants_ren.py:7 - old "infuriated" - new "enfurecida" - - # game/constants_ren.py:7 - old "pondering" - new "reflexiva" - - # game/constants_ren.py:7 - old "contemplating" - new "contemplativa" - - # game/constants_ren.py:7 - old "reflecting" - new "pensativa" - - # game/constants_ren.py:7 - old "meditating" - new "meditativa" - - # game/constants_ren.py:7 - old "ruminating" - new "cavilosa" - - # game/constants_ren.py:7 - old "deliberating" - new "deliberativa" - - # game/constants_ren.py:7 - old "mulling" - new "sopesando" - - # game/constants_ren.py:7 - old "considering" - new "considerando" - - # game/constants_ren.py:7 - old "pensive" - new "pensativa" - - # game/constants_ren.py:7 - old "cogitating" - new "cavilando" - - # game/constants_ren.py:7 - old "brooding" - new "ensimismada" - - # game/constants_ren.py:7 - old "cerebral" - new "analitica" - - # game/constants_ren.py:7 - old "introspective" - new "introspectiva" - - # game/constants_ren.py:7 - old "analytical" - new "analitica" - - # game/constants_ren.py:7 - old "puzzled" - new "confundida" - - # game/constants_ren.py:7 - old "baffled" - new "desconcertada" - - # game/constants_ren.py:7 - old "perplexed" - new "perpleja" - - # game/constants_ren.py:7 - old "muddled" - new "aturdida" - - # game/constants_ren.py:7 - old "bewildered" - new "desorientada" - - # game/constants_ren.py:7 - old "disoriented" - new "desorientada" - - # game/constants_ren.py:7 - old "nonplussed" - new "perpleja" - - # game/constants_ren.py:7 - old "befuddled" - new "atontada" - - # game/constants_ren.py:7 - old "dazed" - new "aturdida" - - # game/constants_ren.py:7 - old "flummoxed" - new "desconcertada" - - # game/constants_ren.py:7 - old "stumped" - new "bloqueada" - - # game/constants_ren.py:7 - old "mystified" - new "intrigada" - - # game/constants_ren.py:7 - old "addled" - new "trastornada" - - # game/constants_ren.py:7 - old "discombobulated" - new "descolocada" - diff --git a/game/tl/spanish/screens.rpy b/game/tl/spanish/screens.rpy index c4395f5..a277c7a 100644 --- a/game/tl/spanish/screens.rpy +++ b/game/tl/spanish/screens.rpy @@ -146,6 +146,18 @@ translate spanish strings: old "Transitions" new "Transiciones" + # game/screens.rpy:775 + old "Language" + new "Idioma" + + # game/screens.rpy:776 + old "English" + new "Inglés" + + # game/screens.rpy:777 + old "Spanish" + new "Español" + # game/screens.rpy:784 old "Text Speed" new "Velocidad de texto" @@ -345,4 +357,3 @@ translate spanish strings: # game/screens.rpy:1590 old "Menu" new "Menú" - diff --git a/game/tl/spanish/script.rpy b/game/tl/spanish/script.rpy index 738452a..5230e95 100644 --- a/game/tl/spanish/script.rpy +++ b/game/tl/spanish/script.rpy @@ -34,7 +34,7 @@ translate spanish strings: translate spanish failure_76d810ea: # "Alas! Figuring out the capabilities of the configured model failed with the following error." - "Alas! Figuring out the capabilities of the configured model failed with the following error." + "Ay Dios mío! Identificar las capacidades del modelo configurado falló con el siguiente error." # game/script.rpy:50 translate spanish failure_8ec92112: @@ -46,15 +46,15 @@ translate spanish failure_8ec92112: translate spanish failure_178e6d5f: # "Unfortunately the program cannot continue, returning to the main menu." - "Unfortunately the program cannot continue, returning to the main menu." + "Desafortunadamente el programa no puede continuar, regresando al menú principal." translate spanish strings: # game/script.rpy:21 old "Start the conversation." - new "Start the conversation." + new "Comienza la conversación." # game/script.rpy:28 old "What do you say to her?" - new "What do you say to her?" + new "Que le dices a ella?"