Jump to content

Laike_Endaril

Members
  • Posts

    166
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by Laike_Endaril

  1. It looks like the method posted in the initial post is where the sync is happening. The lightning is being created here, in WorldServer.updateBlocks(): I left out most of the method because it's pretty long. There are some more conditions before what's posted but nothing that looks to me like it would be easy to alter, but you can look at it in your IDE if you want (line 392 in WorldServer class). I just wanted to point out that since the lightning entities are being newly created within the method, and being pushed directly to the method where they are sent to (nearby) clients, you won't be able to do an easy reflection hack to change a field for this. In order to literally change the course of lightning bolts, you would probably have to replace either the entire World class or the entire WorldServer class, neither of which I really recommend. I can also think of a byte code edit that would do it, but would also very likely make your mod incompatible with many other mods, so that's not a good approach either. All that being said, I JUST thought up a possible solution. This method in WorldProvider is part of the check which allows or disallows normal lightning behavior: public boolean canDoLightning(net.minecraft.world.chunk.Chunk chunk) { return true; } If you're ok with just redirecting lightning bolts in the overworld (and any modded dimension that uses DimensionType.OVERWORLD / WorldProviderSurface), you can create your own edited version of WorldProviderSurface which contains all the original fields and methods from the original WorldProviderSurface (there is actually only 1 field and 1 method; the rest are simply redirected to the WorldProvider superclass), and add in an overridden method for canDoLightning that returns "false" instead of "true". This will disable normal lightning completely. After all that, you'll have to add your own system to the game to reintroduce lightning. I would just copy the existing system in WorldServer.updateBlocks() as much as possible but add a special condition for your redirected bolts. If you decide to overwrite WorldProviderSurface with your own version of it, you'll need to replace the enum field for it in the DimensionType enum class, like this: Field f; try { f = ReflectionHelper.findField(DimensionType.class, "field_186077_g"); } catch (ReflectionHelper.UnableToFindFieldException e) { f = ReflectionHelper.findField(DimensionType.class, "clazz"); } Field modifiersField = ReflectionHelper.findField(Field.class, "modifiers"); try { modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL); f.set(DimensionType.OVERWORLD, WorldProviderSurfaceEdit.class); } catch (IllegalAccessException e) { e.printStackTrace(); } And if all this looks too complicated, you might want to reconsider redirecting lightning bolts! Edit 1 ========================== Almost forgot to say that Voidwalker is the one who familiarized me with the internal structure of enum classes, and how to properly reflect into them, so if you use this method you can thank him for that.
  2. Low tick rate can be hard to debug and often involves some trial and error, so try the easiest/fastest possibilities first, like the one Cadibloo suggested. Try setting RAM a bit lower and see what the tick rate is. Then try setting it a bit higher and see what it is (though ofc make sure not to set it over 12G even for testing if you have 16G). If neither of those make a difference, rule out RAM amount and try something else. Also, if you're on Windows, open the task manager while the game is running and see if anything is getting maxed out. It's even possible (but not very likely) that the SSD access is getting maxed (if that's the case it's probably not due to minecraft alone; I've only really seen this happen while an automatic backup program was running in the background). Too many possibilities for someone to pinpoint it for you, so you'll just have to experiment. Btw, you never said if you were on a freshly created world or not. If you're on a world that already has stuff in it, make a new one and test there in case it's something in the old world (especially if you got a world save from someone else to load up). By freshly created I don't mean you have to make a new one each time - just make sure it doesn't have any existing tech devices, etc.
  3. If you mean in RAM, then yes, but if the alternative is to keep a copy of the previous value of each config option and reset them to what they were before joining the server, well...that also keeps a 2nd copy of each config option. Both methods will also require you to reset something when leaving a server. Other than that, my method only has one advantage. Because mine never touches the client config directly, even if the client's game process is interrupted while connected to a server, their config file will not be corrupted...whereas if you are changing the actual client config, even temporarily, using the server's settings, the server's settings will be their new "client" settings from then on out until they either manually change them or log onto a different server and the same thing happens there. You could prevent that issue by saving the entire client config to a separate file (not a config file) and deal with saving/loading that, but that would be an over-complicated workaround. And ofc. when I say "the client's game process is interrupted" I mean either... 1. The game crashes 2. The client user ends the game process 3. Probably if the client user presses alt+f4, though I haven't tested that so don't take my word on it 4. The client's power goes out 5. Possibly if the client's OS decides to suddenly force a restart to install updates... It's a bit of a niche advantage, but I don't really see a disadvantage. That said it's not my mod, that's just how I would do it. Edit 1 =================================== Just in case you were thinking there was a 2nd config FILE, no there is not. I may have named the class "CombinedConfig" but it doesn't generate or use a config file itself.
  4. This world seems to be a Biomes o' Plenty world. If BOP is not installed, you probably won't be able to load it. If that's not the issue then... The next thing I would try is disabling either shaders or optifine, or both. As a side note... It looks like the game is running on only 2G of RAM. That seems low to me for modded minecraft so if your system has more than 4G RAM total I'd increase it a bit. If you have 4G total, I would leave it as is. If you have 8G total I'd give it 6G (and not run any other intensive programs while playing minecraft). If you have 16G total or more I'd go with at least 8G for minecraft. I'm actually running it with 16G but I don't expect most ppl to have that much to spare (I have 32G total) and in most cases 8G is enough. I don't think this is what caused the crash you posted, but I wouldn't be surprised if it caused an issue later.
  5. I have some unfortunate news. Despite the solution in my previous post working for vanilla mob spawns (but making them burst into flame immediately if set low during the day), it did not allow the Grue to spawn. After realizing this, I also tried the second approach of overwriting the WorldProvider subclass for the overworld referenced by the DimensionType enum (DimensionType.OVERWORLD normally references the WorldProviderSurface class). The result was that vanilla mobs can not only spawn, but also no longer burst into flame, and their AI acts as if it is dark as well (spiders attack). The fog is also darkened, but the blocks themselves are not. The Grue does not spawn using this method either (but here's the code) Main mod class: WorldProviderSurfaceEdit, a substitute for WorldProviderSurface: Grue aside, I expected this method to dim the blocks themselves, because I thought that the blocks' sky light levels were based on the calculation in World.getSunBrightnessFactor, for which I'm currently redirecting every call to my own function (while in the overworld, at least). This doesn't appear to be the case, which is confusing because in a normal vanilla game, as we all know, the blocks visually darken (and the sky light level lowers, as shown in debug / F3) as the sun sets, and I can't think of a reason to have a second function that calculates the base sky light level. For now, I will continue to search through the backend for where the blocks' sky light level is being determined. I wasn't sure why this would be relevant for the new approach (because as I said before I assumed the base light level would only ever be calculated in a single method, which I've overridden), but I'm looking through WorldServer.updateBlocks right now to see if I can find anything.
  6. I assume you mean one at a time and not both at once. I'm also assuming you mean it happens even on a newly created world? Which would mean a profiler like the "laggoggles" (one word) mod probably wouldn't be that helpful? Well here's a link to it just in case you feel like trying it anyway (to use it, check for its key bindings in the settings menu; it's not an item): https://minecraft.curseforge.com/projects/laggoggles?gameCategorySlug=mc-mods&projectID=283525 This could possibly be a sign that the tick rate is lower than normal. If the tick rate (or ticks per second / tps) of the server (including on a single player world) is lower than normal, then all mobs, projectiles, etc will look like they're moving slower and/or choppier even if your FPS is still high. You can check whether this is the case easy enough, just go into a single player world and type this in chat: /forge tps Look at the part of the output that says "Mean TPS". Hopefully it reads 20, or close to 20. If it's much lower, then you have TPS issues, which means your CPU can't handle the amount of computation the modpack is asking it to do. In any case, finding out for sure whether it's TPS or FPS is probably the best first step so try that command above and see what you get.
  7. I started writing the reflection for altering World.skylightSubtracted when I realized that the method for writing to the field is already public anyway: public void setSkylightSubtracted(int newSkylightSubtracted) { this.skylightSubtracted = newSkylightSubtracted; } So I went ahead and tried that in the WorldTick event like so: @SubscribeEvent public static void worldTick(TickEvent.WorldTickEvent event) { event.world.setSkylightSubtracted(15); } It had the expected result based on what you said about the timings, ie. ...Monsters can spawn during the day, but... ...Block light levels are unchanged (because the light level is being recalculated before then) It's an interesting result, having zombies and skeletons burst into flame the moment they come into existence. Luckily, my main interest is simply making nighttime a bit darker so this isn't an issue for me. As usual, this conversation has been very educational! Thanks again Voidwalker, I think I've got the rest of this mod covered (there's really not much else to it). And as a bonus, I know to look out for the final modifier on enums from now on.
  8. I actually attempted this, but had no success. I'll admit I don't have a lot of experience with enums, though. I'll re-explore this option. Well, the original goal was to create a companion mod to Grue and Hardcore Darkness which allows Grue to spawn on the surface at night (because Hardcore Darkness is only visual and Grue doesn't have an applicable config option), but at this point my curiosity has me by the ear as well. It's being called every tick in WorldServer to calculate the current sky light as well, which was what I was worried about, but now that I think about it, if forge's WorldTick event fires immediately after that and before the data is sent to the client, I should be able to overwrite the field during WorldTick. I'll probably try this first. I don't know a lot about the threading on the backend but hopefully I'm safe in assuming that at the very least, WorldServer.tick() and forge's WorldTick event always fire in the same order and at the same frequency? In any case I'll try it.
  9. Aye, a mouthful. I'm currently attempting to alter the overworld sky light levels in a way that won't break a users game if they load a world that was created before my mod was installed. I was hoping there would be a base sequence in an array or something that was used with interpolation, so I could simply reflect my way into the data and change it. Unfortunately this doesn't seem to be the case; as far as I can tell, the sky light level is determined in World.getSunBrightnessFactor: This method is in turn ONLY referenced in exactly one place...if no other mods are referencing it, that is...which is in WorldProvider.getSunBrightnessFactor (this method simply returns the result of the first method posted, unless overridden in a subclass). All these being methods, I don't see any way of altering them directly. I've also considered creating my own class based on one of those 2 classes, or on WorldProviderSurface, but even with that, I don't think there is a way for me to inject my new version where the old one was, because it's only being referenced in an enum called DimensionType: And afaik you can't overwrite a previously written enum value, so the register method in there won't do me any good either, right? I continued searching through for a few hours, but haven't come up with a good solution. At this point I'm thinking I may have made a mistake somewhere overlooked something much simpler and need someone to bash me over the head again.
  10. Alright, so I think there's a misunderstanding here. Correct me if I'm wrong, but to me it looks like Kinniken is saying that the code handling his achievements is actually automatically detecting villagers from other mods (presumably completely procedurally, without any specification needed), which would allow a great amount of flexibility without the authors of said mods actually doing anything at all? Basically, without other mod/modpack authors doing a thing, it automatically detects other mods' villagers? Wouldn't a system like that cause all kinds of issues if it were rewriting portions of JSON every run? Quite possibly portions modpack authors had changed? IF I'm actually right about all that, wouldn't all the workarounds beyond that point have their own sets of issues with more workarounds needed? *IF* I'm right about that stuff above...now I'm curious.
  11. That's actually the first thing I looked at when I started. It wasn't nearly as helpful as the video imo (in fact, if you follow steps 1-6 on that page, as is logical, and then get down to the intelliJ section, it basically says "oh, and I hope you stopped after step 3 above"; it's not well organized, should have explicit sets of steps for each IDE)
  12. Great!
  13. Don't worry too much about that. Just post the full code (including where dt is defined) so myself or someone else can see what's going on.
  14. A lot of things *look* wrong to me in that code, but may not necessarily be wrong for what you're trying to do, so without making too many assumptions, I *think* that the *most likely* issue is that you should be using "partialTicks" where you're currently using "dt". In fact, "dt" isn't even declared in the code you posted, so I can't say much about it (though I assume it stands for "delta ticks"). I'd try replacing "dt" with "partialTicks". If that doesn't do what you're looking for, try posting the full code so others can have a better understanding of how it's set up. Edit 1 ====================================== I'm also pretty sure that this line: this.particleX += vx; should be in updateScreen, after the other 2 lines that are already there. Edit 2 =================================== Actually if you could post the full code that would be fantastic lol...I'd like to get a better idea of what's going on because otherwise I might be giving bad advice.
  15. Backslashes in a string in JSON indicate escape sequences. So your attempted escape sequences in this line are "\c" and "\g". I would try using forward slashes for the directory paths instead.
  16. What Voidwalker meant is that if you use deltaPartialTick in drawScreen it will have the effect you want, which it sounds like you've already done. If you use it in updateScreen, it's still only running your code 20 times per second, so the interpolation won't do you any good there. It would be the same without using interpolation at all afaik. So in the end, for any smooth animation, you want drawScreen with deltaPartialTick. This means you're setting/changing the actual position, etc. (not the *drawn* position) each tick Notice here he said "each frame", meaning in drawScreen
  17. Oh dear God lol...I forgot that the entries in the config file are ordered alphabetically and not in the same order you put them in (in the java class). Which annoys me to no end, btw... Thanks again Voidwalker. I feel pretty dumb right about now lol
  18. I just added a String in my config file handler class alongside all my booleans, ints, etc. and it isn't posting to the newly created config file. Are strings not supported? And if they're not, is the best way to go about this a separate file handled by my own file handler, or is there a little trick I can use to get a string working here? Config handler class: Actual config file, after being deleted and recreated:
  19. Laike_Endaril

    .

    Right, got it.
  20. I was thinking something more like this... Normal config class: import net.minecraftforge.common.config.Config; @Config(modid = YourMod.MODID) public class ClientConfig { public static int powerLevel = 9001; } CombinedConfig, the class handling the combination ofc: At this point, you should simply be able to reference CombinedConfig.powerLevel throughout the rest of your project. Or you can put a getter in CombinedConfig and make that variable private if you're worried about public access to it.
  21. Laike_Endaril

    .

    On a dedicated server, or on the client when in LAN mode, you have access to the server console commands (though in the latter you still have ClientTickEvent anyway). I just wasn't sure from the OP's post whether he was talking about typing something in *on the client* or typing something in *on the server*, since it wasn't specified. Or am I missing your point? By "server" do you mean a certain part of the server that we have access to, or the entirety of the server, including the command console?
  22. The way I was thinking of it, I'm fairly sure that would not be the case, but I could be wrong. I might dig into the backend classes and look through them more later. Thank you! I was looking way too deep into the system, as I tend to do.
  23. I'd like to send a direct English death message to the clients instead of a key. My use case: I have a basic combat tagging mod, which is already working with the internationalized key being sent to the client and being re-localized client-side with the lang file, however... 1. The only thing this mod does on the client side is translate the death message key using the lang file, nothing else happens client-side 2. I'm already sending direct English chat messages for when players enter/leave combat. Maybe those could be programmed to work with internationalization as well, but... 3. I'm not likely to ever add any languages to this mod; it's not a necessity. In the end, a death message is a death message, and even if you can't understand exactly what it says (due to having a different native language), you'll recognize it (and even the cause of death) once you're used to seeing it. Same goes for the enter/leave combat messages. They have square braces and are color-coded. I could make the text for them say "h9fkjehfkajn" and everyone would still figure out what they mean. If I make a CONTENT mod, I will most certainly use internationalization methods, but this is not a content mod. It's a utility. If I can de-internationalize the death message being sent from the server to the client, I can make my mod server-side only, instead of requiring clients to have it installed just because the death message spits out an ugly keycode. This will increase its utility value. As a side note, wouldn't the internationalization system be better if it used one native language's actual message AS the key, instead of "death.attack.whatever"? Isn't it basically the exact same thing, other than being a proprietary string instead of one chosen by the mod programmer? Ie. couldn't it work the same if I simply sent "%s was smote for their cowardice!" from the server to the client, and on the client side, the lang file for a different language contained this: "%s was smote for their cowardice!"="%s <enter foreign translation here>!" Given that the internationalization backend were programmed to accept that format? Wouldn't the only difference between that and the current system be that if the key was not present on the client, it would use the English string with a real meaning ("was smote!") instead of a string that looks like code? (The concatenation the backend system uses to construct said keys could still be used as-is; it would just need one more very basic layer in between those keys and the system I'm talking about) /rant Anyway, if someone knows a good way to intercept and alter this "death.attack.smite" string before its send off to the client, I'd greatly appreciate it. Prepared to take a bit of criticism as well, but I don't see a real down side to my proposition regarding how internationalization is handled.
  24. For intelliJ, I got my modding environment set up using this video: https://www.youtube.com/watch?v=RZ66HdNkank The only real mistake he makes is not adding "\run" to the end of his configurations around 15:20 (he corrects it later, but not before it has some minor consequences). I already had many years of experience with java and intelliJ before I started modding though, so I'm not sure if it will be as understandable for someone who isn't already familiar with java/intelliJ, but it's something. If you're getting into programming you'll have to get used to experimenting and blowing stuff up once in a while anyway, so don't be too afraid of making a mistake. If things don't get set up right you can always uninstall and start over.
  25. If you only want the variables normally controlled by your config to change on the client *for the current session* I would not directly overwrite the variables being controlled by the client's config at all (backup or no). Instead, I would use two variables; the normal client config variables, and a separate set of variables sent by the server, which take precedence over the client ones. This will prevent any possibility of the actual config file on the client being changed. On the client side, you will of course need to clear the values of the "server-set" when disconnecting from the current server.
×
×
  • Create New...

Important Information

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