Jump to content

How to debug dedicated server problems.


Jontom Xire

Recommended Posts

I have finally got around to setting up a dedicated Minecraft server and my mod crashes.

 

The first crash was easy. It complained about trying to instantiate a Screen. A quick search of my code showed that my client event handler class was "static final" initialising my screen. I changed it to dynamic initialisation, moved client tick event registration into the FMLClientSetupEvent handler and all was well...or so I hoped.

I now get this error:

[17:03:22] [main/ERROR] [minecraft/Main]: Failed to start the minecraft server
net.minecraftforge.fml.LoadingFailedException: Loading errors encountered: [
	Stats and Skills (stats_and_skills) has failed to load correctly
§7java.lang.RuntimeException: Attempted to load class net/minecraft/client/player/LocalPlayer for invalid dist DEDICATED_SERVER

So, I did a search of my code for LocalPlayer...and found nothing. I am not importing that class, not instantiating it, not (apparently) referencing it, anywhere.

 

I am not asking you to solve this problem. There will, I am sure, be others after this. I am asking for tips on how to find the root cause of such problems and would also appreciate tips on avoiding them in the first place.

 

Link to comment
Share on other sites

I've tracked down this specific issue to this code, and now I am confused because I am sure I am handling this as per the documentation:

 

    public static void handler(SyncMsg msg, Supplier<NetworkEvent.Context> ctx)
    {
        ctx.get().enqueueWork(() -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> safe_handler(msg)));
        ctx.get().setPacketHandled(true);
    }

    public static void safe_handler(SyncMsg msg)
    {
        Player      player = (Player)(Minecraft.getInstance().player);
        PlayerData  data   = PlayerData.get(player);

        ...

 

The crash occurs when loading the mod, long before any of this code is executed. Minecraft.getInstance() is a static function, but surely this won't get executed until a message is received by the client.

Link to comment
Share on other sites

And to answer my own question...the documentation, if you read the "Common mistakes" section REALLY closely, holds all the answers, including a hint about race conditions when using static members in a normal client installation. The bit I really needed to read was about: ...@OnlyIn(Dist) annotation....

 

Now all I need to do is figure out which import that is in.

 

HOWEVER:

The documentation also says:

 

    There is NO reason for using this annotation directly. Use DistExecutor or a check on FMLEnvironment#dist instead.

 

I am. It doesn't work! Yes my supplied method is in the same class, but I tried putting it in a different class and it didn't work either.

 

Edited by Jontom Xire
Link to comment
Share on other sites

I changed "DistExecutor.unsafeRunWhenOn" to "DistExecutor.safeRunWhenOn". No change. However, I also at the same time made "DistExecutor.safeRunWhenOn" call an empty function in another class. Completely empty. However I did not remove/comment out my original safe_handler() function which is no longer being called AT ALL from ANYWHERE! Still got a crash. Code that is simply not being called at all.

 

I renamed the function to NOT_CALLED() to be really really sure it isn't being called at all somehow. Still crashed. Commented out the body of the NOT_CALLED() function and it works just fine.

Looks like @OnlyIn is my only option, as long as I can find the import...

Link to comment
Share on other sites

  • 3 weeks later...
On 2/19/2023 at 5:14 PM, Jontom Xire said:
Attempted to load class net/minecraft/client/player/LocalPlayer for invalid dist DEDICATED_SERVER

Classes in the client package don't exist on the server.

On 2/19/2023 at 5:56 PM, Jontom Xire said:

public static void handler(SyncMsg msg, Supplier<NetworkEvent.Context> ctx)
    {
        ctx.get().enqueueWork(() -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> safe_handler(msg)));
        ctx.get().setPacketHandled(true);
    }

    public static void safe_handler(SyncMsg msg)
    {
        Player      player = (Player)(Minecraft.getInstance().player);
        PlayerData  data   = PlayerData.get(player);

        ...

Are those methods in the same class? Any code that interacts with client only code should be in a seperate class.

Minecraft#player is an instance of LocalPlayer, so the game tries to load that class in order to cast it.

Please provide a complete stacktrace and git repo.

Edited by Alpvax
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now


  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hi, i want to add an item to player's inventory when specific event is fired, but i don't know how to do that
    • Try searching for the Shapeless Recipe in your workspace program's external libraries, which should have been downloaded along with the assets when you set up gradle for Forge. Looking at that file will show you how Minecraft sets it up and you can tinker with it in a custom file of your own from there. Additionally, take a look at how the crafting table handles the matching up of ingredients for shapeless recipes. You can also look at my two-slot fuel free furnace type that uses shapeless recipes. I did exactly as described above to design my custom recipe class and then built my entity class. https://github.com/toadie-odie/TodeCoins/blob/1.3.2/src/main/java/net/warrentode/todecoins/recipe/CoinPressRecipe.java https://github.com/toadie-odie/TodeCoins/blob/1.3.2/src/main/java/net/warrentode/todecoins/block/entity/CoinPressBlockEntity.java An alternative recipe check method can be looked at here:  https://github.com/toadie-odie/TodeVillagers/blob/master_03/src/main/java/net/warrentode/todevillagers/blocks/entity/GlassKilnBlockEntity.java I think maybe that the Glass Kiln one would be easier for you starting out, it was for me. In your case the points of interest are at lines 164 and 215.
    • I copied the Totem of Undying event for my coin charm, and as you can see in line 113 it has the method removeAllEffects in there, so if you're building a similar event, simply don't add the method to prevent it from removing effects. https://github.com/toadie-odie/TodeCoins/blob/1.3.2/src/main/java/net/warrentode/todecoins/event/ModEvents.java
    • Okay I got on the discord server and followed there steps and got it to start working, however the log is constantly being filled with this error code. It is creating additional copies of the config file, up to 5 copies.
    • I would like to force the pose of a living entity to a standing position (i.e. Pose.STANDING) when it is riding a certain vehicle. I have tried to call Entity#setPose every tick via LivingTickEvent, but the living entity remains in a sitting position. Here is my code: // I made it a low-priority event because I was wondering if the code should be executed at the end of each tick. @SubscribeEvent(priority = EventPriority.LOWEST) public static void livingTickEvent(LivingEvent.LivingTickEvent event) { LivingEntity livingEntity = event.getEntity(); if (!livingEntity.level.isClientSide && livingEntity.getVehicle() instanceof TheVehicle) { livingEntity.setPose(Pose.STANDING); } }   By the way, I am aware there is a setForcedPose method, but it's only for the Player class.
  • Topics

  • Who's Online (See full list)

    • There are no registered users currently online
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.