Version 0.1 (Beta) [internal 0.10000], 31 Oct 2026 (developer: RadimirSi) - official Beta

- New name: the game is now "Perfectly Imperfective" (window title, About, credits,
  build/executable names, in-game text). Save directory unchanged, so old saves load.
- The university is now Udarenie University (Университет «Ударение»); new dictionary
  entry «ударение» (stress/accent) with the university sense.
- New main menu: Story / Study / Minigame mode, Load, Preferences, About, Help, Quit,
  Patreon and Feedback buttons, version tag "v0.1 (Beta)" and the RadimirSi logo.
- Game menus (Save, Load, Preferences, History, About, Help) restyled in walnut and brass.
- Saves can be deleted: a brass x on filled slots, with a confirmation (No is default).
- Tests, quizzes, the barista shift, practice choices, part select, the minigame hub,
  records and the phone apps restyled; scramble tiles are now lowercase.
- Error screen: new "Report this bug" button opens the support page with the version,
  platform and the error log filled in.
- Grammar: «Вы сдали» / «Вы получили» (formal Вы takes the plural past).
- Day-1 lines from Katya, Prof. Volkova, Misha and Dima now have full Russian versions,
  so the mixed and Russian modes show them.
- Prof. Volkova now uses her own varied reactions to wrong answers in practice.
- dima_tea_rude checked: it returns to the hangout correctly (flow test added); the
  "jump intro_katya_done" note in the 0.00401 voice-script README was a false report.

Version 0.00401, 31 Oct 2026 (developer: RadimirSi) - bug-fix build

- Choice menus: the standard Ren'Py choice menu is used everywhere; the compact
  layout only kicks in when the options would not fit on screen.
- Dictionary: every word in the game now has a definition (Wiktionary first, a small
  hand-written supplement for inflected forms and names); online search removed,
  the dictionary is fully offline.
- Maps: places you can go but have not visited yet glow; the first visit plays a short
  one-time story intro. After that a place glows only when something is happening there.
- Notebook app: an aligned table (Russian | English | Lesson | ✓/✗) with a header row.
- Dorm: the bed, desk, textbook and laptop glow until you first use them.
- Barista minigame: tap the items (no typing numbers), with a − button and Serve.
  Harder number forms and multi-item orders appear as your level grows.
- Language notes reviewed for accuracy: gender of -а words for men and -мя nouns,
  prepositional -ии / -и, accusative of feminine -ь nouns and animate masculines,
  genitive plural after 5-20 and 21/22/25, numbers with adjectives, months, surnames,
  давай + imperfective infinitive, не vs нет, and several item notes.
- Reading the textbook now makes its words free to Inspect for a full in-game week.
- Character sprites: cleaner transparent edges (originals kept in old/).
- Fixed characters speaking without their sprite in socialize and story scenes
  (Prof. Volkova's office hours, Anna, Alexei, Jess, Katya, Misha); every speaker
  checked.
- Inspect is now a painted magnifying-glass button at the bottom right (same round brass
  button as the bottom-left controls; glows while inspecting). The old top-right button
  that overlapped the HUD is gone.
- Campus and town maps now sit inside a carved walnut-and-brass frame. The paintings are
  scaled down evenly so nothing is cropped, and building hotspots were moved to match.
- Removed the unused laptop menu. Lint clean.

Version 3.0, 30 Oct 2026 (developer: RadimirSi)

Curriculum and units
- The year now follows the course textbooks (textbooks/curriculum_map): grammar is taught
  in textbook lesson order, lessons 1-41, with the ~45 topics the game was missing added
  (87 topics, 316 practice items). All explanations and examples are original.
- Units: Unit 1 = textbook Mod 1 (Part 1) + Mod 2 (Part 2); Unit 2 = Mod 3 + Mod 4;
  Unit 3 = Mod 5, 6, 7 (Parts 1-3); Unit 4 = News & Media (Part 1) + Thematics (Part 2).
  The frequency list is "Supplemental", lowest priority. Labels read "Unit 1 Part 2".
- python-packages/curriculum.py builds the year plan: one lesson per slot, slots spread
  over every class week (weighted by how much grammar a lesson has), review lessons
  (10, 15, 20, 25, 31, 36, 41) get their own slot, no two lessons share a start day.
  Unit 4 Part 1 words ride along with the Unit 2-3 lessons; Supplemental words are
  spread thinly over every slot.
- Main menu: Story mode (everything), Study mode (pick unit parts; they are spread over
  the whole year), Minigame mode (pick unit parts, minigames only, all words open).

Class, textbook, socializing
- Class is a full lesson: the explanation, then several exercises in several formats
  (pick-the-form, vocabulary multiple choice, word tiles). "Skip lesson" skips only the
  explanation. Russian skill is awarded only for correct answers.
- Reading the textbook gives the day's words; they are free to Inspect for the rest of
  that day.
- Socialize in Russian: 24 real dialogues in 5 difficulty tiers that follow your progress.
  Every answer is best / ok / wrong with different points; wrong answers cost charm and
  add stress, two wrong answers end the conversation. Partners speak Russian; the
  English is behind Hint.
- Hints: in tests, quizzes, exams and minigames the English and the case name sit behind
  a Hint button that costs points (no Russian point). Lessons may show them openly.

Balance and flow
- Russian skill is an encouragement score, not a grade: gains with gentle diminishing
  returns, nothing is gated on it; the daily decay for skipped classes stays.
  Exam marks: pass 55, good 70, excellent 85; scholarship = average 80 and 30% of the
  required words mastered. Checked with full-year bot runs: a random player passes
  (average 58-60%); a 90%-accurate player who still skips half the classes ends at
  79% / 27% mastered, just under the scholarship, so attending class earns it.
- Midnight: "It's too late" and you are sent to bed with a little less energy restored.
- Groceries no longer use a time slot.
- Word picking: no repeats within a round, a recency penalty, and spaced review still
  brings missed words back.
- The textbox background appears only while a line is shown.

Music
- 16 tracks (game/audio/music), assigned to moods (menu, campus, folk, cafe, romance,
  exam, game, holiday, celebration...). Long tracks are trimmed and looped.
- Playlist (Preferences > Playlist..., or the phone's Music app): tracks grouped by genre
  (Classical-Piano, Orchestral, Folk, Winter/Holiday, Modern Russian-style); switch whole
  genres or single songs; choices persist; only enabled tracks play, all off = silence.
- Full credits (exact Kevin MacLeod wording, Musopen, and the other recordings) in
  About and in CREDITS.txt.

Scramble keyboard typing
- In letter scrambles (minigame and exam tiles) you can type: a Cyrillic letter picks
  the first free tile with that letter, exactly like clicking; letters not on a free tile
  do nothing; Latin keys are ignored (no transliteration); Backspace undoes the last
  pick. Case-insensitive; е and ё are different letters. While a letter scramble is up,
  single-key shortcuts (h, s, f, ...) are swallowed; Esc, Enter, Tab, arrows and Ctrl/Alt
  combos still work. Uses SDL text input, so any Russian layout works.

Metadata
- Developer "RadimirSi": window title, About, credits, options.rpy, build/package name
  (Bellwether-RadimirSi-3.0), version 3.0.

Bugs fixed during this build
- Stale compiled 15_social.rpyc made "ru_social" defined twice (removed).
- Minigame hub variable clashed with a harness function on save (renamed).
- Scramble.full() briefly ended up on the wrong class while adding typing (caught by test).

Build notes, 29 Oct 2026 (overnight feedback batch)

Changes
- No open-ended typed translations anywhere. Exams and minigames use multiple choice,
  matching, letter/word tiles and pick-the-form. Typing remains only for case endings
  (Cyrillic or translit) and the finite scramble answers.
- Case-ending game: the case name and English gloss are behind "Hint (-1/2 pt)".
  Exams keep their case label visible (an exam is a test of the ending, not the case).
- Maps: the textbox is hidden on maps (window auto), so it only appears with a line.
  (30 Oct) Locations are spread over the full screen again; the action bar is a slim
  strip just above the quick menu.
  The action bar sits mid-screen, clear of the textbox and quick menu at every window
  size (checked at 1920x1080, 1280x720, 1024x768 and 960x540).
- Curriculum order: Mod 1..7, then News & Media, then Thematics, then Frequency (lowest). (Superseded in v3: Units.)
- Phone (map bar > Phone): a home screen with an app grid, a status bar, Messages
  (who is where now) and Calendar (upcoming events). Games rotate the phone to
  landscape (animated) and back. The dorm keeps a plain "laptop" menu.
  To swap the art, replace these files (same size) in game/images/phone/:
  phone_frame.png 380x660, phone_wallpaper.png 336x560,
  phone_bezel_landscape.png 1280x720 (transparent centre),
  apps/app_<id>.png 96x96 for <id> in match scramble endings review messages
  calendar stats notebook records. tools/make_phone_art.py only fills in missing files.
- Inspect button: hidden entirely (not greyed out) where it cannot be used.
- Schedules: python-packages/vn_schedule.py gives each romanceable character one place
  (or none) per slot: story-event overrides > term-specific weekly table > class-term or
  break weekly table. Runtime story overrides use set_presence() (e.g. Valentine's).
  The map, phone Messages and hangouts all read char_location().
  tests/test_schedule.py checks that nobody is in two places in any slot of the year.
- Inspect prefers an exact course-vocabulary match over the Wiktionary lemma
  (e.g. "надо" = must, not a form of "над").

30 Oct 2026 (Ren'Py 8.5.3 crash fix)
- Crash "TypeError: %o format: an integer is required, not TagQuotingDict" at
  11_intro.rpy:129 ("10% off"). Cause: Ren'Py's default config.old_substitutions = True
  %-formats every say line and menu caption (renpy/exports/sayexports.py), so
  "10% off" was read as the format "% o". Same in 8.3.7; the old test harness
  bypassed renpy.say, so it was never hit in testing.
- Fix: options.rpy sets config.old_substitutions = False. Text is never %-formatted;
  write a literal % as a single % everywhere ([var] interpolation is unchanged).
  12_events.rpy year-end summary: "%%" -> "%" (4 places, English and Russian).
- tests/test_percent.py checks the setting and scans all displayed strings (say lines,
  ru=/mix= alternates, menus, renpy.say/notify, L(), ru_choice/RuOpt, screen text).
- Tested on Ren'Py 8.3.7 and 8.5.3 (lint clean, fuzz play-throughs through the real
  renpy.say path, screenshots match).
