Skip to content

Conversation

@Aotumuri
Copy link
Member

Description:

Add {team_count} to public lobby team size translations so word order stays correct across languages.

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory
  • I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced

Please put your Discord username so you can be contacted if a bug or regression is found:

aotumuri

@Aotumuri Aotumuri requested a review from a team as a code owner December 23, 2025 06:11
@CLAassistant
Copy link

CLAassistant commented Dec 23, 2025

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ iiamlewis
❌ Aotumuri
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

Walkthrough

Public-lobby team labels were changed to use a {team_count} placeholder in translations and PublicLobby.getTeamDetailLabel was refactored to return { label: string | null; isFullLabel: boolean }; call sites were updated to destructure and use isFullLabel when composing final labels. (34 words)

Changes

Cohort / File(s) Summary
Localization strings
resources/lang/en.json
Replaced static team-size strings with parameterized forms: public_lobby.teams_Duos, public_lobby.teams_Trios, public_lobby.teams_Quads now use "{team_count} of 2 (Duos)", "{team_count} of 3 (Trios)", "{team_count} of 4 (Quads)".
Team label rendering logic
src/client/PublicLobby.ts
getTeamDetailLabel signature changed to return { label: string | null; isFullLabel: boolean }; branches updated to produce that shape and render() adjusted to destructure { label: teamDetailLabel, isFullLabel } and compute composed labels conditionally.

Sequence Diagram(s)

(No sequence diagrams generated — changes are localized to i18n strings and a small rendering return-shape change.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

UI/UX

Suggested reviewers

  • evanpelle

Poem

A placeholder finds its place,
labels tidy, logic clear,
functions now return with grace,
strings await the number near,
🎉

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix public lobby team labels with team_count placeholder' directly and clearly describes the main change: adding a {team_count} placeholder to team label translations.
Description check ✅ Passed The description clearly relates to the changeset, explaining the purpose (correct word order across languages), mentioning the required translation additions, and confirming testing and process compliance.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5748300 and 8b7e84a.

📒 Files selected for processing (2)
  • resources/lang/en.json
  • src/client/PublicLobby.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • resources/lang/en.json
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: TheGiraffe3
Repo: openfrontio/OpenFrontIO PR: 884
File: resources/lang/en.json:456-461
Timestamp: 2025-08-16T10:52:08.292Z
Learning: In OpenFrontIO, translation files in resources/lang/*.json (except en.json) should not be updated in regular PRs. Only dedicated translation PRs titled "mls" and made by Aotumori should update non-English locale files. Regular PRs should only update en.json when adding or modifying translation keys.
Learnt from: andrewNiziolek
Repo: openfrontio/OpenFrontIO PR: 1007
File: resources/lang/de.json:115-115
Timestamp: 2025-06-02T14:27:37.609Z
Learning: For OpenFrontIO project: When localization keys are renamed in language JSON files, the maintainers separate technical changes from translation content updates. They wait for community translators to update the actual translation values rather than attempting to translate in the same PR. This allows technical changes to proceed while ensuring accurate translations from native speakers.
Learnt from: FloPinguin
Repo: openfrontio/OpenFrontIO PR: 2689
File: src/client/PublicLobby.ts:245-245
Timestamp: 2025-12-26T22:21:21.904Z
Learning: In public lobbies with HumansVsNations mode in src/client/PublicLobby.ts, maxPlayers represents only human player slots (already halved in DefaultConfig.ts). The nation NPCs are added automatically server-side and don't count toward maxPlayers. Therefore, getTeamSize correctly returns maxPlayers directly for HumansVsNations to display the proper team size (e.g., maxPlayers=5 yields "5 Humans vs 5 Nations").
Learnt from: GlacialDrift
Repo: openfrontio/OpenFrontIO PR: 2298
File: src/client/graphics/layers/TerritoryLayer.ts:200-210
Timestamp: 2025-10-26T15:37:07.732Z
Learning: In GameImpl.ts lines 124-139, team assignment logic varies by number of teams: when numPlayerTeams < 8, teams are assigned ColoredTeams values (Red, Blue, Yellow, Green, Purple, Orange, Teal); when numPlayerTeams >= 8, teams are assigned generic string identifiers like "Team 1", "Team 2", etc., which are not members of ColoredTeams.
Learnt from: Ble4Ch
Repo: openfrontio/OpenFrontIO PR: 1063
File: src/core/configuration/PastelThemeDark.ts:53-53
Timestamp: 2025-06-10T09:56:44.473Z
Learning: In ColorAllocator class in src/core/configuration/Colors.ts, the correct method names are assignColor(id: string): Colord for general color assignment and assignTeamColor(team: Team): Colord for team-specific colors. There are no assignPlayerColor() or assignBotColor() methods.
📚 Learning: 2025-12-26T22:21:21.904Z
Learnt from: FloPinguin
Repo: openfrontio/OpenFrontIO PR: 2689
File: src/client/PublicLobby.ts:245-245
Timestamp: 2025-12-26T22:21:21.904Z
Learning: In public lobbies with HumansVsNations mode in src/client/PublicLobby.ts, maxPlayers represents only human player slots (already halved in DefaultConfig.ts). The nation NPCs are added automatically server-side and don't count toward maxPlayers. Therefore, getTeamSize correctly returns maxPlayers directly for HumansVsNations to display the proper team size (e.g., maxPlayers=5 yields "5 Humans vs 5 Nations").

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-10-26T15:37:07.732Z
Learnt from: GlacialDrift
Repo: openfrontio/OpenFrontIO PR: 2298
File: src/client/graphics/layers/TerritoryLayer.ts:200-210
Timestamp: 2025-10-26T15:37:07.732Z
Learning: In GameImpl.ts lines 124-139, team assignment logic varies by number of teams: when numPlayerTeams < 8, teams are assigned ColoredTeams values (Red, Blue, Yellow, Green, Purple, Orange, Teal); when numPlayerTeams >= 8, teams are assigned generic string identifiers like "Team 1", "Team 2", etc., which are not members of ColoredTeams.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-06-10T09:56:44.473Z
Learnt from: Ble4Ch
Repo: openfrontio/OpenFrontIO PR: 1063
File: src/core/configuration/PastelThemeDark.ts:53-53
Timestamp: 2025-06-10T09:56:44.473Z
Learning: In ColorAllocator class in src/core/configuration/Colors.ts, the correct method names are assignColor(id: string): Colord for general color assignment and assignTeamColor(team: Team): Colord for team-specific colors. There are no assignPlayerColor() or assignBotColor() methods.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-10-21T20:06:04.823Z
Learnt from: Saphereye
Repo: openfrontio/OpenFrontIO PR: 2233
File: src/client/HostLobbyModal.ts:891-891
Timestamp: 2025-10-21T20:06:04.823Z
Learning: For the HumansVsNations game mode in `src/client/HostLobbyModal.ts` and related files, the implementation strategy is to generate all nations and adjust their strength for balancing, rather than limiting lobby size based on the number of available nations on the map.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/PublicLobby.ts
🧬 Code graph analysis (1)
src/client/PublicLobby.ts (3)
src/core/game/Game.ts (1)
  • HumansVsNations (56-56)
src/client/Utils.ts (1)
  • translateText (92-147)
src/client/LangSelector.ts (1)
  • translateText (258-278)
🔇 Additional comments (4)
src/client/PublicLobby.ts (4)

100-114: Clean refactor with clear comment.

The comment at line 100 explains the purpose of isFullLabel well. The destructuring with aliases is idiomatic, and the conditional logic for building fullModeLabel is straightforward and easy to follow.


258-261: Return type is well-defined.

Using a typed object { label: string | null; isFullLabel: boolean } is a clean approach. This is better than using a tuple or multiple return values since the property names make the intent clear at call sites.


267-276: Translation fallback detection is correct.

The check maybeTranslated !== teamKey correctly identifies when a translation exists, since translateText returns the key itself when no translation is found. The comment at line 269 helps future readers understand this behavior.


278-288: Fallback logic is well-structured.

The fallback at lines 280-285 correctly returns isFullLabel: false since the players_per_team translation needs to be concatenated with the mode label. The comment at line 279 makes the intent clear. All return paths now consistently use the object shape.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Aotumuri Aotumuri added the Translation Addition or modification of a language to the translations. label Dec 23, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 23, 2025
Duwibi
Duwibi previously approved these changes Dec 23, 2025
@iiamlewis iiamlewis moved this from Triage to Final Review in OpenFront Release Management Dec 23, 2025
@iiamlewis iiamlewis added this to the v29 milestone Dec 23, 2025
@Aotumuri Aotumuri dismissed stale reviews from Duwibi and coderabbitai[bot] via 9401a1f December 28, 2025 01:08
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/client/PublicLobby.ts (1)

147-151: Label combination logic is correct.

The conditional logic properly combines mode and team detail labels based on the isFullLabel flag. Full labels stand alone, while partial labels get the mode prepended.

The nested ternary is readable, though you could optionally extract it into a helper function if the team decides that improves clarity.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4f83e6 and 9401a1f.

📒 Files selected for processing (2)
  • resources/lang/en.json
  • src/client/PublicLobby.ts
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: TheGiraffe3
Repo: openfrontio/OpenFrontIO PR: 884
File: resources/lang/en.json:456-461
Timestamp: 2025-08-16T10:52:08.292Z
Learning: In OpenFrontIO, translation files in resources/lang/*.json (except en.json) should not be updated in regular PRs. Only dedicated translation PRs titled "mls" and made by Aotumori should update non-English locale files. Regular PRs should only update en.json when adding or modifying translation keys.
Learnt from: andrewNiziolek
Repo: openfrontio/OpenFrontIO PR: 1007
File: resources/lang/de.json:115-115
Timestamp: 2025-06-02T14:27:37.609Z
Learning: For OpenFrontIO project: When localization keys are renamed in language JSON files, the maintainers separate technical changes from translation content updates. They wait for community translators to update the actual translation values rather than attempting to translate in the same PR. This allows technical changes to proceed while ensuring accurate translations from native speakers.
Learnt from: FloPinguin
Repo: openfrontio/OpenFrontIO PR: 2689
File: src/client/PublicLobby.ts:245-245
Timestamp: 2025-12-26T22:21:15.466Z
Learning: In public lobbies with HumansVsNations mode in src/client/PublicLobby.ts, maxPlayers represents only human player slots (already halved in DefaultConfig.ts). The nation NPCs are added automatically server-side and don't count toward maxPlayers. Therefore, getTeamSize correctly returns maxPlayers directly for HumansVsNations to display the proper team size (e.g., maxPlayers=5 yields "5 Humans vs 5 Nations").
Learnt from: GlacialDrift
Repo: openfrontio/OpenFrontIO PR: 2298
File: src/client/graphics/layers/TerritoryLayer.ts:200-210
Timestamp: 2025-10-26T15:37:07.732Z
Learning: In GameImpl.ts lines 124-139, team assignment logic varies by number of teams: when numPlayerTeams < 8, teams are assigned ColoredTeams values (Red, Blue, Yellow, Green, Purple, Orange, Teal); when numPlayerTeams >= 8, teams are assigned generic string identifiers like "Team 1", "Team 2", etc., which are not members of ColoredTeams.
Learnt from: Saphereye
Repo: openfrontio/OpenFrontIO PR: 2233
File: src/client/HostLobbyModal.ts:891-891
Timestamp: 2025-10-21T20:06:04.823Z
Learning: For the HumansVsNations game mode in `src/client/HostLobbyModal.ts` and related files, the implementation strategy is to generate all nations and adjust their strength for balancing, rather than limiting lobby size based on the number of available nations on the map.
📚 Learning: 2025-12-26T22:21:15.466Z
Learnt from: FloPinguin
Repo: openfrontio/OpenFrontIO PR: 2689
File: src/client/PublicLobby.ts:245-245
Timestamp: 2025-12-26T22:21:15.466Z
Learning: In public lobbies with HumansVsNations mode in src/client/PublicLobby.ts, maxPlayers represents only human player slots (already halved in DefaultConfig.ts). The nation NPCs are added automatically server-side and don't count toward maxPlayers. Therefore, getTeamSize correctly returns maxPlayers directly for HumansVsNations to display the proper team size (e.g., maxPlayers=5 yields "5 Humans vs 5 Nations").

Applied to files:

  • resources/lang/en.json
  • src/client/PublicLobby.ts
📚 Learning: 2025-10-26T15:37:07.732Z
Learnt from: GlacialDrift
Repo: openfrontio/OpenFrontIO PR: 2298
File: src/client/graphics/layers/TerritoryLayer.ts:200-210
Timestamp: 2025-10-26T15:37:07.732Z
Learning: In GameImpl.ts lines 124-139, team assignment logic varies by number of teams: when numPlayerTeams < 8, teams are assigned ColoredTeams values (Red, Blue, Yellow, Green, Purple, Orange, Teal); when numPlayerTeams >= 8, teams are assigned generic string identifiers like "Team 1", "Team 2", etc., which are not members of ColoredTeams.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-06-10T09:56:44.473Z
Learnt from: Ble4Ch
Repo: openfrontio/OpenFrontIO PR: 1063
File: src/core/configuration/PastelThemeDark.ts:53-53
Timestamp: 2025-06-10T09:56:44.473Z
Learning: In ColorAllocator class in src/core/configuration/Colors.ts, the correct method names are assignColor(id: string): Colord for general color assignment and assignTeamColor(team: Team): Colord for team-specific colors. There are no assignPlayerColor() or assignBotColor() methods.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-10-21T20:06:04.823Z
Learnt from: Saphereye
Repo: openfrontio/OpenFrontIO PR: 2233
File: src/client/HostLobbyModal.ts:891-891
Timestamp: 2025-10-21T20:06:04.823Z
Learning: For the HumansVsNations game mode in `src/client/HostLobbyModal.ts` and related files, the implementation strategy is to generate all nations and adjust their strength for balancing, rather than limiting lobby size based on the number of available nations on the map.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/PublicLobby.ts
🧬 Code graph analysis (1)
src/client/PublicLobby.ts (3)
src/core/game/Game.ts (1)
  • HumansVsNations (56-56)
src/client/LangSelector.ts (1)
  • translateText (258-278)
src/client/Utils.ts (1)
  • translateText (92-147)
🔇 Additional comments (3)
resources/lang/en.json (1)

272-274: Nice i18n improvement with dynamic team count placeholders.

Adding the {team_count} placeholder enables different word orders across languages, which is essential for proper localization. The consistent naming pattern (teams_Duos, teams_Trios, teams_Quads) aligns well with the code usage in PublicLobby.ts.

Based on learnings, correctly updating only en.json in this regular PR.

src/client/PublicLobby.ts (2)

139-145: Clean destructuring with clear variable naming.

The destructuring correctly handles the new return type, and renaming isFullLabel to isTeamDetailFullLabel avoids potential naming confusion with the local usage context.


285-310: Well-structured refactor with clear control flow.

The new return type { label: string | null; isFullLabel: boolean } cleanly separates concerns:

  • The label carries the text
  • The isFullLabel flag indicates whether it needs mode prepending

The logic flow is sound:

  1. Early return for non-Team modes
  2. Try new translation pattern for named team modes (Duos/Trios/Quads)
  3. Fall back to generic "of {num}" pattern
  4. Default to null

The fallback (lines 300-307) is appropriate for custom numeric team counts and cases where translations don't exist yet.

Minor note: Line 293 uses teamTotal ?? 0 as a safety fallback. For the named team modes (Duos/Trios/Quads), teamTotal should always be calculated from maxPlayers / teamSize, so the fallback to 0 shouldn't trigger in practice. Still, it prevents potential "0 of 2 (Duos)" displays if something unexpected happens upstream.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 28, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
src/client/PublicLobby.ts (3)

140-146: Add a comment explaining isTeamDetailFullLabel.

Per previous review feedback, add a comment explaining what isTeamDetailFullLabel represents. This flag determines whether the team detail label is complete on its own or needs to be combined with the mode label.


148-152: Replace nested ternary with if/else statements.

Per previous review feedback, the nested ternary operator is hard to reason about. Refactor to use if/else statements for clarity.

🔎 Proposed refactor using if/else
-    const fullModeLabel = teamDetailLabel
-      ? isTeamDetailFullLabel
-        ? teamDetailLabel
-        : `${modeLabel} ${teamDetailLabel}`
-      : modeLabel;
+    let fullModeLabel: string;
+    if (teamDetailLabel) {
+      if (isTeamDetailFullLabel) {
+        fullModeLabel = teamDetailLabel;
+      } else {
+        fullModeLabel = `${modeLabel} ${teamDetailLabel}`;
+      }
+    } else {
+      fullModeLabel = modeLabel;
+    }

298-317: Add comments explaining translation logic and fallback behavior.

Per previous review feedback, add comments explaining:

  1. Why maybeTranslated may fail (line 300): The translation key may not exist in the language file, causing translateText to return the key itself.
  2. Why we fall back (line 309): When the string-based team translation is missing or when teamTotal/teamSize are undefined, we fall back to the generic "X players per team" format.
🔎 Proposed comments
     if (typeof teamCount === "string") {
       const teamKey = `public_lobby.teams_${teamCount}`;
+      // Try to translate team size labels like "Duos", "Trios", etc.
+      // If the translation key doesn't exist, translateText returns the key itself
       const maybeTranslated = translateText(teamKey, {
         team_count: teamTotal ?? 0,
       });
       if (maybeTranslated !== teamKey) {
         return { label: maybeTranslated, isFullLabel: true };
       }
     }
 
+    // Fallback: use generic "X players per team" format when string-based
+    // translations are missing or when we have numeric team configuration
     if (teamTotal !== undefined && teamSize !== undefined) {
       return {
         label: translateText("public_lobby.players_per_team", {
           num: teamSize,
         }),
         isFullLabel: false,
       };
     }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9401a1f and d5716e2.

📒 Files selected for processing (2)
  • resources/lang/en.json
  • src/client/PublicLobby.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • resources/lang/en.json
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: TheGiraffe3
Repo: openfrontio/OpenFrontIO PR: 884
File: resources/lang/en.json:456-461
Timestamp: 2025-08-16T10:52:08.292Z
Learning: In OpenFrontIO, translation files in resources/lang/*.json (except en.json) should not be updated in regular PRs. Only dedicated translation PRs titled "mls" and made by Aotumori should update non-English locale files. Regular PRs should only update en.json when adding or modifying translation keys.
Learnt from: andrewNiziolek
Repo: openfrontio/OpenFrontIO PR: 1007
File: resources/lang/de.json:115-115
Timestamp: 2025-06-02T14:27:37.609Z
Learning: For OpenFrontIO project: When localization keys are renamed in language JSON files, the maintainers separate technical changes from translation content updates. They wait for community translators to update the actual translation values rather than attempting to translate in the same PR. This allows technical changes to proceed while ensuring accurate translations from native speakers.
Learnt from: FloPinguin
Repo: openfrontio/OpenFrontIO PR: 2689
File: src/client/PublicLobby.ts:245-245
Timestamp: 2025-12-26T22:21:15.466Z
Learning: In public lobbies with HumansVsNations mode in src/client/PublicLobby.ts, maxPlayers represents only human player slots (already halved in DefaultConfig.ts). The nation NPCs are added automatically server-side and don't count toward maxPlayers. Therefore, getTeamSize correctly returns maxPlayers directly for HumansVsNations to display the proper team size (e.g., maxPlayers=5 yields "5 Humans vs 5 Nations").
Learnt from: GlacialDrift
Repo: openfrontio/OpenFrontIO PR: 2298
File: src/client/graphics/layers/TerritoryLayer.ts:200-210
Timestamp: 2025-10-26T15:37:07.732Z
Learning: In GameImpl.ts lines 124-139, team assignment logic varies by number of teams: when numPlayerTeams < 8, teams are assigned ColoredTeams values (Red, Blue, Yellow, Green, Purple, Orange, Teal); when numPlayerTeams >= 8, teams are assigned generic string identifiers like "Team 1", "Team 2", etc., which are not members of ColoredTeams.
Learnt from: Ble4Ch
Repo: openfrontio/OpenFrontIO PR: 1063
File: src/core/configuration/PastelThemeDark.ts:53-53
Timestamp: 2025-06-10T09:56:44.473Z
Learning: In ColorAllocator class in src/core/configuration/Colors.ts, the correct method names are assignColor(id: string): Colord for general color assignment and assignTeamColor(team: Team): Colord for team-specific colors. There are no assignPlayerColor() or assignBotColor() methods.
📚 Learning: 2025-12-26T22:21:15.466Z
Learnt from: FloPinguin
Repo: openfrontio/OpenFrontIO PR: 2689
File: src/client/PublicLobby.ts:245-245
Timestamp: 2025-12-26T22:21:15.466Z
Learning: In public lobbies with HumansVsNations mode in src/client/PublicLobby.ts, maxPlayers represents only human player slots (already halved in DefaultConfig.ts). The nation NPCs are added automatically server-side and don't count toward maxPlayers. Therefore, getTeamSize correctly returns maxPlayers directly for HumansVsNations to display the proper team size (e.g., maxPlayers=5 yields "5 Humans vs 5 Nations").

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-10-26T15:37:07.732Z
Learnt from: GlacialDrift
Repo: openfrontio/OpenFrontIO PR: 2298
File: src/client/graphics/layers/TerritoryLayer.ts:200-210
Timestamp: 2025-10-26T15:37:07.732Z
Learning: In GameImpl.ts lines 124-139, team assignment logic varies by number of teams: when numPlayerTeams < 8, teams are assigned ColoredTeams values (Red, Blue, Yellow, Green, Purple, Orange, Teal); when numPlayerTeams >= 8, teams are assigned generic string identifiers like "Team 1", "Team 2", etc., which are not members of ColoredTeams.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-06-10T09:56:44.473Z
Learnt from: Ble4Ch
Repo: openfrontio/OpenFrontIO PR: 1063
File: src/core/configuration/PastelThemeDark.ts:53-53
Timestamp: 2025-06-10T09:56:44.473Z
Learning: In ColorAllocator class in src/core/configuration/Colors.ts, the correct method names are assignColor(id: string): Colord for general color assignment and assignTeamColor(team: Team): Colord for team-specific colors. There are no assignPlayerColor() or assignBotColor() methods.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-10-21T20:06:04.823Z
Learnt from: Saphereye
Repo: openfrontio/OpenFrontIO PR: 2233
File: src/client/HostLobbyModal.ts:891-891
Timestamp: 2025-10-21T20:06:04.823Z
Learning: For the HumansVsNations game mode in `src/client/HostLobbyModal.ts` and related files, the implementation strategy is to generate all nations and adjust their strength for balancing, rather than limiting lobby size based on the number of available nations on the map.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/PublicLobby.ts
🧬 Code graph analysis (1)
src/client/PublicLobby.ts (3)
src/core/game/Game.ts (1)
  • HumansVsNations (56-56)
src/client/LangSelector.ts (1)
  • translateText (258-278)
src/client/Utils.ts (1)
  • translateText (92-147)
🪛 GitHub Actions: 🧪 CI
src/client/PublicLobby.ts

[error] 295-295: TypeScript error during build-prod: TS2322: Type 'null' is not assignable to type '{ label: string | null; isFullLabel: boolean; }'.

@github-project-automation github-project-automation bot moved this from Final Review to Development in OpenFront Release Management Dec 29, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/client/PublicLobby.ts (1)

296-298: Fix TypeScript type error: return object instead of null.

The function signature requires returning { label: string | null; isFullLabel: boolean }, but this branch returns null directly. This causes the TypeScript compilation error shown in the pipeline failure.

🔎 Proposed fix
 if (typeof teamCount === "string" && teamCount === HumansVsNations) {
-  return null;
+  return { label: null, isFullLabel: false };
 }
🧹 Nitpick comments (1)
src/client/PublicLobby.ts (1)

149-154: Consider using full if/else statements for clarity.

The nested ternary inside the if statement works, but pure if/else statements would be easier to read and maintain.

🔎 Proposed refactor
 let fullModeLabel = modeLabel;
 if (teamDetailLabel) {
-  fullModeLabel = isTeamDetailFullLabel
-    ? teamDetailLabel
-    : `${modeLabel} ${teamDetailLabel}`;
+  if (isTeamDetailFullLabel) {
+    fullModeLabel = teamDetailLabel;
+  } else {
+    fullModeLabel = `${modeLabel} ${teamDetailLabel}`;
+  }
 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d5716e2 and edd85ee.

📒 Files selected for processing (1)
  • src/client/PublicLobby.ts
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: TheGiraffe3
Repo: openfrontio/OpenFrontIO PR: 884
File: resources/lang/en.json:456-461
Timestamp: 2025-08-16T10:52:08.292Z
Learning: In OpenFrontIO, translation files in resources/lang/*.json (except en.json) should not be updated in regular PRs. Only dedicated translation PRs titled "mls" and made by Aotumori should update non-English locale files. Regular PRs should only update en.json when adding or modifying translation keys.
Learnt from: andrewNiziolek
Repo: openfrontio/OpenFrontIO PR: 1007
File: resources/lang/de.json:115-115
Timestamp: 2025-06-02T14:27:37.609Z
Learning: For OpenFrontIO project: When localization keys are renamed in language JSON files, the maintainers separate technical changes from translation content updates. They wait for community translators to update the actual translation values rather than attempting to translate in the same PR. This allows technical changes to proceed while ensuring accurate translations from native speakers.
Learnt from: FloPinguin
Repo: openfrontio/OpenFrontIO PR: 2689
File: src/client/PublicLobby.ts:245-245
Timestamp: 2025-12-26T22:21:15.466Z
Learning: In public lobbies with HumansVsNations mode in src/client/PublicLobby.ts, maxPlayers represents only human player slots (already halved in DefaultConfig.ts). The nation NPCs are added automatically server-side and don't count toward maxPlayers. Therefore, getTeamSize correctly returns maxPlayers directly for HumansVsNations to display the proper team size (e.g., maxPlayers=5 yields "5 Humans vs 5 Nations").
Learnt from: GlacialDrift
Repo: openfrontio/OpenFrontIO PR: 2298
File: src/client/graphics/layers/TerritoryLayer.ts:200-210
Timestamp: 2025-10-26T15:37:07.732Z
Learning: In GameImpl.ts lines 124-139, team assignment logic varies by number of teams: when numPlayerTeams < 8, teams are assigned ColoredTeams values (Red, Blue, Yellow, Green, Purple, Orange, Teal); when numPlayerTeams >= 8, teams are assigned generic string identifiers like "Team 1", "Team 2", etc., which are not members of ColoredTeams.
📚 Learning: 2025-12-26T22:21:15.466Z
Learnt from: FloPinguin
Repo: openfrontio/OpenFrontIO PR: 2689
File: src/client/PublicLobby.ts:245-245
Timestamp: 2025-12-26T22:21:15.466Z
Learning: In public lobbies with HumansVsNations mode in src/client/PublicLobby.ts, maxPlayers represents only human player slots (already halved in DefaultConfig.ts). The nation NPCs are added automatically server-side and don't count toward maxPlayers. Therefore, getTeamSize correctly returns maxPlayers directly for HumansVsNations to display the proper team size (e.g., maxPlayers=5 yields "5 Humans vs 5 Nations").

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-10-26T15:37:07.732Z
Learnt from: GlacialDrift
Repo: openfrontio/OpenFrontIO PR: 2298
File: src/client/graphics/layers/TerritoryLayer.ts:200-210
Timestamp: 2025-10-26T15:37:07.732Z
Learning: In GameImpl.ts lines 124-139, team assignment logic varies by number of teams: when numPlayerTeams < 8, teams are assigned ColoredTeams values (Red, Blue, Yellow, Green, Purple, Orange, Teal); when numPlayerTeams >= 8, teams are assigned generic string identifiers like "Team 1", "Team 2", etc., which are not members of ColoredTeams.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-10-21T20:06:04.823Z
Learnt from: Saphereye
Repo: openfrontio/OpenFrontIO PR: 2233
File: src/client/HostLobbyModal.ts:891-891
Timestamp: 2025-10-21T20:06:04.823Z
Learning: For the HumansVsNations game mode in `src/client/HostLobbyModal.ts` and related files, the implementation strategy is to generate all nations and adjust their strength for balancing, rather than limiting lobby size based on the number of available nations on the map.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-06-10T09:56:44.473Z
Learnt from: Ble4Ch
Repo: openfrontio/OpenFrontIO PR: 1063
File: src/core/configuration/PastelThemeDark.ts:53-53
Timestamp: 2025-06-10T09:56:44.473Z
Learning: In ColorAllocator class in src/core/configuration/Colors.ts, the correct method names are assignColor(id: string): Colord for general color assignment and assignTeamColor(team: Team): Colord for team-specific colors. There are no assignPlayerColor() or assignBotColor() methods.

Applied to files:

  • src/client/PublicLobby.ts
📚 Learning: 2025-06-09T02:20:43.637Z
Learnt from: VariableVince
Repo: openfrontio/OpenFrontIO PR: 1110
File: src/client/Main.ts:293-295
Timestamp: 2025-06-09T02:20:43.637Z
Learning: In src/client/Main.ts, during game start in the handleJoinLobby callback, UI elements are hidden using direct DOM manipulation with classList.add("hidden") for consistency. This includes modals, buttons, and error divs. The codebase follows this pattern rather than using component APIs for hiding elements during game transitions.

Applied to files:

  • src/client/PublicLobby.ts
🧬 Code graph analysis (1)
src/client/PublicLobby.ts (3)
src/core/game/Game.ts (1)
  • HumansVsNations (56-56)
src/client/LangSelector.ts (1)
  • translateText (258-278)
src/client/Utils.ts (1)
  • translateText (92-147)
🪛 GitHub Actions: 🧪 CI
src/client/PublicLobby.ts

[error] 297-297: src/client/PublicLobby.ts(297,7): TS2322: Type 'null' is not assignable to type '{ label: string | null; isFullLabel: boolean; }'.

🔇 Additional comments (2)
src/client/PublicLobby.ts (2)

140-140: Good addition - comment clarifies the flag's purpose.

The comment clearly explains what isTeamDetailFullLabel means, addressing the previous review request.


302-303: Good additions - comments explain the translation logic.

The comments at lines 302 and 312 clearly explain why translateText might return the key and why the fallback is needed, addressing the previous review requests.

Also applies to: 312-312

Copy link
Collaborator

@evanpelle evanpelle left a comment

Choose a reason for hiding this comment

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

thanks!

@github-project-automation github-project-automation bot moved this from Development to Final Review in OpenFront Release Management Jan 2, 2026
@evanpelle evanpelle merged commit 4c8bc33 into openfrontio:main Jan 2, 2026
7 checks passed
@github-project-automation github-project-automation bot moved this from Final Review to Complete in OpenFront Release Management Jan 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Translation Addition or modification of a language to the translations.

Projects

Status: Complete

Development

Successfully merging this pull request may close these issues.

5 participants