Skip to content

Conversation

@Marc-Spector
Copy link
Collaborator

@Marc-Spector Marc-Spector commented Oct 16, 2025

Closes #3400

Summary by CodeRabbit

  • New Features

    • Added status messages during game startup: "Connecting to ICE adapter", "Connecting to replay server", and "Loading a league information".
    • Improved background task handling for more reliable startup and connection flows.
  • Tests

    • Updated tests to exercise and validate the new background task execution behavior.

@Marc-Spector Marc-Spector marked this pull request as ready for review October 18, 2025 15:07
@Marc-Spector
Copy link
Collaborator Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

Walkthrough

Introduces task-based async execution: new SimpleTask and CompletableTask constructor, TaskService gains submitFutureTask overloads with i18n title resolution, GameRunner now submits league/replay/ICE operations through TaskService, status i18n keys added, and tests updated to capture and run submitted future suppliers.

Changes

Cohort / File(s) Summary
Task primitives
src/main/java/com/faforever/client/task/SimpleTask.java, src/main/java/com/faforever/client/task/CompletableTask.java
Added SimpleTask<V> wrapping a Supplier<CompletableFuture<V>>. Added no-arg CompletableTask() delegating to MEDIUM priority; standardized lambdas to use _ for unused event params.
TaskService API
src/main/java/com/faforever/client/task/TaskService.java
Added I18n usage and two submitFutureTask overloads (submitFutureTask(Supplier<CompletableFuture<V>>) and submitFutureTask(String, Supplier<CompletableFuture<V>>)), returning the underlying future of a submitted SimpleTask. Ensures active task removal runs on FX thread.
GameRunner integration
src/main/java/com/faforever/client/game/GameRunner.java
Injected TaskService; replaced direct CompletableFuture creation for league load, replay server connect, and ICE adapter connect with taskService.submitFutureTask(...); adjusted completion and termination chains to use fxApplicationThreadExecutor and updated reactive subscription usage.
UI status wiring
src/main/java/com/faforever/client/ui/statusbar/StatusBarController.java
Minor lambda parameter rename to _ when observing taskService.getActiveWorkers() (no behavioral change).
Localization
src/main/resources/i18n/messages.properties
Added keys: iceAdapter.connecting, replayServer.connecting, league.loadInfo.
Tests
src/test/java/com/faforever/client/game/GameRunnerTest.java
Added TaskService mock and ArgumentCaptor<Supplier<CompletableFuture<Object>>>; capture and execute supplied futures in mocks so submitted simple tasks complete in tests.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant GameRunner
    participant TaskService
    participant SimpleTask
    participant Operations as League/Replay/ICE
    participant StatusBar

    User->>GameRunner: Start online game
    GameRunner->>TaskService: submitFutureTask("league.loadInfo", supplier)
    TaskService->>SimpleTask: create & run (title resolved via i18n)
    TaskService->>StatusBar: register active task (show title)
    SimpleTask->>Operations: execute league load (async)

    par parallel connections
        GameRunner->>TaskService: submitFutureTask("replayServer.connecting", supplier)
        TaskService->>SimpleTask: create & run (replay)
        SimpleTask->>Operations: connect replay server

        GameRunner->>TaskService: submitFutureTask("iceAdapter.connecting", supplier)
        TaskService->>SimpleTask: create & run (ice)
        SimpleTask->>Operations: connect ICE adapter
    end

    Operations-->>SimpleTask: results
    SimpleTask-->>TaskService: futures complete
    TaskService->>StatusBar: remove completed tasks (on FX thread)
    GameRunner->>GameRunner: handle results, wait for process exit, finalize
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Potential attention points:

  • GameRunner: review updated async chaining, termination handling, and correct use of fxApplicationThreadExecutor.
  • TaskService: ensure lifecycle management of SimpleTask futures and FX-threaded cleanup.
  • Tests: verify ArgumentCaptor usage and that mocks faithfully simulate async behavior.

Poem

🐰 I tunneled code with care and cheer,
Tasks now hop and finish near,
Titles bloom upon the bar,
Futures race and reach the star,
A rabbit claps — deploy, hooray! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Linked Issues Check ❓ Inconclusive The linked issue #3400 requires displaying progress information and status text in the status bar when creating a game, with provisions for showing failure reasons. The PR changes demonstrate partial implementation of these requirements by adding infrastructure (TaskService integration with submitFutureTask methods), creating SimpleTask for wrapping Future-based async tasks, and adding three i18n keys for status display ("Connecting to ICE adapter", "Connecting to replay server", "Loading a league information"). However, the raw_summary shows only a parameter rename in StatusBarController without evidence of concrete progress bar UI implementation or failure message handling directly in the UI layer. While the foundation for displaying status information is in place through GameRunner refactoring and i18n strings, explicit verification of the progress bar rendering and failure state handling is not evident from the provided changes. To conclusively determine compliance, additional information is needed about the actual StatusBarController implementation showing how the i18n strings are being rendered in the UI and how failure states are displayed to users. The infrastructure changes support the feature goals, but explicit UI binding and error handling in StatusBarController should be verified to confirm the full feature requirements from issue #3400 are met.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Add more useful information in status bar before running a game" aligns with the stated objective from linked issue #3400, which requests displaying progress information and status text in the status bar while the game is launching. The title accurately captures the user-facing goal of the changes, specifically adding i18n keys for status messages ("Connecting to ICE adapter", "Connecting to replay server", "Loading a league information") and refactoring GameRunner to integrate TaskService for better task management. While the title doesn't describe the technical infrastructure changes (TaskService integration, SimpleTask implementation), it appropriately focuses on the intended outcome rather than implementation details, which is suitable for a PR title.
Out of Scope Changes Check ✅ Passed All changes in this PR appear directly related to the stated objective of displaying status information in the status bar before running a game. The modifications include TaskService integration in GameRunner for managing async task lifecycle and progress, creation of SimpleTask infrastructure for wrapping CompletableFuture-based operations, addition of i18n strings for status messages, and test updates supporting the new TaskService integration. No extraneous changes such as unrelated refactoring, cosmetic modifications, or feature additions outside the scope of issue #3400 are evident in the provided changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/more-info-before-running-game

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

@Marc-Spector
Copy link
Collaborator Author

@coderabbitai help

@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

CodeRabbit commands

These commands are invoked using PR/Issue comments.

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai evaluate custom pre-merge check --instructions <custom-checks-instructions> --name <custom-checks-title> [--mode <error|warning>] to validate the custom pre-merge checks instructions. Defaults to error when --mode is omitted.
    • @coderabbitai ignore pre-merge checks to override pre-merge checks and get an approval on PR.
    • @coderabbitai run pre-merge checks to run pre-merge checks on the pull request.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit configuration file (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, support, documentation and community

  • Visit our status page to check the current availability of CodeRabbit.
  • Create a ticket on our support page for assistance with any issues or questions.
  • Visit our documentation site for detailed information on how to use CodeRabbit.
  • Join our Discord community to connect with other users and get help from the community.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
src/main/java/com/faforever/client/ui/statusbar/StatusBarController.java (1)

95-102: Compilation error: "_" is not a valid identifier on Java 9+.

Using "_" as a lambda parameter name is illegal and breaks builds on Java 17. Rename the parameter to a valid identifier (e.g., ignored) or use a method reference.

-    JavaFxUtil.addListener(taskService.getActiveWorkers(), (Observable _) -> {
+    JavaFxUtil.addListener(taskService.getActiveWorkers(), (Observable ignored) -> {
src/main/java/com/faforever/client/game/GameRunner.java (3)

151-166: Compilation error: "_" in lambda param.

Java forbids "_" as an identifier. Rename the parameter.

-                     .doOnNext(_ -> {
+                     .doOnNext(notice -> {

193-214: Compilation errors: "_" identifiers in chained stages.

Several lambdas use "_" placeholders; invalid on Java 9+. Rename them.

-                            .thenApply(_ -> gameMapper.map(gameLaunchResponse, loadLeagueInfoFuture.join()))
+                            .thenApply(ignored -> gameMapper.map(gameLaunchResponse, loadLeagueInfoFuture.join()))
-                            .whenCompleteAsync((process, _) -> {
+                            .whenCompleteAsync((process, throwable) -> {
                               if (process != null) {
                                 this.process.set(process);
                                 runningGameId.set(uid);
                               }
                             }, fxApplicationThreadExecutor)
-                            .thenAccept(this::handleTermination)
-                            .whenComplete((_, _) -> {
+                            .thenAccept(this::handleTermination)
+                            .whenComplete((ignored, throwable) -> {
                               iceAdapter.stop();
                               replayServer.stop();
                               fafServerAccessor.notifyGameEnded();
                             })
-                            .whenCompleteAsync((_, _) -> {
+                            .whenCompleteAsync((ignored, throwable) -> {
                               process.set(null);
                               runningGameId.set(null);
                             }, fxApplicationThreadExecutor);

556-574: Compilation error: "_" identifier in whenCompleteAsync and exceptionally chains.

Rename unused parameters.

-    CompletableFuture.supplyAsync(() -> forgedAllianceLaunchService.launchOfflineGame(null))
-                     .whenCompleteAsync((process, _) -> {
+    CompletableFuture.supplyAsync(() -> forgedAllianceLaunchService.launchOfflineGame(null))
+                     .whenCompleteAsync((process, throwable) -> {
                        if (process != null) {
                          this.process.set(process);
                        }
                      }, fxApplicationThreadExecutor)
                      .thenCompose(Process::onExit)
                      .thenAccept(this::handleTermination)
-                     .exceptionally(throwable -> {
+                     .exceptionally(throwable -> {
                        throwable = ConcurrentUtil.unwrapIfCompletionException(throwable);
                        log.error("Launching offline game failed", throwable);
                        if (throwable instanceof NotifiableException notifiableException) {
                          notificationService.addErrorNotification(notifiableException);
                        } else {
                          notificationService.addImmediateErrorNotification(throwable, "tutorial.launchFailed");
                        }
                        return null;
                      });
🧹 Nitpick comments (5)
src/main/resources/i18n/messages.properties (1)

1317-1319: Polish i18n strings (grammar + consistency with existing ellipses).

  • Use ellipsis like other “Connecting…”/“Loading…” keys.
  • Fix article: “Loading league information”.
-iceAdapter.connecting = Connecting to ICE adapter
-replayServer.connecting = Connecting to replay server
-league.loadInfo = Loading a league information
+iceAdapter.connecting = Connecting to ICE adapter…
+replayServer.connecting = Connecting to replay server…
+league.loadInfo = Loading league information…
src/main/java/com/faforever/client/task/CompletableTask.java (1)

15-18: Default ctor locks priority to MEDIUM; setPriority() becomes unusable.

The new no-arg ctor sets priority immediately, but setPriority() throws if priority is already set. Any subclass (e.g., SimpleTask) now cannot change priority, eliminating prioritization flexibility.

Options:

  • Add constructors that accept Priority in subclasses (e.g., SimpleTask) and call super(priority).
  • Or allow one-time set in setPriority() (only if not yet executed), initializing priority to null in the no-arg ctor.

Do you want a follow-up patch adding a Priority-accepting SimpleTask ctor and tests?

src/main/java/com/faforever/client/task/SimpleTask.java (2)

17-21: Allow priority configuration for SimpleTask.

SimpleTask currently always uses MEDIUM (inherited default). Provide an overload to pass Priority and call super(priority) to keep prioritization usable.

 public class SimpleTask<V> extends CompletableTask<V> {
@@
-  public SimpleTask(String title, Supplier<? extends CompletableFuture<V>> futureSupplier) {
+  public SimpleTask(String title, Supplier<? extends CompletableFuture<V>> futureSupplier) {
     this.futureSupplier = futureSupplier;
     updateTitle(StringUtils.defaultIfBlank(title, StringUtils.EMPTY));
   }
+
+  public SimpleTask(Priority priority, String title, Supplier<? extends CompletableFuture<V>> futureSupplier) {
+    super(priority);
+    this.futureSupplier = futureSupplier;
+    updateTitle(StringUtils.defaultIfBlank(title, StringUtils.EMPTY));
+  }

22-27: Improve cancellation propagation to underlying future.

Cancelling the Task cancels CompletableTask’s internal future, but not the supplier’s returned Future, which may keep running. Track it and cancel as well.

 public class SimpleTask<V> extends CompletableTask<V> {
 
   private final Supplier<? extends CompletableFuture<V>> futureSupplier;
+  private volatile Future<V> running;
@@
   @Override
   protected V call() throws Exception {
-    Future<V> task = futureSupplier.get();
-    return task.get();
+    running = futureSupplier.get();
+    try {
+      return running.get();
+    } finally {
+      running = null;
+    }
   }
 }
+
+// In CompletableTask (outside this hunk), optionally override cancel to also cancel `running` if present.
src/main/java/com/faforever/client/task/TaskService.java (1)

57-65: NPE and title resolution edge-cases.

  • Guard null Supplier.
  • Consider deferring i18n lookup to FX thread if resource bundles can change at runtime (optional).
-  public <V> CompletableFuture<V> submitFutureTask(String titleI18nKey, Supplier<CompletableFuture<V>> task) {
-    String title = titleI18nKey != null ? i18n.get(titleI18nKey) : null;
-    return submitTask(new SimpleTask<>(title, task)).getFuture();
+  public <V> CompletableFuture<V> submitFutureTask(String titleI18nKey, Supplier<CompletableFuture<V>> task) {
+    if (task == null) {
+      return CompletableFuture.failedFuture(new NullPointerException("task supplier must not be null"));
+    }
+    String title = titleI18nKey != null ? i18n.get(titleI18nKey) : null;
+    return submitTask(new SimpleTask<>(title, task)).getFuture();
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2234cb5 and 6df65df.

📒 Files selected for processing (7)
  • src/main/java/com/faforever/client/game/GameRunner.java (8 hunks)
  • src/main/java/com/faforever/client/task/CompletableTask.java (1 hunks)
  • src/main/java/com/faforever/client/task/SimpleTask.java (1 hunks)
  • src/main/java/com/faforever/client/task/TaskService.java (5 hunks)
  • src/main/java/com/faforever/client/ui/statusbar/StatusBarController.java (1 hunks)
  • src/main/resources/i18n/messages.properties (1 hunks)
  • src/test/java/com/faforever/client/game/GameRunnerTest.java (6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (1)
src/test/java/com/faforever/client/game/GameRunnerTest.java (1)

205-209: Mocking approach to run submitted future tasks looks good.

Capturing the Supplier and joining the returned future ensures tasks complete within tests. This keeps assertions deterministic.

@Marc-Spector
Copy link
Collaborator Author

@coderabbitai resolve

@coderabbitai
Copy link

coderabbitai bot commented Oct 24, 2025

✅ Actions performed

Comments resolved.

@Sheikah45 Sheikah45 force-pushed the feature/more-info-before-running-game branch from 6df65df to bf5f5f1 Compare October 25, 2025 12:13
@Sheikah45 Sheikah45 enabled auto-merge (squash) October 25, 2025 12:13
@Sheikah45 Sheikah45 merged commit da6d6df into develop Oct 25, 2025
3 of 4 checks passed
@Sheikah45 Sheikah45 deleted the feature/more-info-before-running-game branch October 25, 2025 12:15
Copy link

@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 (2)
src/main/java/com/faforever/client/game/GameRunner.java (2)

183-183: Confusing variable name: hasLeague.

The variable hasLeague is true when the leaderboard is null or "global", and league info is loaded only when hasLeague is false. This naming is counterintuitive.

Consider renaming for clarity:

-    boolean hasLeague = leaderboard == null || "global".equals(leaderboard);
+    boolean needsDivisionInfo = leaderboard != null && !"global".equals(leaderboard);

Then update line 189:

-    CompletableFuture<League> loadLeagueInfoFuture = hasLeague ? completedFuture(null) : taskService.submitFutureTask("league.loadInfo", () -> getDivisionInfo(leaderboard).toFuture());
+    CompletableFuture<League> loadLeagueInfoFuture = needsDivisionInfo ? taskService.submitFutureTask("league.loadInfo", () -> getDivisionInfo(leaderboard).toFuture()) : completedFuture(null);

Also applies to: 189-189


193-196: Consider avoiding blocking .join() calls in async chain.

Lines 194-196 call .join() on futures inside thenApply. While these futures are already complete (after allOf), this pattern can block the completion thread and is considered a code smell.

Consider extracting values after allOf completes:

 return CompletableFuture.allOf(downloadMapFuture, loadLeagueInfoFuture, runReplayServerFuture, runIceAdapterFuture)
-                        .thenApply(_ -> gameMapper.map(gameLaunchResponse, loadLeagueInfoFuture.join()))
-                        .thenApply(parameters -> launchOnlineGame(parameters, runIceAdapterFuture.join(),
-                                                                  runReplayServerFuture.join()))
+                        .thenApply(_ -> {
+                          League league = loadLeagueInfoFuture.join();
+                          Integer icePort = runIceAdapterFuture.join();
+                          Integer replayPort = runReplayServerFuture.join();
+                          GameParameters parameters = gameMapper.map(gameLaunchResponse, league);
+                          return launchOnlineGame(parameters, icePort, replayPort);
+                        })

Alternatively, use thenCompose with thenCombine to avoid explicit joins.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6df65df and bf5f5f1.

📒 Files selected for processing (7)
  • src/main/java/com/faforever/client/game/GameRunner.java (8 hunks)
  • src/main/java/com/faforever/client/task/CompletableTask.java (1 hunks)
  • src/main/java/com/faforever/client/task/SimpleTask.java (1 hunks)
  • src/main/java/com/faforever/client/task/TaskService.java (5 hunks)
  • src/main/java/com/faforever/client/ui/statusbar/StatusBarController.java (1 hunks)
  • src/main/resources/i18n/messages.properties (1 hunks)
  • src/test/java/com/faforever/client/game/GameRunnerTest.java (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/main/java/com/faforever/client/task/CompletableTask.java
  • src/main/resources/i18n/messages.properties
  • src/test/java/com/faforever/client/game/GameRunnerTest.java
  • src/main/java/com/faforever/client/task/TaskService.java
  • src/main/java/com/faforever/client/ui/statusbar/StatusBarController.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-24T20:19:47.769Z
Learnt from: Brutus5000
PR: FAForever/downlords-faf-client#3417
File: src/main/java/com/faforever/client/task/CompletableTask.java:22-25
Timestamp: 2025-10-24T20:19:47.769Z
Learning: In Java 21 and later (via JEP 443), the single underscore `_` is the canonical and valid way to declare unnamed variables and patterns, including unused lambda parameters. Do not flag `_` as a compilation error in projects using Java 21 or newer.

Applied to files:

  • src/main/java/com/faforever/client/game/GameRunner.java
📚 Learning: 2025-10-24T20:18:48.136Z
Learnt from: Brutus5000
PR: FAForever/downlords-faf-client#3417
File: src/main/java/com/faforever/client/game/GameRunner.java:488-491
Timestamp: 2025-10-24T20:18:48.136Z
Learning: In Java 21 and later, the single underscore `_` is the standard and correct syntax for unnamed variables and unused lambda parameters. Do not flag `_` as a compilation error in lambda expressions when the project uses Java 21+.

Applied to files:

  • src/main/java/com/faforever/client/game/GameRunner.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: checks
  • GitHub Check: checks
🔇 Additional comments (6)
src/main/java/com/faforever/client/task/SimpleTask.java (1)

9-26: LGTM! Clean wrapper for async operations.

The implementation correctly wraps CompletableFuture suppliers into the Task framework, enabling progress tracking in the status bar. The blocking call to task.get() on line 25 is appropriate since this runs in a background thread managed by the task service.

src/main/java/com/faforever/client/game/GameRunner.java (5)

41-41: LGTM! TaskService integration.

The TaskService dependency is properly added to support progress tracking for game launch operations.

Also applies to: 122-122


168-172: Good refactor to reactive subscription.

The connection state handling now uses subscribe instead of addListener, which is cleaner and more idiomatic. The logic correctly restores the game session when reconnecting.


153-153: LGTM! Appropriate use of unnamed variables.

The lambda parameters are correctly updated to use _ (unnamed variable) to explicitly indicate unused parameters. This is the canonical syntax in Java 21+ and improves code clarity.

Also applies to: 194-197, 205-213, 488-489, 514-514, 524-525, 557-557


197-213: Well-structured process lifecycle management.

The completion chain properly:

  • Sets process state on the FX thread (lines 197-202)
  • Waits for process exit (line 203)
  • Performs cleanup operations (lines 205-209)
  • Clears state on the FX thread (lines 210-213)

The sequencing ensures cleanup happens before final state updates, and FX thread safety is maintained.


189-191: All i18n keys are properly defined.

The verification confirms that all three i18n keys exist in the localization files at src/main/resources/i18n/messages.properties:

  • league.loadInfo (line 1319)
  • replayServer.connecting (line 1318)
  • iceAdapter.connecting (line 1317)

No issues found.

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.

[Feature]: Show progress after clicking "Create Game"

4 participants