Repository navigation
Combat: no raw ids in action-bar targets; translate catalog item/attack names - #84
Merged
Merged
Conversation
added 2 commits
September 29, 2026 08:40
TargetDropdown (attack/talk), DirectionalDropdown (move/dash toward/away)
and the smite choice panel labelled targets with the internal entity id
("Атаковать goblin_chieftain_5"). They now use perceivedLabels, the same
rule as the Nearby panel: perceived description (a stranger's race), else
known name, with an ordinal suffix for duplicates.
Attack names ("longsword slash") reached the combat panel without gettext
and neither they nor most item names (Shield, Chain Mail, ...) had a ru
translation; perception.py kept a hand-maintained, incomplete _() list.
- content_loader/catalog_messages.py lists every catalog item name,
weapon attack_name and monster attack name; make messages appends them
to messages.pot (regenerated here).
- ru .po/.mo: translations for all catalog names; the hardcoded item list
in perception.py is removed.
- Combat panel weapon, inventory payload, ItemInfo and equipped names go
through gettext (English output unchanged).
- test_catalog_translations fails when a catalog name has no ru msgstr.
Owner
Author
|
Independent review: PASS
|
…-names-6w57du # Conflicts: # src/dnd_simulator/locale/messages.pot # src/dnd_simulator/locale/ru/LC_MESSAGES/dnd_simulator.mo
vladmesh
pushed a commit
that referenced
this pull request
Sep 29, 2026
make messages keeps both steps: pybabel extract for code msgids, then #84's catalog_messages appends the YAML catalog names. The catalog test expects the babel code msgids plus catalog_msgids(content) in the .pot. README keeps the gettext workflow and the containerized-stack section. Regenerated messages.pot, kept every ru translation from both sides, recompiled the .mo.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Card W3-3: issues 076f74d5fcf57a1a5f10 (remainder), e904083d3ff4ec37c275, da580696f20123039c1b (perception-hardcoded-weapons). Base: main @ 2f79530.
I checked all four items against main first. None of them was already fixed.
1. Raw ids in combat action-bar targets
Root cause.
TargetDropdown.buildTargetsbuilt its labels frome.id("Атаковать goblin_chieftain_5", "Говорить с npc_…"). Three other places did the same:DirectionalDropdown: move/dash toward and away from a target.targetName={smiteTargetId}.Fix. All of these now use
perceivedLabelsfrom #74, the same rule and helper as the Nearby panel. The label is the perceiveddescription(a stranger's race), then the known name, thenunknown_creature. Duplicate labels get an ordinal suffix. The id is still sent astarget_id, but it is never shown. I loosened thetparameter ofperceivedLabelsto a plain function type so the action-bar components can pass theirtprop.2–4. Item and attack names in RU
Root cause.
_()on item and attack names. But the ru.pohad no entries for most catalog items (Shield, Chain Mail, all armor, Rapier, Greatsword…), for any weaponattack_name, or for any monster attack name ("scimitar")._()list inperception.py. It also listed names no content uses (Handaxe, Javelin, Light Crossbow, Spear).self_weapon("Оружие: longsword slash"), the inventory payload,ItemInfo.name(loot/trade/consumables) and the equipped-items names.Fix. Instead of another hand-kept list, the catalogs themselves are the source:
New module
content_loader/catalog_messages.py.catalog_msgids()lists every translatable catalog string, with source references:nameattack_nameattacks[].nameMonster names are already
{en, ru}maps in the YAML, so they are not included.make messagesnow appends any missing catalog msgids tomessages.pot(with#: content/catalogs/...references). I regenerated the.potwith the tool. It had been stale since 2026-09-13, so its diff is large but fully generated.ru
.po/.mo: translations for all 50 catalog names, compiled withmake compile-messages.Hardcoded list: the item/weapon names are removed from
perception._TRANSLATABLE_STRINGS. Damage types, "AC" and the fallback labels stay there, because they are not catalog content.gettext applied to
self_weapon(awareness_builder),item_info().name,build_equippednames andbuild_inventory_payloadnames.English output is unchanged:
_()returns the msgid in EN, and the tests assert this.Tests
The frontend tests are in
ActionButton.test.tsx, "target labels never show internal ids". I verified that all 4 fail on main and pass with the fix:goblin_ids;I updated one existing assertion in
ActionBar.test.tsx. It expected the raw id in the smite menu (/Attack practice_thug$/), which is the bug itself, and now expectsAttack Thug.The backend tests are the new file
tests/unit/test_catalog_translations.py. I verified that 6 of them fail on main's code:.po(this is the guard that fails when a new catalog item or attack ships untranslated);.motranslates every catalog name;perception._TRANSLATABLE_STRINGSno longer hand-lists catalog names;item_infoand equipped names: EN unchanged, RU "Щит"/"Кольчуга";The other two test the new extractor, so they cannot run on main: it covers item, attack and monster-attack names, and it appends only missing msgids and is idempotent.
Checks
make checkis green: ruff, mypy, 2947 pytest, 357 vitest.make test-integrationcould not run. I rantests/integration/against a local backend with the docker-compose.test.yml settings (DND_DICE_SEED=42,DND_CONTENT_DIR=tests/integration/content,BACKEND_URL=http://localhost:8001): 184 passed.No new test revealed a separate bug.
Found but not fixed (out of scope)
content/catalogs. Inline names in world YAML, e.g.flail/clubinworlds/level_up_test/entities/npcs.yamlorlongswordintest_vale, still show in English. The same mechanism could extend to world/library YAML.describe_item()is English, machine-style text. Example: "Longsword (weapon: 1d8 slashing, reach 5ft)". It is shown as the item description in the inventory, loot and trade panels.RuleBrainand the frontendInventoryDrawermatch on the substrings "weapon"/"heal" in it, so localizing it needs those matches moved toitem_type/props first.make messagesdoes not pass--keyword=N_, so strings marked withN_()(about 87 call sites) are never extracted into the.pot..poentries: Handaxe, Javelin, Light Crossbow and Spear (from the removed list) are not used by any content. They are harmless and left in place.target.name. I did not check whether any monster name reaches the player without its localized value.