Skip to content

Add Italian locale (block.* keys) - #582

Merged
marceld23 merged 4 commits into
marceld23:mainfrom
alessandroquirino-lab:alessandroquirino-lab-patch-1
Jul 30, 2026
Merged

Add Italian locale (block.* keys)#582
marceld23 merged 4 commits into
marceld23:mainfrom
alessandroquirino-lab:alessandroquirino-lab-patch-1

Conversation

@alessandroquirino-lab

Copy link
Copy Markdown
Contributor

Introduced Italian translations for various game blocks to enhance localization and player experience.

What does this change?

Related issue

Checklist

  • I built and ran the tests before pushing (dotnet build BlocksBeyondTheStars.sln and dotnet test) — they pass.
  • Player-facing text is localized (keys in data/locales/{en,de}.json), not hardcoded.
  • The server stays authoritative — the client doesn't decide resources, inventory, crafting, ship state, oxygen, damage, blueprints or travel.
  • I updated TODO.md and any docs/ that my change makes stale (if applicable).

Introduced Italian translations for various game blocks to enhance localization and player experience.
@CLAassistant

CLAassistant commented Jul 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@alessandroquirino-lab

alessandroquirino-lab commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed split — that works great for me. 🙏

A couple of notes on this PR:

  • I couldn't run the tests locally (no PC at the moment), so I'm relying on CI.
  • All 290 block.* keys are in the same order as en.json, and this group contains no {0}-style placeholders, so nothing to preserve there.
  • The CLA isn't signed yet — it's being sorted out on my side, should be done shortly.

Happy to continue with the next key group once this one lands.

@marceld23 marceld23 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an excellent first PR — thank you! 🇮🇹

I went through the whole file against en.json:

Structure: flawless. Exactly 290/290 block.* keys (the group is complete), zero keys that don't exist in en.json, key order mirrors en.json exactly. Merging is safe on our side: the content loader only reads locale files for languages in the GameLocale enum, so it.json sits inert until my plumbing PR lands.

Translation quality: native-level. Idiomatic choices instead of literal ones ("Manto alieno", "Segnaletica da stiva"), correct disambiguation ("Scala a pioli" vs "Scalini"), the nautical "babordo/tribordo" for the port/starboard lights, and consistent phrasing across all the repeated description templates. Your terminology (trapano di livello 2/3, fibra vegetale, scheggia di cristallo, polvere di materia…) is now the reference glossary for the following groups — please keep using exactly these terms.

One tiny suggestion inline (non-blocking), and two things before I can merge:

  1. CLA — the license/cla check is waiting for your signature; just follow its link.
  2. CI build is still running (everything else is already green).

Next slice: I'd suggest item.* (342 keys) — it references exactly the terms from your glossary, so it's the natural continuation. After that we can split ui.* (1192 keys) into smaller chunks.

Best, Marcel

Comment thread data/locales/it.json Outdated
"block.heal_tank.desc": "Vasca di rigenerazione rilassante. Restando vicino recuperi lentamente salute, sazietà ed energia della tuta: il cuore di ogni base o stazione. Premi E per impostare qui il tuo punto di rinascita.",
"block.energy_fence.desc": "Pilone energetico ronzante. Le creature — selvatiche, addomesticate e ostili — non possono attraversarlo, quindi un anello di piloni forma un recinto sicuro o un muro di difesa. Le bestie volanti però lo scavalcano.",
"block.energy_gate.desc": "Membrana energetica per le aperture del recinto: i giocatori e gli abitanti degli insediamenti la attraversano, le creature restano fuori. Sempre attiva, non c'è nulla da aprire o chiudere.",
"block.factory_terminal.desc": "Il terminale di controllo di una fabbrica. Produci le sue ricette in blocco gratuitamente, oppure rivendica la fabbrica come base con un codice d'accesso SPS.",

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tiny nitpick: in a voxel game, "in blocco" reads ambiguously next to "blocco" (the block). "In serie" avoids the collision:

Suggested change
"block.factory_terminal.desc": "Il terminale di controllo di una fabbrica. Produci le sue ricette in blocco gratuitamente, oppure rivendica la fabbrica come base con un codice d'accesso SPS.",
"block.factory_terminal.desc": "Il terminale di controllo di una fabbrica. Produci le sue ricette in serie gratuitamente, oppure rivendica la fabbrica come base con un codice d'accesso SPS.",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch on "in blocco" — you're right, next to the actual blocks it reads ambiguously. Fixed to "in serie" and pushed. I also re-validated the JSON and re-checked that all 290 keys are still in the same order as en.json.

Added "in serie" to the glossary for the following groups.

On the CLA: I should be able to get it signed within a day or so — sorting it out on my side. Sorry for the small delay.

Happy to start on item.* after that.

@marceld23

Copy link
Copy Markdown
Owner

Hi Alessandro — one process note about the CLA, then we're good to go. 🙂

Let me say this openly and without any drama: I genuinely don't mind how a contribution gets written. Typed by hand, with a dictionary next to you, with an AI assistant helping out — for a locale file the only two things I care about are that the Italian reads native (yours does) and that the text is yours to give.

The CLA is exactly where that second part lives, and it's why it can't be delegated to a tool. It's a legal agreement, so it has to be accepted by you, personally, as the human behind the account. Signing it means you're confirming that the strings in this PR are yours to contribute — that you wrote them (or directed whatever helped you write them), and that they weren't lifted from another game, another project, or a translation someone else holds the rights to. No tool can make that promise on your behalf; only a person can. That's not a rule I invented for you, it applies to every contributor here, me included.

Practically it takes about a minute and doesn't need a PC — open the CLA link on your phone, log in with GitHub, confirm. The check goes green by itself shortly after.

And if any of the lines did come from somewhere else: just tell me. Honestly, no problem — we swap those out and merge the rest. Much easier now than later.

Looking forward to getting this one in and moving on to item.*.

Best, Marcel

@alessandroquirino-lab

Copy link
Copy Markdown
Contributor Author

Thanks for explaining it so clearly — that makes sense, and nothing here came from another game or an existing translation. The Italian was written from scratch for this project, and the terminology choices are mine.

The "in serie" fix is pushed and the JSON re-validated.

The CLA will be handled properly on our side — it just needs the account holder to do it personally, as you said. Should be done shortly.

Also: I'm back at my desktop tonight, so from the next PR on I'll be able to build and run dotnet test locally before pushing instead of relying on CI.

@alessandroquirino-lab

Copy link
Copy Markdown
Contributor Author

CLA is signed now — the check should turn green shortly.

Everything on this PR should be ready from my side. Let me know if you'd like anything else changed before merging, otherwise I'll get started on item.* next.

@marceld23 marceld23 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — thank you, Alessandro! 🇮🇹

I checked the file mechanically against en.json on current main:

  • 290 keys, all block.*, zero orphans (every key exists in en.json)
  • key order mirrors en.json exactly — future diffs will stay readable
  • no placeholders in this group, no empty values, no leftover English
  • the two values identical to English (block.lava.name, block.flora_cactus.name) are correct that way in Italian

Squashing this in now.

@marceld23
marceld23 merged commit 078d71b into marceld23:main Jul 30, 2026
12 checks passed
@marceld23

Copy link
Copy Markdown
Owner

Merged. 🎉 Italian is now in the repository — the first new language since the game shipped, and the first one contributed from outside the family. Thank you, Alessandro.

A few things I want to say properly, because this one matters to me:

The file was clean. Not "good enough for a volunteer" clean — actually clean. 290 keys, correct order, zero invented keys, nothing left in English, and the two entries that look untranslated (Lava, Cactus) are simply the same word in Italian. I ran the whole thing against en.json mechanically and had nothing to report back. That is rarer than you'd think, and it made this a one-click merge.

I also appreciate how you handled the CLA. You didn't get defensive about it, you just went and did it, and then you told me plainly where the text came from. That's exactly the kind of thing that makes a maintainer relax.

Two tiny leftovers, and they're my fault, not yours: while this PR was open, main grew by 83 keys (a big playtest batch landed), two of them in your group — block.torch.name ("Torch") and block.door_wood.name ("Wooden Door"). I deliberately did not ask you to add them first, because it would have cost you a round-trip for two words and the same drift would just happen again during the next group. Grab them whenever it suits you — with your item.* PR is perfect. Nothing breaks in the meantime: missing keys fall back to English per key.

What I'm doing on my side, starting now:

  1. Making Italian actually load. Right now it.json sits in the repo and the game ignores it, because the language enum only knows en/de. I'm adding Italian this week, plus the file needs to be added to the client's asset manifest (otherwise the browser build never sees it). Point is: you should be able to see your own strings in the game long before the language is officially announced — that seems only fair.
  2. A coverage tool (tools/locale_report.py) that prints per-group translation coverage and lists exactly which keys are missing or drifted. That's the drift problem solved properly instead of me eyeballing it each time — and it gives you a reliable way to pick your next batch instead of guessing.
  3. A CI guard so any future locale PR is automatically checked for invented keys and mismatched {0} placeholders. Protects you as much as me: you'll get told by the machine, not by me in review.

And you're going in the credits — the README contributor list and the in-game Credits screen, alongside Cora, Maqbool, Devin and SpaleRuby. That ships in the same PR as the plumbing. If you'd like a different name or handle shown there than alessandroquirino-lab, just say so and I'll use whatever you prefer.

On item.* (346 keys): good pick, same mechanical shape as block.*. Two heads-ups before you start:

  • Some item.* entries do contain {0}-style placeholders — please keep them intact and in a position that reads naturally in Italian. Word order may move; the placeholder moves with it.
  • Feel free to split it. 346 keys in one PR is fine by me, but two PRs of ~170 are easier for you to finish in one sitting and easier for me to turn around fast. Your call entirely.

After item.* I'd love to steer you toward the core UI (ui.menu, ui.settings, ui.hud, ui.craft, hud.* — roughly 200 keys together), because that's the set that decides when I can switch "Italiano" on in the settings menu for real players. There's also a large ui.portal.* group (145), but that's the website, not the game — I want to verify it reads the same files before I ask anyone to spend an evening on it.

Also glad to hear you're back at your desktop. Being able to run dotnet test locally will make this faster for you, though honestly: for pure locale files, CI has you covered.

Thanks again — and welcome aboard properly. 🙂

Best, Marcel

marceld23 added a commit that referenced this pull request Jul 30, 2026
…) (#622)

@alessandroquirino-lab contributed data/locales/it.json (290 block.* keys, #582) — and the
game ignored the file, because DE/EN was baked into the enum, the server and the client.

Shared/loader:
- GameLocale.Italian + Code() "it" + TryParse ("it", "it-it", "italian", "italiano"), plus a
  Parse(string?) helper replacing the `== "de" ? German : English` pattern that could never see
  a third language. ContentLoader already enumerates the enum and skips absent files, so the
  loader itself needed no change — and a world shipped without it.json still starts.

Client:
- GameBootstrap.Locale (a GameLocale) drives every key-based text and the join locale.
  Deliberately [NonSerialized]: a scene-baked value would override what WorldRig assigns from
  the player's settings (the Launcher.unity PlayerName trap).
- bool German stays, but only for the surfaces that ship DE/EN *content* instead of locale
  keys: the embedded wiki, minigames, arcade, terms text, What's new. Those read English for a
  third language, which is the documented per-key fallback.
- StreamingAssetsCache's fallback manifest listed only locales/{de,en}.json. The build-time
  manifest enumerates the folder, so this only bites a build without manifest.json — fixed
  anyway, since a silently unfetchable language is worse than a redundant entry.
- The settings control stays a DE/EN toggle but now shows the ACTIVE code, so a hand-set "IT"
  is displayed honestly. Italian joins the picker once coverage clears the bar.

Server:
- NormalizeLocale delegates to GameLocale, so "it" survives into PlayerSession.Locale and
  reaches the existing Localize(locale, key) path instead of being flattened to "en". The 13
  `bool de` gates are untouched on purpose — converting them belongs with #427 S20.

Guards + tooling:
- CommunityLocaleTests: for every non-DE/EN locale — no invented keys, {0}/{item} placeholder
  parity, no blank values (a blank SHADOWS the English fallback and renders as empty UI), no
  locale file without an enum member, plus a loader round-trip. Explicitly does NOT demand
  completeness: translating group by group is the point. Verified by injecting all three
  defect types and checking each failure names the offending keys.
- tools/locale_report.py: coverage per language and key group, --missing GROUP prints the
  untranslated keys with their English text, --markdown, --check. locale-report.yml posts the
  table to the CI job summary (not a PR comment: locale PRs come from forks, where the token
  is read-only and commenting would need pull_request_target).

Credits: Alessandro added to README and the in-game Credits screen (en + de).

Coverage today: it 290/2271 (12.8 %); block 290/292 — block.torch.name and
block.door_wood.name arrived in #618 while #582 was open.

Co-authored-by: Claude Opus 5 <[email protected]>
@marceld23

Copy link
Copy Markdown
Owner

Thanks again for this one, @alessandroquirino-lab — 290 clean block.* keys, and the engine side is
now in place too: #622 added GameLocale.Italian, so it.json is loaded automatically and every key
you haven't translated yet falls back to English at runtime.

To keep the work in one place I opened #625 as the tracking issue for the remaining key groups:
a checkbox list in a suggested order (item.* next), the current coverage table, the translation
rules, and the tools/locale_report.py it --missing item command that prints every untranslated key
with its English text.

Drop a comment there when you pick up the next group and I'll assign it to you. 🇮🇹

marceld23 added a commit that referenced this pull request Jul 30, 2026
Cuts [Unreleased] into [2026.7.24] "the long-view release" and adds the three
items that landed since the 2026.7.23 tag without a changelog entry: binoculars
plus the thermal upgrade (#629, #630), greenhouses in settlements and stations
(#626-#628) and the flight chart's drawn orbital paths + click-position fix
(#623). The Italian plumbing (#99, #582) and the portal accessibility pass
(#574) were already sitting in [Unreleased] and move into the release as-is.

data/whatsnew.json is re-exported from the DE+EN devblog release posts (18
entries now) so the in-game "What's new?" feed carries 2026.7.24 before the tag
is pushed, as AGENTS.md requires. The date stays empty until the posts go live.

TODO.md: the thermal-vision work log documented the toggle as N; the shipped
default is I (N is the VEGA dialogue advance).

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
marceld23 pushed a commit that referenced this pull request Jul 31, 2026
…keys (#625) (#645)

Adds 183 keys to it.json:

- item.*: the first 177 keys (of 354), in en.json order — tools, suit gear,
  weapons, raw materials, ores, ingots and refined goods.
- block.*: the 6 keys still missing, which completes the group at 296/296 —
  block.flora_cropberry.*, block.hydro_tray.*, block.torch.name and
  block.door_wood.name.

Terminology follows the reference glossary agreed in #582 (trapano, fibra
vegetale, polvere di materia, Roccia madre, Ardesia profonda, babordo/tribordo,
"in serie" and never "in blocco"). Item names reuse the exact wording already
used for the matching block, so the two groups stay consistent.

Verified with tools/locale_report.py: no hard defects, key order mirrors
en.json, no invented or blank keys, no placeholder changes.

Co-authored-by: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants