MrChoke Posted September 15, 2018 Posted September 15, 2018 Well, one of the main things I want to do with learning forge is see if I can override the default spawning behavior. Namely how far away a mob is before it despawns for example. I can't find a way to do it. And no handling a "LivingSpawnEvent.AllowDespawn" does not do it. And here is why: Class: net.minecraft.EntityLiving, line 791: else if ((this.idleTime & 0x1F) == 0x1F && (result = net.minecraftforge.event.ForgeEventFactory.canEntityDespawn(this)) != net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT) As you can see the forge event handler is only called every 32nd tick. I can't modify how long a mob can stay around if all the rest of the ticks will fall into the default behavior!!!! The placement of this forge event is a failure. Is there another way to do this? Quote
V0idWa1k3r Posted September 15, 2018 Posted September 15, 2018 7 hours ago, MrChoke said: I can't modify how long a mob can stay around if all the rest of the ticks will fall into the default behavior!!!! I am sorry but what are you talking about? No other ticks will fall into the default behaviour, minecraft simply tries to despawn entities once every 32 ticks and this is where forge hooks into. If this 7 hours ago, MrChoke said: (this.idleTime & 0x1F) == 0x1F isn't true no despawning code will be executed at all. And no forge event will fire either because there is no need to. If you want your mob to stick around for a certain amount of time you can attach a capability to that entity and store your time there. Quote
MrChoke Posted September 15, 2018 Author Posted September 15, 2018 11 hours ago, V0idWa1k3r said: I am sorry but what are you talking about? No other ticks will fall into the default behaviour, minecraft simply tries to despawn entities once every 32 ticks and this is where forge hooks into. If this isn't true no despawning code will be executed at all. And no forge event will fire either because there is no need to. If you want your mob to stick around for a certain amount of time you can attach a capability to that entity and store your time there. No, I am sorry but you are not correct. EntityLiving#despawnEntity() is called every tick. And the code below is such that the default spawn behavior (the ELSE) is called for every tick except the 32nd one and only then is the forge event called: if (this.persistenceRequired) { this.idleTime = 0; } else if ((this.idleTime & 0x1F) == 0x1F && (result = net.minecraftforge.event.ForgeEventFactory.canEntityDespawn(this)) != net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT) { if (result == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) { this.idleTime = 0; } else { this.setDead(); } } else { Entity entity = this.world.getClosestPlayerToEntity(this, -1.0D); if (entity != null) { double d0 = entity.posX - this.posX; double d1 = entity.posY - this.posY; double d2 = entity.posZ - this.posZ; double d3 = d0 * d0 + d1 * d1 + d2 * d2; if (this.canDespawn() && d3 > 16384.0D) { this.setDead(); } if (this.idleTime > 600 && this.rand.nextInt(800) == 0 && d3 > 1024.0D && this.canDespawn()) { this.setDead(); } else if (d3 < 1024.0D) { this.idleTime = 0; } } } The forge event is not called enough to be useful in anyway. In addition, I didn't check the non-forge vanilla minecraft code yet but if Mojang's intent was to have despawning occur every 32nd tick, then Forge created a bug here where despawning can happen ALL but every 32nd tick. Who is Forge? Is there a group or bug report I can make? They really need to fix this for 1.13. Quote
V0idWa1k3r Posted September 15, 2018 Posted September 15, 2018 Do you see this line if (result == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) { this.idleTime = 0; } If the result is deny then the idle time is set to 0 preventing the entity from despawning. From the code you've pasted: if (this.idleTime > 600 && this.rand.nextInt(800) == 0 && d3 > 1024.0D && this.canDespawn()) { this.setDead(); } The entity will only despawn if idleTime is greater than 600 and denying the event sets it to 0. Quote
MrChoke Posted September 15, 2018 Author Posted September 15, 2018 (edited) 1 hour ago, V0idWa1k3r said: Do you see this line if (result == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) { this.idleTime = 0; } If the result is deny then the idle time is set to 0 preventing the entity from despawning. From the code you've pasted: if (this.idleTime > 600 && this.rand.nextInt(800) == 0 && d3 > 1024.0D && this.canDespawn()) { this.setDead(); } The entity will only despawn if idleTime is greater than 600 and denying the event sets it to 0. The 1st line you copied, in the forge-event section, called when it returns ALLOW or DENY doesn't matter. You showing part of the default-behavior ELSE is also missing the point. The forge-event itself AND the handling after is only called on the 32nd tick. If we want to override the default behavior with an event handler then we need to handle it on EVERY TICK. Again, this is the line that has the issue: else if ((this.idleTime & 0x1F) == 0x1F && (result = net.minecraftforge.event.ForgeEventFactory.canEntityDespawn(this)) != net.minecraftforge.fml.common.eventhandler.Event.Result.DEFAULT) You know Java well right? You understand that ONLY if the below evaluates to TRUE: (this.idleTime & 0x1F) == 0x1F Will it ever call the forge event handler. An "&&" doesn't even evaluate the 2nd argument once the 1st is FALSE. And that's it. That's all that matters. The above condition is a logical AND. It's only true on the 32nd tick of any group of 32 ticks. Can someone else please comment on this post? We need another person to deny or agree with the behavior I am saying. And I still have this question: If forge itself has a bug (like above), how can I report it? Thanks. Edited September 15, 2018 by MrChoke Quote
Draco18s Posted September 16, 2018 Posted September 16, 2018 22 minutes ago, MrChoke said: You know Java well right? You understand that ONLY if the below evaluates to TRUE: (this.idleTime & 0x1F) == 0x1F Will it ever call the forge event handler. An "&&" doesn't even evaluate the 2nd argument once the 1st is FALSE. And that's it. That's all that matters. The above condition is a logical AND. It's only true on the 32nd tick of any group of 32 ticks. In order for idleTime to be > 600, idleTime must, at some point, been equal to 32. If it was 32, Forge fired an event, you denied it, idleTime is 0 again. 21 hours ago, MrChoke said: I can't modify how long a mob can stay around if all the rest of the ticks will fall into the default behavior! The rest of the ticks are irrelevant unless you're worried about this line: if (this.canDespawn() && d3 > 16384.0D) Which if you are, you shouldn't be, because that mob is so far away from the player is freaking irrelevant. 21 hours ago, MrChoke said: The placement of this forge event is a failure. Make a pull request, then Quote 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.
MrChoke Posted September 16, 2018 Author Posted September 16, 2018 27 minutes ago, Draco18s said: In order for idleTime to be > 600, idleTime must, at some point, been equal to 32. If it was 32, Forge fired an event, you denied it, idleTime is 0 again. The rest of the ticks are irrelevant unless you're worried about this line: if (this.canDespawn() && d3 > 16384.0D) Which if you are, you shouldn't be, because that mob is so far away from the player is freaking irrelevant. Make a pull request, then idleTIme can and will increase unless something resets it, like the mob getting attacked for example. And of course if you return DENY when the event handler is called. I get that but what if I wanted to modify the behavior coming from the exact line you specify if (this.canDespawn() && d3 > 16384.0D) That's the the 128 blocks away rule. If I try to return DENY for a greater distance to keep the mob around, I can't. As soon ans the default code executes it will despawn. The rule I hate more is this one: if (this.idleTime > 600 && this.rand.nextInt(800) == 0 && d3 > 1024.0D && this.canDespawn()) What if I wanted the despawn check to start after 60 seconds instead of the 30 seconds this line above has? Again, as soon as I try to extend this with my every 32nd tick, DENY, the default code will despawn him anyway. What is a "PULL REQUEST"? Can you explain? Quote
Animefan8888 Posted September 16, 2018 Posted September 16, 2018 2 hours ago, MrChoke said: What is a "PULL REQUEST"? Can you explain? 3 hours ago, MrChoke said: If forge itself has a bug (like above), how can I report it? It also requires you give a solution. Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
jabelar Posted September 16, 2018 Posted September 16, 2018 (edited) Regarding the "pull request" you can start by just filing an "issue" against the MinecraftForge project on GitHub. The "pull request" is where you actually offer a solution, but honestly it can be a bit tricky to set up properly to contribute to Forge (because Forge is actually a set of patches and because other people are modifying patches as well at the same time you're trying to contribute). However, it is really good if people are able to contribute because ultimately Forge is a community open source project. So I actually responded to someone who had posted this as an issue previously. See https://github.com/MinecraftForge/MinecraftForge/issues/4485 In that I looked at the code and here is I summarized the functionality then: Definitely I think the logic could be clearer, but I think the idea is that you can prevent despawning with the event easily because every 32 ticks you get a chance to reset the idleTimer to 0 whereas if you let it get to 600 then there is a chance that closer entities might be despawned. Interestingly though I think the logic is that entities that are very far cannot be prevented from despawning by the event. Now, although the event cannot prevent despawning, the EntityLiving#persistenceRequired field can. That can be set with the EntityLiving#setPersistence() method. So I think that if you want to take total control of despawning you could theoretically set the persistence of any entity you're interested in and then run your own despawning algorithm in the LivingUpdateEvent. Note I do think the despawn event would be better if it was either fired in both code paths or if it was just fired once at the beginning of the method to allow denial of any sort of despawn. I suppose that the original implementers felt that maybe allowing modders to prevent despawn generally would be "dangerous" as there is a real performance impact. Edited September 16, 2018 by jabelar 1 Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/
MrChoke Posted September 16, 2018 Author Posted September 16, 2018 8 hours ago, jabelar said: Regarding the "pull request" you can start by just filing an "issue" against the MinecraftForge project on GitHub. The "pull request" is where you actually offer a solution, but honestly it can be a bit tricky to set up properly to contribute to Forge (because Forge is actually a set of patches and because other people are modifying patches as well at the same time you're trying to contribute). However, it is really good if people are able to contribute because ultimately Forge is a community open source project. So I actually responded to someone who had posted this as an issue previously. See https://github.com/MinecraftForge/MinecraftForge/issues/4485 In that I looked at the code and here is I summarized the functionality then: Definitely I think the logic could be clearer, but I think the idea is that you can prevent despawning with the event easily because every 32 ticks you get a chance to reset the idleTimer to 0 whereas if you let it get to 600 then there is a chance that closer entities might be despawned. Interestingly though I think the logic is that entities that are very far cannot be prevented from despawning by the event. Now, although the event cannot prevent despawning, the EntityLiving#persistenceRequired field can. That can be set with the EntityLiving#setPersistence() method. So I think that if you want to take total control of despawning you could theoretically set the persistence of any entity you're interested in and then run your own despawning algorithm in the LivingUpdateEvent. Note I do think the despawn event would be better if it was either fired in both code paths or if it was just fired once at the beginning of the method to allow denial of any sort of despawn. I suppose that the original implementers felt that maybe allowing modders to prevent despawn generally would be "dangerous" as there is a real performance impact. That's for the reply. YES, that is the exact issue I am reporting here. I realize that I can modify idleTime to slow or stop despawning (within 128 blocks anyway) but its the distances in the default code that we do not get to control. So I can re-activate that issue or create a new one but I see in the current one only the original poster and you replied. Are you on the Forge team? The fix is easy, simply remove this check: (this.idleTime & 0x1F) == 0x1F I agree it was done for performance to allow slow complicated despawn handlers to run and not kill the game that much. But more important is allowing the ability to truly override the default behavior, which it is not doing. So IMO it's a bug. Anyway I'll create an issue and see what happens. Thanks. Quote
MrChoke Posted September 16, 2018 Author Posted September 16, 2018 (edited) UPDATE: So I did a pull request for this issue. However github would not let me create one for 1.13pre!! I don't know why. My pull request says I want to pull 1.13 into 1.12x. SIgh. https://github.com/MinecraftForge/MinecraftForge/pull/5148 UPDATE 2: I got git and github desktop installed, forked and pulled the 1.12x Forge codebase. OK but this does nothing to fix the bug. What I got is the "net.minecraftforge" source but the bug is in Forge's hook placement in "net.minecraft.entity.EntityLiving". Modification of this code is required. How do I get that? Edited September 16, 2018 by MrChoke Quote
MrChoke Posted September 16, 2018 Author Posted September 16, 2018 1 hour ago, diesieben07 said: If only there was a readme file. I followed that and have the workspace installed on my machine. Do you? Do you notice that the only source in it is "net.minecraftforge"? Where is "net.minecraft" at???? Quote
DaemonUmbra Posted September 16, 2018 Posted September 16, 2018 From this section of the document: Quote The most important thing to note is that if you wish to edit Minecraft source code, you must only do so in the “Forge” sub-project. Quote This is my Forum Signature, I am currently attempting to transform it into a small guide for fixing easier issues using spoiler blocks to keep things tidy. As the most common issue I feel I should put this outside the main bulk: The only official source for Forge is https://files.minecraftforge.net, and the only site I trust for getting mods is CurseForge. If you use any site other than these, please take a look at the StopModReposts project and install their browser extension, I would also advise running a virus scan. For players asking for assistance with Forge please expand the spoiler below and read the appropriate section(s) in its/their entirety. Spoiler Logs (Most issues require logs to diagnose): Spoiler Please post logs using one of the following sites (Thank you Lumber Wizard for the list): https://gist.github.com/: 100MB Requires member (Free) https://pastebin.com/: 512KB as guest, 10MB as Pro ($$$) https://hastebin.com/: 400KB Do NOT use sites like Mediafire, Dropbox, OneDrive, Google Drive, or a site that has a countdown before offering downloads. What to provide: ...for Crashes and Runtime issues: Minecraft 1.14.4 and newer: Post debug.log Older versions: Please update... ...for Installer Issues: Post your installer log, found in the same place you ran the installer This log will be called either installer.log or named the same as the installer but with .log on the end Note for Windows users: Windows hides file extensions by default so the installer may appear without the .jar extension then when the .log is added the log will appear with the .jar extension Where to get it: Mojang Launcher: When using the Mojang launcher debug.log is found in .minecraft\logs. Curse/Overwolf: If you are using the Curse Launcher, their configurations break Forge's log settings, fortunately there is an easier workaround than I originally thought, this works even with Curse's installation of the Minecraft launcher as long as it is not launched THROUGH Twitch: Spoiler Make sure you have the correct version of Forge installed (some packs are heavily dependent on one specific build of Forge) Make a launcher profile targeting this version of Forge. Set the launcher profile's GameDir property to the pack's instance folder (not the instances folder, the folder that has the pack's name on it). Now launch the pack through that profile and follow the "Mojang Launcher" instructions above. Video: Spoiler or alternately, Fallback ("No logs are generated"): If you don't see logs generated in the usual place, provide the launcher_log.txt from .minecraft Server Not Starting: Spoiler If your server does not start or a command window appears and immediately goes away, run the jar manually and provide the output. Reporting Illegal/Inappropriate Adfocus Ads: Spoiler Get a screenshot of the URL bar or copy/paste the whole URL into a thread on the General Discussion board with a description of the Ad. Lex will need the Ad ID contained in that URL to report it to Adfocus' support team. Posting your mod as a GitHub Repo: Spoiler When you have an issue with your mod the most helpful thing you can do when asking for help is to provide your code to those helping you. The most convenient way to do this is via GitHub or another source control hub. When setting up a GitHub Repo it might seem easy to just upload everything, however this method has the potential for mistakes that could lead to trouble later on, it is recommended to use a Git client or to get comfortable with the Git command line. The following instructions will use the Git Command Line and as such they assume you already have it installed and that you have created a repository. Open a command prompt (CMD, Powershell, Terminal, etc). Navigate to the folder you extracted Forge’s MDK to (the one that had all the licenses in). Run the following commands: git init git remote add origin [Your Repository's URL] In the case of GitHub it should look like: https://GitHub.com/[Your Username]/[Repo Name].git git fetch git checkout --track origin/master git stage * git commit -m "[Your commit message]" git push Navigate to GitHub and you should now see most of the files. note that it is intentional that some are not synced with GitHub and this is done with the (hidden) .gitignore file that Forge’s MDK has provided (hence the strictness on which folder git init is run from) Now you can share your GitHub link with those who you are asking for help. [Workaround line, please ignore]
MrChoke Posted September 16, 2018 Author Posted September 16, 2018 28 minutes ago, DaemonUmbra said: From this section of the document: Ok, I did read this. Can you explain what that means? If I am looking at the pulled code for Forge in my IDE (IntelliJ), where is the "net.minecraft" source? I am missing this.... Thanks Quote
DaemonUmbra Posted September 16, 2018 Posted September 16, 2018 Did you run the setupForge task? Quote This is my Forum Signature, I am currently attempting to transform it into a small guide for fixing easier issues using spoiler blocks to keep things tidy. As the most common issue I feel I should put this outside the main bulk: The only official source for Forge is https://files.minecraftforge.net, and the only site I trust for getting mods is CurseForge. If you use any site other than these, please take a look at the StopModReposts project and install their browser extension, I would also advise running a virus scan. For players asking for assistance with Forge please expand the spoiler below and read the appropriate section(s) in its/their entirety. Spoiler Logs (Most issues require logs to diagnose): Spoiler Please post logs using one of the following sites (Thank you Lumber Wizard for the list): https://gist.github.com/: 100MB Requires member (Free) https://pastebin.com/: 512KB as guest, 10MB as Pro ($$$) https://hastebin.com/: 400KB Do NOT use sites like Mediafire, Dropbox, OneDrive, Google Drive, or a site that has a countdown before offering downloads. What to provide: ...for Crashes and Runtime issues: Minecraft 1.14.4 and newer: Post debug.log Older versions: Please update... ...for Installer Issues: Post your installer log, found in the same place you ran the installer This log will be called either installer.log or named the same as the installer but with .log on the end Note for Windows users: Windows hides file extensions by default so the installer may appear without the .jar extension then when the .log is added the log will appear with the .jar extension Where to get it: Mojang Launcher: When using the Mojang launcher debug.log is found in .minecraft\logs. Curse/Overwolf: If you are using the Curse Launcher, their configurations break Forge's log settings, fortunately there is an easier workaround than I originally thought, this works even with Curse's installation of the Minecraft launcher as long as it is not launched THROUGH Twitch: Spoiler Make sure you have the correct version of Forge installed (some packs are heavily dependent on one specific build of Forge) Make a launcher profile targeting this version of Forge. Set the launcher profile's GameDir property to the pack's instance folder (not the instances folder, the folder that has the pack's name on it). Now launch the pack through that profile and follow the "Mojang Launcher" instructions above. Video: Spoiler or alternately, Fallback ("No logs are generated"): If you don't see logs generated in the usual place, provide the launcher_log.txt from .minecraft Server Not Starting: Spoiler If your server does not start or a command window appears and immediately goes away, run the jar manually and provide the output. Reporting Illegal/Inappropriate Adfocus Ads: Spoiler Get a screenshot of the URL bar or copy/paste the whole URL into a thread on the General Discussion board with a description of the Ad. Lex will need the Ad ID contained in that URL to report it to Adfocus' support team. Posting your mod as a GitHub Repo: Spoiler When you have an issue with your mod the most helpful thing you can do when asking for help is to provide your code to those helping you. The most convenient way to do this is via GitHub or another source control hub. When setting up a GitHub Repo it might seem easy to just upload everything, however this method has the potential for mistakes that could lead to trouble later on, it is recommended to use a Git client or to get comfortable with the Git command line. The following instructions will use the Git Command Line and as such they assume you already have it installed and that you have created a repository. Open a command prompt (CMD, Powershell, Terminal, etc). Navigate to the folder you extracted Forge’s MDK to (the one that had all the licenses in). Run the following commands: git init git remote add origin [Your Repository's URL] In the case of GitHub it should look like: https://GitHub.com/[Your Username]/[Repo Name].git git fetch git checkout --track origin/master git stage * git commit -m "[Your commit message]" git push Navigate to GitHub and you should now see most of the files. note that it is intentional that some are not synced with GitHub and this is done with the (hidden) .gitignore file that Forge’s MDK has provided (hence the strictness on which folder git init is run from) Now you can share your GitHub link with those who you are asking for help. [Workaround line, please ignore]
MrChoke Posted September 16, 2018 Author Posted September 16, 2018 57 minutes ago, diesieben07 said: Yes, I do. And honestly, I have never navigated to a class manually in the file tree view. You have an IDE, god damn it, use it. "Search for class" is Ctrl-N in IntelliJ. But, if you must know: Clean sources are in projects/Clean/src/main/java, Forge-Patched sources are in projects/Forge/src/main/java. I do have an IDE, IntelliJ. And I did not execute "gradlew setupForge". Why? Because the readme you told me to read had that step under the ECLIPSE section, not the IntelliJ section. Maybe you have been living and breathing Forge and Gradle for years but I haven't. If the doco is not correct, guess what? I start asking questions. After running that command with IntelliJ, yes I have the forge sub-project now and it has "net.minecraft" in it. Quote
MrChoke Posted September 16, 2018 Author Posted September 16, 2018 1 hour ago, diesieben07 said: Actually, the Eclipse documentation is outdated. The IntelliJ section tells you to run the clean and setup tasks. The setup task is the replacement for setupForge. Well going back, looks like I missed the link to the video for IntelliJ that would have helped. I need to take a Gradle/Git tutorial or something as well. Quote
MrChoke Posted September 16, 2018 Author Posted September 16, 2018 1 hour ago, diesieben07 said: The video is not needed, everything is explained in the text version as well. OK... I completely started over. I realized everything I was doing was off of the 1.12 default branch which I don't want. I want 1.13.-pre. I wiped everything related to this off my PC. I went into GIT and even blew away my repo there as well. I followed the readme line-by-line this time, starting with re-doing the fork to my own repo (and choosing 1.13-pre as the default for it this time). Then cloning to a brand new folder on my PC. I followed the IntelliJ section, yes the text and got to where I opened "build.gradle" as a project. It started to build and failed. It didn't get as far as last time when I was going off of 1.12x. I got this exception when it was trying to configure the project: Caused by: org.gradle.internal.resolve.ModuleVersionNotFoundException: Could not find any version that matches net.minecraftforge.gradle:ForgeGradle:3.+. I attached a screenshot. I changed nothing. I pulled whatever was in 1.13-pre branch. Quote
Animefan8888 Posted September 16, 2018 Posted September 16, 2018 11 minutes ago, MrChoke said: I pulled whatever was in 1.13-pre branch. I dont believe 1.13 is in any way ready to be used or have a pr made for it. You need to use 1.12.2 Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator.
MrChoke Posted September 16, 2018 Author Posted September 16, 2018 3 minutes ago, Animefan8888 said: I don't believe 1.13 is in any way ready to be used or have a pr made for it. You need to use 1.12.2 Oh. I guess that makes sense since I was getting much further with 1.12. I thought since there is a 1.13-pre that people can start submitting changes to it. I'll go back to 1.12x and go from there. Thanks. Quote
MrChoke Posted September 17, 2018 Author Posted September 17, 2018 Ok, I finally did this right. I have a pull request for 1.12 with my change: https://github.com/MinecraftForge/MinecraftForge/pull/5150 Does anybody know what comes next? I assume it needs to get approved? 1 Quote
Recommended Posts
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.