jabelar
Members-
Posts
3266 -
Joined
-
Last visited
-
Days Won
39
Everything posted by jabelar
-
One thing you're not understanding is that you can think of NBT as a map data structure that has keys (called "tags"). So it is not just one tagged entry, rather it is a "compound" of multiple tagged entries. When you use the set method, it just edits the entry for the thing that is tagged with the same tag key. No need to recreate the whole compound, the single entry can be edited directly.
-
Cannot Extinguish fire on player death when Manually Respawning
jabelar replied to jredfox's topic in Modder Support
If you traced it with breakpoints, it should be obvious. You should see that when you call extinguish that the value changes and then you keep following and see if something else sets it back again. -
Also another problem with your packet code is that you're reaching across logical sides. You can't access Minecraft() class directly in your onMessage() method. You'll need to call a proxy method.
-
You need to trace the execution. Like you've already done a bit of, put console statements throughout your code (or use debug mode in your IDE). It should be really obvious quickly -- what ID does it think it is getting? Does that id match what you sent? Does that id match the id for the particle you intended?
-
Guys you might be confused because many people will put the code for both classes in a single file. But they are still separate classes. if you think about it, the message itself gets instantiated every time it is sent, whereas there should be a single handler. The general concept is: 1) Make a class that extends IMessage. 2) This class can have fields representing the payload information, and you need a constructor that takes in that information and assigns it to the field. (Note I think you also need a default constructor with no parameters as well.) 3) You need to override the toBytes() and fromBytes() methods to put your field information into the ByteBuf that is passed in. You should use ByteBufUtils for converting your information. 4) You make a separate class that extends IMessageHandler 5) In that class you need to override the onMessage() method. The message instance will be passed to you and you can access the fields and do whatever you need to do. Note that due to threaded nature, for packets that go from client to server, I think you need to encapsulate your code as a Runnable. 6) The return value for the onMessage() method should generally be null. It is possible to create a confirmation method where the receiver sends a packet back to confirm receipt and unerrored processing, but that is a more advanced topic. I have an example here: https://github.com/jabelar/ExampleMod-1.12/blob/master/src/main/java/com/blogspot/jabelarminecraft/examplemod/networking/MessageSyncEntityToServer.java
-
As Draco18s is pointing out, you need to fully understand how Minecraft handles blocks. What you just said is closer to what you need to do, but we want to make sure you understand why. Basically, from a "normal" object-oriented sense you would have a Block class and you would create an instance of it every time you had a block placed in the world. Logically this is good, but it has a bad consequence for performance -- the number of instances gets very large very fast. In just one chunk there is 65k possible positions to place a block so a world of just 20 chunks is going to have 1.2 million possible blocks. So if there was a instance for every block placed in the world there would be a serious problem with memory. So instead, Minecraft decided to have a single instance of each block class and instead create a "map" of where they are placed. That works great if the blocks are simple and unchanging as it is a very compressed format. However, of course they then added the idea that some blocks might want to be varied. To do this they allowed a little bit more (just 4 bits) of data for each block position to allow variation -- this was called metadata. Some blocks used this for things like color (dyed wool), and some used it for direction, etc. But the key point is that the information that represented these things was stored in the "map" NOT in the block instance or class. There was no field in the wool class for the color, rather when the wool was rendered it looked up the data stored in the world data and applied the color then. Now, the block class code sometimes needs to behave differently based on the metadata. Originally that was literally a matter of decoding the 4-bit values (that is why various Minecraft wikis and such you'll still see tables showing the values). But eventually this got more advanced implementation using properties and block states. Basically every combination of values of the properties creates possible blockstate. But ultimately these are still stored in a limited 4-bit mapping. So putting it all together it means that you shouldn't confuse scope (like public or private or static or whatever) with this issue. Rather you must contain all your per-position information within a property, not within fields of the class itself. Okay, assuming you understand all this... just look at other blocks which already do similar things, like a furnace or torch or something, and adapt their code to your specific need.
-
No that won't help. As I mentioned above there is actually only one block instance in the whole game. You cannot put anything in fields that will be different in different positions. Those things either must be values that can be calculated in real time, or if they need to be remembered they must be in a property. Basically you don't need your field at all. The property is supposed to contain the value.
-
Okay. But then you still run into the problem that you can't have a direction field in the block class like that. It will have the same value for all blocks placed in the world.
-
That's your first problem. A static field is shared among all the instances of that class. That means all your instances will face the same direction. Beyond that though, the answer is not simply to remove the static because you need to know is that in Minecraft a Block instance is a "singleton" -- there is only one in the whole game. So any position-specific value needs to be stored in a property (which helps form the block state). Basically your direction field won't work. And if you expect the range and height to vary on a per-block basis those won't work either. Your fields need to either be constants, or something that when changed is meant to change all the blocks in the world at the same time. So really a "block" in the Minecraft world is a Block instance which contains all the common stuff, modified by a little bit of per-location state information.
-
Minecraft#theWorld.playerEntities doesn't seem to contain all players
jabelar replied to ZhabaKlava's topic in Modder Support
Yes, when you're registering entities one of the things you specify is the entity tracker, which includes the range. But as diesieben07 pointed out, you can't get the rest of the players unless the server sends it (which requires a server-side mod) so your original original idea is only possible if the radius that you're interested in is less than the tracking distance for the client. If that is true, then you're good to go. -
Why would the packet need to specify the entity ID? When you send the packet you've already decided to spawn the particle and you know the location you want to spawn it at. Why would the client need the entity information? You need to tell the client just enough information to get what you want visually. You know the position (the server can add a bit of randomness) and the server can set the speed (with some randomness). If you let the client set the randomness technically every player sees something a bit different (that usually doesn't really matter), but I kinda like the idea of all of them seeing same. In any case, the minimum information you need to send is just the origin position (and client adds randomness and speeds) and the maximum you could send is position and speeds including randomness.
-
Yes, but one other thing you need to understand is that programming is a very exacting thing that depends on detail, organized thought and accurate semantics and so it attracts a certain type of personality that is very factual and efficient and therefore may come across to "normal" people as being blunt. With diesieben07 you know you're getting accurate information and that is worth a lot, and if he says go learn Java then it is the right suggestion. Another thing to consider is having empathy the other way. Imagine being an expert musician and having to teach beginner violin. It is actually "painful" for a good musician to hear something out of tune, and so when someone is writing code that is "out of tune" it is very hard for an expert programmer to not get impatient. Then imagine that every day another half-dozen beginner violin players show up on your doorstep playing out of tune and asking for help. For your own sanity you basically have to get efficient at shooing some away and picking the ones that you think you can actually help. Basically I'm saying there is a reason why the personality of kindergarten teacher tends to be very different than a doctoral math professor.
-
Sure, but it is literally at the top of the forum constantly "pinned" there. Also, a "harsh" statement that you need to learn Java better is really the truth. Basically there comes a point in trying to help someone on the forum where you realize that they are missing something fundamental about Java itself. Since Java is so well covered elsewhere, we do actively shoo people away to go do their homework. I guess that could be perceived as "unwelcoming", but ultimately it is accurate and for your own good. Think of it more like a tough gym coach telling you you're out of shape -- it might sting to hear it but it is still worthy advice.
-
To continue to dig into it, you need to further observe the execution. You need to see if the AI shouldExecute() is getting called at all and if it is whether it is returning true. You should set a breakpoint on that method and use debug run mode in Eclipse to see if it hits that line (breaks) and then inspect the field values as well as step through the rest of the AI execution. Depending on what you find, there will be different solutions. If it isn't being called at all then it means that either the AI task isn't properly on the list, or that it is being pre-empted -- AI only runs depending on the priority combined with the mutex bits. For example, if certain other AI is already running it may never actually check your shouldExecute(). Anyway, using breakpoint and debug mode should tell you a lot about what is going on.
-
When debugging this sort of thing, you simply need to observe the execution. I usually do that by adding console print statements at every interesting point including printing out the values of key variables. In your setMadChickenDisease() method, you only set the attack AI if the bool parameter is true. However, are you sure that you are calling that method properly with bool value as true? To check that you should print out the value of bool as first line in that method. I suspect that you're having trouble with that because it looks like you call the method using some value you get from a tag compound so I have no idea if that is set properly. One other thing that comes to mind is that in your target task you have set the checkSight parameter to true. That is probably what you want, but it is possible that chickens, which have very low eye height, might have trouble actually seeing other chickens since maybe even grass could hide them or something. You might want to try setting that to false for testing purposes.
-
I know this but was teaching a beginner about what a weighted system means. For testing purposes I was basically telling the OP to copy a number used by vanilla, but I could see him/her then going off and adding a dozen more entities later with the same number, so I wanted to warn him/her about that. Also, although it is true that there is a good reason to limit the total entities, it is also reasonable for a modder to want to add a bit more prolific entities to the game. This is especially true where game balance is concerned. Like if I wanted to add flocks of seagulls, I wouldn't necessarily want food entities like pigs to become more scarce. So it is worth them understanding that they are not really adding to the overall fauna but rather substituting spawns and making existing fauna more rare.
-
[1.12.2] Prevent sand/gravel blocks from falling
jabelar replied to kevinmd88's topic in Modder Support
It would work fine. What I was suggesting is replacing it in the registry. Therefore, as far as all vanilla and other mods are concerned it would be sand/gravel. That's part of the benefit of a registry. This has nothing to do with modifying base classes, so the warnings about that aren't applicable. The whole point of modding is changing behavior. If there is a conflict in what the mods want to do that is a different problem -- if one mod is preventing the sand from falling and another mod wants to make it fall faster then no interface is going to help that. LexManos and PaleoCrafter (both major Forge contributors) support this approach. See their discussion here: https://github.com/MinecraftForge/MinecraftForge/issues/4079. "Overrides" in the registry are an intended feature. -
Yes, just handle the check spawn event and modify the result based on whatever condition (in your case nearby entities) you want. At least that is if you want to affect vanilla entities. If this is only for your own entity you can just override the checkSpawn() method in your entity class to do what you want.
-
You're right, but the the reason I made my statement about the lower being more common is that entities like pigs have weight of 12 and entity like zombie has weight of 100. However, I see now that each list (creatures, monsters, water creatures) the vanilla weight levels are quite different. Tuning weight numbers can be a bit tricky because they are relative to the total weight. In other words, every time you add an entity, the chance of all other entities spawning gets a bit smaller. But that shouldn't be an issue in this case. In any case, my point was that he should use numbers similar to the vanilla entities when testing. Since he's looking at monsters, he should have number around 100 to spawn with similar frequency to zombies and skeletons. A number of 1 should be less frequent than a witch which is 5. If you want to see the default values, look at the constructor for the Biome base class. Anyway, we need way more code than that to help you solve this problem. It obviously isn't this line of code causing the trouble. Is this problem related to a custom biome? If so, maybe you're calling the generation code way more times than you think (and therefore generating more of the entity). Or something like that.
-
I'd like to suggest an alternate approach. I think what you're asking to do is to modify a vanilla rabbit's behavior without requiring the client to install a specific mod. If so, in that case I think you can simply spawn regular rabbits (no need to register a new type). Instead you just replace the AI task lists for the vanilla rabbits whenever they join the world by handling the join world event, checking for instanceof EntityRabbit and if true then simply change the AI task lists. The AI task lists are public fields so you're allowed to access them directly. Would that do what you want to do? Or otherwise be more specific about what you want to change about the vanilla rabbit as there may be server-side hooks that are easier than fully replacing rabbits in the registry.
-
The general idea with "noise" generation is that they are just different functions for randomization. You have a threshold for placing blocks based on the output of that function. The function also usually has some input parameters to further control the amount of randomness. All this means that the outcome depends on a lot of "tuning" because you have a lot of "knobs to turn" to change the behavior. The random functions used in game world generation are often things like Perlin. This describes a distribution of randomness that seems more natural. For example, if you just used a "flat" random function you would get a result that would be actually random -- there wouldn't be clusters of hills, flat areas, etc. Perlin noise is well documented so you should check out information like: http://flafla2.github.io/2014/08/09/perlinnoise.html. Normally it is "best" to combine the Perlin noise on top of a more algorithmic structure. Like in the link above it talks about how you can make artificial handwriting by adding a Perlin noise offset to the line to emulate the shakiness of a real human hand. So for your islands you could use a sort of "reverse cave" approach. Instead of carving out a space of air within existing stone, you could create a space of stone in the air. That might be pretty cool. Or you could be more controlled about it and literally have logic that decides (also randomly, but could be traditional flat random chance) to make a floating island and then you could procedurally fill in a space in the air with stone and then use noise to carve away the surface to create more randomness. And so on. Ultimately it will take a lot of tuning but the basic ideas are the same -- you need some logic that decides that placing blocks for floating island is needed and then you add some noise on top of that to give sense of natural randomness.
- 1 reply
-
- 1
-
The only situation where you have to by default worry about performance and code size is in "embedded" programming -- code that goes into an inexpensive device like a toy or a networking router. Otherwise, when coding for a full-size computer the main place you have to worry about performance is in things that don't scale well like large databases, tree algorithms, recursive algorithms and convergent iteration. For example if you're trying to do "generative adversarial networks" in AI you would care about performance a lot. In Minecraft there are only a few cases where people get in trouble with performance. The main one is by not understanding the sheer number of block positions there are in even a seemingly small area -- structure generation, block pattern detection, alternate pathfinding algorithms, all fall in this category.
-
Making a 1.12.2 mod compatible with a 1.11.2 client/server
jabelar replied to Stenbergcsgo's topic in Modder Support
The way I recommend for doing multi-version development. 1.) Use git and github to provide revision control for your code. Make sure the build.gradle is under the revision control (this is key to quickly switching between the versions). 2.) Have your master branch with the latest version of the code. 3.) Create a branch for each version of the code. 4.) Whenever you plan to work on a certain version, clone the repository and do the gradlew setupDecompWorkspace and gradlew eclipse. 5.) In Eclipse, import each as a separate project. 6.) Now as you develop you can keep the things that are different separate, but you can also easy merge code across versions where appropriate. Basically, standard version control. In most programming situations you are developing a couple different versions simultaneously. I recommend setting up all your modding developments this way from the beginning because you undoubtedly will want to upgrade at some point. -
ItemStack has a number of methods related to this. Did you look at the type hierarchy to see the list of methods? You can check if it hasTagCompound(), and there is getTagCompound() and a bunch of other related methods.
-
Create a new type of Energy using forge's integrated Energy System.
jabelar replied to EmeraldJelly's topic in Modder Support
This one might help: https://www.planetminecraft.com/blog/forge-tutorial-capability-system/