MovingBlocks / Terasology

Terasology - open source voxel world
http://terasology.org
Apache License 2.0
3.68k stars 1.34k forks source link

Headless Server tries to return to main menu on failing to start game #4960

Open jdrueckert opened 2 years ago

jdrueckert commented 2 years ago

What you were trying to do

Start a headless server and override its default configuration.

./gradlew server --args="--override-default-config=override.cfg"

What actually happened

The server failed to start the game and crashed.

How to reproduce

  1. Run ./gradlew server and notice that the server starts successfully
  2. Stop the server
  3. Provoke a game start failure, e.g. if the issues still exists by exploiting https://github.com/MovingBlocks/Terasology/issues/4958: ./gradlew server --args="--override-default-config=override.cfg"
  4. Notice that something in the logs indicates that the server failed to start the game [main] WARN o.t.e.c.m.loadProcesses.RegisterMods - Missing at least one required module (or dependency) from the following list: [BiomesAPI, Thirst, StructureTemplates, Furnishings, CoreRendering, AnotherWorld, Health, CoreSampleGameplay, Inventory, Explosives, CoreWorlds, CoreAdvancedAssets, Drops, StructuralResources, AnotherWorldPlants, engine, ClimateConditions, AlterationEffects, Fluid, CoreAssets, PlantPack, GrowingFlora]
  5. Notice that the server crashes with an NPE in org.terasology.engine.rendering.nui.internal.TerasologyCanvasImpl.<init>(TerasologyCanvasImpl.java:42)

Log details

14:03:18.919 [main] WARN  o.t.e.c.m.loadProcesses.RegisterMods - Missing at least one required module (or dependency) from the following list: [BiomesAPI, Thirst, StructureTemplates, Furnishings, CoreRendering, AnotherWorld, Health, CoreSampleGameplay, Inventory, Explosives, CoreWorlds, CoreAdvancedAssets, Drops, StructuralResources, AnotherWorldPlants, engine, ClimateConditions, AlterationEffects, Fluid, CoreAssets, PlantPack, GrowingFlora]
14:03:18.962 [main] ERROR o.t.engine.core.TerasologyEngine - Uncaught exception, attempting clean game shutdown
java.lang.NullPointerException: null
        at org.terasology.engine.rendering.nui.internal.TerasologyCanvasImpl.<init>(TerasologyCanvasImpl.java:42)
        at org.terasology.engine.rendering.nui.internal.NUIManagerInternal.<init>(NUIManagerInternal.java:117)
        at org.terasology.engine.core.modes.AbstractState.initEntityAndComponentManagers(AbstractState.java:45)
        at org.terasology.engine.core.modes.StateMainMenu.init(StateMainMenu.java:48)
        at org.terasology.engine.core.TerasologyEngine.switchState(TerasologyEngine.java:587)
        at org.terasology.engine.core.TerasologyEngine.processPendingState(TerasologyEngine.java:575)
        at org.terasology.engine.core.TerasologyEngine.tick(TerasologyEngine.java:479)
        at org.terasology.engine.core.TerasologyEngine.mainLoop(TerasologyEngine.java:459)
        at org.terasology.engine.core.TerasologyEngine.runMain(TerasologyEngine.java:435)
        at org.terasology.engine.core.TerasologyEngine.run(TerasologyEngine.java:401)
        at org.terasology.engine.Terasology.call(Terasology.java:180)
        at org.terasology.engine.Terasology.call(Terasology.java:69)
        at picocli.CommandLine.executeUserObject(CommandLine.java:1933)
        at picocli.CommandLine.access$1200(CommandLine.java:145)
        at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2332)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2326)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2291)
        at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2159)
        at picocli.CommandLine.execute(CommandLine.java:2058)
        at org.terasology.engine.Terasology.main(Terasology.java:138)

Full logs at https://pastebin.com/EN0hZTha

Additional Info

The current assumption is that on failing to start a game, the server attempts to go back to the main menu. Since https://github.com/MovingBlocks/Terasology/pull/4907, the headless server does not have a NuiManager anymore which is why it runs into an NPE at this point.

Note, that for reproducing this, you might need to take additional actions due to https://github.com/MovingBlocks/Terasology/issues/4956 and https://github.com/MovingBlocks/Terasology/issues/4957 or find a different way to provoke the game start failure in case https://github.com/MovingBlocks/Terasology/issues/4958 has been fixed.

keturn commented 2 years ago

Yeah, we have "change to StateMainMenu" coded in various different places as the thing to do when they can't continue as planned.

I would very much like them to have a different way to communicate that error and then let some logic at a higher level decide what the appropriate response is. e.g. show a message and fall back to main menu for a GUI, but print message and quit for headless, etc.

keturn commented 2 years ago

Related: #4962

DarkWeird commented 2 years ago

Yeah, we have "change to StateMainMenu" coded in various different places as the thing to do when they can't continue as planned.

I would very much like them to have a different way to communicate that error and then let some logic at a higher level decide what the appropriate response is. e.g. show a message and fall back to main menu for a GUI, but print message and quit for headless, etc.

There needs to implement strict Stack or State Machine for states with strict interfaces.

Variant 1:

class States<MENU extends GameState, LOAD extends GameState, GAME extends GameState> {

    MENU start(...);
    LOAD load(...);
    GAME loadDone(...);
    ? getState();
    MENU error(...);
}

Pros:

  1. Strict structure
  2. Easier enough
  3. replaceble slots (MTEMainMenu, MTELoading) Cons:
  4. Needs to provide this anywhere
  5. Not extendable
  6. need to think how it implement better


Variant 2:
I like this https://book.amethyst.rs/book/stable/concepts/state#state-manager
Pros:
1. Extandable
2. Strict transitions.
3. NUI screens can be as substates 
Cons:
1.this example use a bit another architecture..