Jump to content

World Changes Not Saving


T.S.White

Recommended Posts

So I wrote a mod to make paths as you walk. (It's already up here.) It does what it's supposed to, which is amazing.

Except that when you quit, all your paths are gone when you start the world again.

 

I'm guessing I have to tell the program to commit the changes to the world somewhere... and I'm a n00b so I have no idea where/how to do that. Something about client/common classes and stuff probably...... Anyone have a good tutorial that explains how and why?

 

Current Code:

Spoiler

@EventBusSubscriber

public class MakePath {

 

 

@SubscribeEvent

public static void makePath(LivingUpdateEvent event) {

if (event.getEntity() !=null && event.getEntity() instanceof EntityPlayer) {

Entity player = event.getEntity();

BlockPos entityLocation = new BlockPos(player.posX, player.posY + player.getYOffset(), player.posZ);

World world = player.getEntityWorld();

IBlockState state = world.getBlockState(entityLocation);

Block block = state.getBlock();

 

double random = Math.random() * 100 + 1;

 

if (player.motionX > 0 || player.motionY > 0 || player.motionZ > 0)

{

if (block instanceof BlockGrass)

{

if (random < 25) {

        world.setBlockState(entityLocation, Blocks.DIRT.getDefaultState());

}

}

 

}

}

 

 

Edited by T.S.White
Link to comment
Share on other sites

1 hour ago, T.S.White said:

world.setBlockState(entityLocation, Blocks.DIRT.getDefaultState());

That is your "commit the changes to the world somewhere" line. You're done.

The only thing wrong with your code is that instead of using LivingUpdateEvent you should use PlayerUpdateEvent. Also, those updates have Phases, you should check for one of them (START or END).  You should probably also do an if(!world.isRemote) check, just to insure you're on the server.

 

Have you tried the debugger?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

57 minutes ago, Draco18s said:

Have you tried the debugger?

EDIT: nm. I know what that is. XP

Spoiler

"Debugger?" she says with wide eyes, "that would be helpful!" /derp

How do I find and use this magic?

 

 

Since it is apparently not my first guess and I am already (apparently) updating the world, I have to ask about the theory that seemed fundamentally wrong:

BlockStates are ALL the block info, right? So I'm updating the actual block and all its state info. It couldn't be tripping over something about updating the State and not the Block, right?

 

Thanks for the tip about PlayerUpdateEvent. That makes way more sense since it's currently just the player doing this thing. And the !world.isRemote check too.

 

Phases when the UpdateEvent gets called? Like, you can make the ForgeEvent go before or after the original minecraft code that forge is hijacking? If I'm understanding right, that could be incredibly useful.

Edited by T.S.White
Link to comment
Share on other sites

Draco18s, the reason he's using the living update event is that he actually wants many types of entities to do the same and just started with the player.

 

Yes, the phases allow you to get some control of your code versus the original. Usually the START is cancellable to allow you to fully replace the vanilla code whereas the END would simply augment the vanilla code.

 

The debugger is a feature of your IDE (probably Eclipse but maybe you're using IDEA or something else) that allows you to inspect code execution by methods such as setting breakpoints which will stop execution and let you see the value of various fields at that point. There are plenty of tutorials on such things. It is very useful but I often prefer using console statements instead because I like to watch behavior in real-time -- like actually play the game while watching some value change. But debugger is something you should absolutely become comfortable with.

 

Now to your actual problem about the change not being saved it seems a bit odd. As Draco18s mentioned, the set block state method should be sufficient. 

 

However, I think it is a problem with the sides. The tick event actually gets called four times per tick -- once for each phase and then per side. I have the feeling that your code is only true on the client side. This is because I think player motion is controlled primarily on the client side (still enforced on the server to prevent cheating) to avoid glitchiness waiting for server synchronization.

 

So to debug this I would set a breakpoint on the if statement and check the value of the motion fields and such. You may find that motion is 0 on server and so never sets the block. But the server is side where saves happen.

 

You could also prove this theory by deleting the check for motion and simply always changing the block under the entity. If you  find that that saves properly, it implies that the check for motion was the issue.

 

If that is indeed the problem, you could create a server-side check for "motion" by simply subtracting previous positions from current positions (and be sure to take the absolute value).

 

By the way, you have a bug in your code because motion can be negative. So your if statement would also not trigger if you walked in certain direction.

 

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

5 minutes ago, jabelar said:

Draco18s, the reason he's using the living update event is that he actually wants many types of entities to do the same and just started with the player.

True, but it's not super critical to have All entities do this. Priority is to get the player working.

 

Quote

By the way, you have a bug in your code because motion can be negative. So your if statement would also not trigger if you walked in certain direction.

I was laughing just before you posted because of this. Already fixed with abs.

 

 

 

Quote

You could also prove this theory by deleting the check for motion and simply always changing the block under the entity. If you  find that that saves properly, it implies that the check for motion was the issue.

Oooh. That was interesting. This doesn't solve the problem if I use PlayerEvent, but it does fix it if I use LivingUpdateEvent.

Which tells us several things: 1. It is indeed a client vs. server issue, and 2. PlayerEvent = Client Side, LivingUpdateEvent = Server Side, and Player-Specific Motion (the motionXYZ is player specific) = Client Side.

 

Aaaaand that means I need to figure out how to tell the server that the client changed the block and it should do the same.

I set up client and common proxies. And the ClientProxy extends the CommonProxy, and something goes in one or both of those. Right? I'm pretty sure that's the bit that's missing.

(I understand the Client/Server/Common concepts pretty well. It's using them that's the issue.)

Link to comment
Share on other sites

There are server side player events, but the player's motion is always 0 (because the client is the authority, the server ends up just teleporting the player to where the client says the player should be).

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

I think I'm getting this better now. Since I'm calling the "doSomething" code inside of a ClientEvent, it has Nothing to do with the server. So I'm going to have to run the If on the client side and return a boolean, which I can then use on the server side to setBlockState. I think. Does that make any kind of sense?

 

(I really wish I knew Java better. Most of my experience is with Agent Based Modeling, and everything in Java, and minecraft, seems SOOO backwards and top-down compared to the way I would do it with agents.)

Edited by T.S.White
Link to comment
Share on other sites

11 minutes ago, T.S.White said:

So I'm going to have to run the If on the client side and return a boolean, which I can then use on the server side to setBlockState. I think. Does that make any kind of sense?

Doing that requires packets.

But you should not need packets for this. There are already events for the player that run server side.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

1 minute ago, Draco18s said:

Doing that requires packets.

But you should not need packets for this. There are already events for the player that run server side.

Gotcha. Let's make it easier then and not do the crazy side-switcheroo dance.

I can also (probably) fix it by using a different way to check if the entity is moving (which also means I can get other entities to do this! yay!), but I need to get my priorities straight. Because all the other ways I came up with to figure out if something is moving got changed in methods that got called before mine. That's why I was so excited to hear that you could make them execute first... /ramble
 

Quote

Also, those updates have Phases, you should check for one of them (START or END).

So, I have a LivingUpdateEvent, and I need to attach the thing that says "go first".  Which is START vs END? Is it also the same as this? And how does that fit into the code?

Link to comment
Share on other sites

7 minutes ago, T.S.White said:

Which is START vs END? Is it also the same as this? And how does that fit into the code?

No, priority is what order event handlers (mod code) are executed. Without specifying (or specifying the same priority as another mod) means they go in the same order that the mods were loaded.

 

Phase is whether the event is fired before the vanilla code executes or after the vanilla code executes.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

21 minutes ago, Draco18s said:

No, priority is what order event handlers (mod code) are executed. Without specifying (or specifying the same priority as another mod) means they go in the same order that the mods were loaded.

 

Phase is whether the event is fired before the vanilla code executes or after the vanilla code executes.

 

huh. I was messing with it and changed it to

@SubscribeEvent(priority=EventPriority.HIGHEST)

 which completely fixed the problem...

 

Probably Wrong: I'm guessing that the priority treats Minecraft Itself as it would a Mod, so if it fires at HIGHEST priority Minecraft fires somewhere after and does something that updates the blocks on the server.

 

 

Thanks for all your help, btw. Every time you answer a question I seem to learn about something I hadn't even considered. 

Link to comment
Share on other sites

Quote

Probably Wrong: I'm guessing that the priority treats Minecraft Itself as it would a Mod, so if it fires at HIGHEST priority Minecraft fires somewhere after and does something that updates the blocks on the server.

You're wrong. 

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I had been using a mobile wallet to store around $200,000 worth of Bitcoin, and everything was going smoothly until my phone was stolen. At first, I wasn’t too worried. I thought I had written down the backup phrase somewhere safe, so I figured I could easily recover my funds. But after tearing my home apart, checking every drawer, notebook, and folder I could think of, I came to a horrible realization—I hadn’t been as careful as I thought. The backup phrase was nowhere to be found. Panic started to set in. Losing access to that much Bitcoin was like watching years of hard work and financial progress vanish right before my eyes. It wasn’t just about the money; it felt like my future had been snatched away in an instant. I couldn’t believe I had been so careless. It was a nightmare that I wouldn’t wish on anyone. Desperate to find a solution, I started searching online for recovery options. That’s when I came across Cyber Constable Intelligence, recommended by someone in a cryptocurrency forum. At first, I was hesitant—there are so many scams in the crypto space, and the last thing I wanted was to get ripped off while trying to recover my funds. But the positive reviews gave me a glimmer of hope, so I decided to reach out. From the moment I contacted Cyber Constable Intelligence on Email at support (AT) cyberconstableintelligence.com, they made me feel understood and reassured. They didn’t make me feel stupid for my mistake, which was something I really appreciated. They explained the recovery process clearly and thoroughly, and they reassured me that they had successfully handled cases like mine before. Even though I was still anxious—after all, this was $200,000 on the line—I felt like I was in good hands. The next few days were tense, but then I received the news I had been praying for: Cyber Constable Intelligence had managed to recover my Bitcoin. I honestly didn’t believe it until I logged in and saw my balance restored. It was like a second chance at life. The relief was overwhelming. If you’ve lost access to your wallet, no matter how hopeless the situation may seem, I can’t recommend Cyber Constable Intelligence enough. They turned my nightmare into a success story, and I’m forever grateful for their expertise and professionalism. Here's Their info below What Sapp Info: 1. (2. 5.  2.  ) 3.  7.  8.  (7. 6. 1. 1.) Website Info : www. cyber constable intelligence   com
    • So I'm creating yet another minecraft modpack and stumbled upon error I've never encoutered.. I tried to troubleshoot it myself and it always worked but this time I didn't manage.. Here is minecraft crash report: https://pastebin.com/EVqzdDKg I can't find how or from where to post debug.log  I'm sorry, can someone help me? (as a disclaimer - i've tried already reinstalling minecraft and java)
    • It works without mods, I've ran it through the launcher by itself and runs perfectly fine, when I open it through Forge I can get through to the launcher but when I go to open the world it loads then gives me the error code 1. Is there anymore info that could help diagnose it?
    • Also had the issue. GLAD TO TELL YOU I HAVE THE FIX! Create: Applied Kinetic literally says "Replace all inscriber recipes with Create's sequenced assembly recipe". When I turned off this mod it worked fine. I also didn't use that mod of the pack i played so it didn't matter for me.
    • Right now im trying to make an own mod for minecraft for the version 1.16.5 with forge but whatever i do it still doesnt fix the error this is my build.gradle : buildscript { repositories { maven { url = "https://maven.minecraftforge.net" } mavenCentral() } dependencies { classpath 'net.minecraftforge.gradle:ForgeGradle:5.1.+' } } apply plugin: 'net.minecraftforge.gradle' apply plugin: 'java' group = 'com.example' // Modify to your package name version = '1.0' archivesBaseName = 'flippermod' java { toolchain { languageVersion = JavaLanguageVersion.of(8) } } minecraft { version = "1.16.5-36.2.42" // Ensure this matches your Forge version mappings channel: 'official', version: '1.16.5' runs { client { workingDirectory project.file('run') property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' property 'forge.logging.console.level', 'debug' mods { flipper_mod { sourceSets.main.output } } } } } repositories { maven { url = "https://maven.minecraftforge.net/" } mavenCentral() } dependencies { minecraft "net.minecraftforge:forge:1.16.5-36.2.42" } and this one is my settings.gradle:  pluginManagement { repositories { gradlePluginPortal() maven { name = 'MinecraftForge' url = 'https://maven.minecraftforge.net/' } } } plugins { id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0' } rootProject.name = 'flippermod' this one is the mods.tml    modLoader="javafml" loaderVersion="[36,)" modId="flippermod" version="1.0.0" displayName="Flippermod" and the last one is the gradle-wrapper.properties distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip dc :"code_slivki"
  • Topics

×
×
  • Create New...

Important Information

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