Bug Report
What Happened
In network play, selecting the MoJhoSto or MomirBasic variant and clicking Start without selecting a player deck causes the game to either:
- Show "Please specify a deck" error and refuse to start, OR
- Crash with a
NullPointerException in RegisteredPlayer.<init>() because originalDeck is null
This is incorrect because these variants auto-generate their decks (60 basic lands + avatars) — player deck selection is irrelevant and the deck chooser panel is intentionally hidden when these variants are selected.
Stack Trace (crash path)
java.lang.NullPointerException: Cannot invoke "forge.deck.Deck.getName()" because "this.originalDeck" is null
at forge.game.player.RegisteredPlayer.restoreDeck(RegisteredPlayer.java:241)
at forge.game.player.RegisteredPlayer.<init>(RegisteredPlayer.java:45)
at forge.gamemodes.match.GameLobby.startGame(GameLobby.java:442)
Root Cause
GameLobby.startGame() has a deck null check at line 363 that blocks the game from starting:
if (slot.getDeck() == null) {
SOptionPane.showMessageDialog("Please specify a deck...");
return null;
}
This check runs before the auto-generation logic at line 458-467 that would replace the null deck with a generated one. The check does not account for auto-generated variants where a null deck is expected and valid.
Additionally, even if the null check is bypassed, new RegisteredPlayer(deck) at line 442 crashes because RegisteredPlayer's constructor calls deck.getName() on the null deck.
The desktop VLobby.setReady() already had a bypass for MomirBasic/MoJhoSto (checking vntMomirBasic.isSelected() and vntMoJhoSto.isSelected()), but this only guards the ready-up step. The core GameLobby.startGame() and the mobile LobbyScreen.setReady() (local path) were missing the bypass.
Fix
Three changes across two files:
1. forge-gui/src/main/java/forge/gamemodes/match/GameLobby.java
Add auto-gen variant detection before the deck null check loop, skip the check when active, and provide a placeholder deck for RegisteredPlayer:
// Before the loop:
final boolean hasAutoGenVariant = data.appliedVariants.stream().anyMatch(GameType::isAutoGenerated);
// In the loop — skip deck null check:
if (slot.getDeck() == null && !hasAutoGenVariant) { ... }
// Before RegisteredPlayer creation — provide placeholder:
Deck deck = slot.getDeck();
if (deck == null && hasAutoGenVariant) {
deck = new Deck("auto-generated");
}
RegisteredPlayer rp = new RegisteredPlayer(deck);
2. forge-gui-mobile/src/forge/screens/constructed/LobbyScreen.java
Add the same bypass to the mobile local setReady() path:
boolean autoGenVariant = lobby.getAppliedVariants() != null
&& Iterables.any(lobby.getAppliedVariants(), GameType::isAutoGenerated);
if (decks[index] == null && !autoGenVariant) { ... }
Testing
Fix verified working in local two-instance network play test. Both MoJhoSto and MomirBasic variants can now start without selecting a deck.
Related: #9861 (network multiplayer meta issue), #10131 (related MoJhoSto/MomirBasic NPE, different code path)
Bug Report
What Happened
In network play, selecting the MoJhoSto or MomirBasic variant and clicking Start without selecting a player deck causes the game to either:
NullPointerExceptioninRegisteredPlayer.<init>()becauseoriginalDeckis nullThis is incorrect because these variants auto-generate their decks (60 basic lands + avatars) — player deck selection is irrelevant and the deck chooser panel is intentionally hidden when these variants are selected.
Stack Trace (crash path)
Root Cause
GameLobby.startGame()has a deck null check at line 363 that blocks the game from starting:This check runs before the auto-generation logic at line 458-467 that would replace the null deck with a generated one. The check does not account for auto-generated variants where a null deck is expected and valid.
Additionally, even if the null check is bypassed,
new RegisteredPlayer(deck)at line 442 crashes becauseRegisteredPlayer's constructor callsdeck.getName()on the null deck.The desktop
VLobby.setReady()already had a bypass for MomirBasic/MoJhoSto (checkingvntMomirBasic.isSelected()andvntMoJhoSto.isSelected()), but this only guards the ready-up step. The coreGameLobby.startGame()and the mobileLobbyScreen.setReady()(local path) were missing the bypass.Fix
Three changes across two files:
1.
forge-gui/src/main/java/forge/gamemodes/match/GameLobby.javaAdd auto-gen variant detection before the deck null check loop, skip the check when active, and provide a placeholder deck for
RegisteredPlayer:2.
forge-gui-mobile/src/forge/screens/constructed/LobbyScreen.javaAdd the same bypass to the mobile local
setReady()path:Testing
Fix verified working in local two-instance network play test. Both MoJhoSto and MomirBasic variants can now start without selecting a deck.
Related: #9861 (network multiplayer meta issue), #10131 (related MoJhoSto/MomirBasic NPE, different code path)