Jump to content

[1.16] Boson Modding Tutorial


Recommended Posts

Hey Everyone, this is FledgeShiu.

I bring the 1.16.3 Modding Tutorial. This Tutorial is translated from my same name tutorial which written by Chinese.

I’m not a native English Speaker. So that, this tutorial may have a lot of grammar and words problems. If you find any problem please tell me.

If you have any question or feedback, welcome join my Discord Server .


Notice: It's still in translation.

Tutorial Link


  1. 1. Introducation
    1. 1.1. What is Forge?
    2. 1.2. How Minecraft Works?
    3. 1.3. Development Model
    4. 1.4. Core Concepetion
  2. 2. Development Environment
    1. 2.1. Setup Environment
    2. 2.2. Introduce Environment
    3. 2.3. Customize Mod Info
  3. 3. Item
    1. 3.1. First Item
    2. 3.2. Model and Texture
    3. 3.3. Item and ItemStack
    4. 3.4. Item Group
    5. 3.5. Food
    6. 3.6. Sword
    7. 3.7. Tool
    8. 3.8. Armor
    9. 3.9. Item Property Override
  4. 4. Localization
  5. 5. Block
    1. 5.1. First Block
    2. 5.2. Block and BlockState
    3. 5.3. Block's Model and Texture
    4. 5.4. Block with BlockState
    5. 5.5. Not Solid Block and custom model
    6. 5.6. Render Type
  6. 6. Special Model
    1. 6.1. Obj Model
  7. 7. TileEntity
    1. 7.1. First TileEntity and Data Storage
    2. 7.2. ITickableTileEntity
    3. 7.3. TileEntity's Data Sync
  8. 8. Special render
    1. 8.1. IBakedModel
    2. 8.2. TileEntityRneder
    3. 8.3. ItemStackTileEntityRenderer
  9. 9. Event System
  10. 10. Network
    1. 10.1. Network Packet
    2. 10.2. Network Security
  11. 11. Entity
    1. 11.1. First Entity and Data Sync
    2. 11.2. Animal and AI
  12. 12. Capability System
    1. 12.1. Capability from Scratch
    2. 12.2. Use Predefined Capability
    3. 12.3. Attach Capability provider
  13. 13. WorldSavedData
  14. 14. Gui
    1. 14.1. First Gui
    2. 14.2. Container
    3. 14.3. HUD
  15. 15. Fluid
  16. 16. World Generation
    1. 16.1. Ore Generation
    2. 16.2. Structure Generation
    3. 16.3. Customize Biome and World Type
    4. 16.4. Customize Dimension
  17. 17. Data Pack
    1. 17.1. Recipe
    2. 17.2. LootTable
  18. 18. Data Generator
  19. 19. Command
  20. 20. Advancements
  21. 21. Configure
  22. 22. Potion
  23. 23. Paticle
  24. 24. Sound
  25. 25. User Input
  26. 26. Compatibiilty
  27. 27. Access Transformer
  28. 28. CoreMod
Edited by FledgeXu
Link to comment
Share on other sites

I guess I will do a review of this too and my opinion on what should be fixed.

--- 1.2 ---

Not particularly a great explanation on distinguishing the four sides. Also only reviews one of the few ways to ensure that you are on the correct logical side/thread.

--- 2.2 ---

build.gradle is glossed over again. You need to set information such as version, archivesBaseName, and group just for basic gradle building. This is not to mention it will not work with data generators.

--- 2.3 ---

You do not own boson.tutorial.com. The package name should be the reverse DNS of your site appended with the modid, which in this case would be 'com.v2mcdev.boson.tutorial'. Or actually the modid is boson so 'com.v2mcdev.boson.boson'.

For a personal note, a Utils class is not needed for this and will confuse users trying to understand as they will copy-paste. It's also a waste of an object currently as I'm updating this as I go along.

mods.toml is completely glossed over just inputting parameters and not really explaining them. Also, not all variables listed are present in the default toml. You also seem to remove any dependencies within the toml. Although they are optional, they are good checks to make sure your mod is being run on a supported version.

--- 3.1 ---

Hardcoding parameters again instead of using the superclass instance. It's a waste of resources.

Explain the underlying structure of DeferredRegister and show multiple ways to achieve the same solution. You can also explain the usefulness of the extra layer of abstraction.

You seem to be leading up to hardcoding the same method reference multiple times. Store an object reference and pass that between every instance provided.

--- 3.2 ---

This is the old way of creating JSON files. Use data generators and template models.

Textures should be explained more thoroughly. They do not need to be one to one or preferably no larger than a specific size. It should be these reasons for how UV mapping is handled for 16x16 textures. However, that needs to be explained.

Personal note, should include differences in PNG saving formats in case people wonder why their alpha is rendering black.

--- 3.3 ---

Singletons and flyweight objects are the words you are looking for.

They are not really the same properties or default behavior. It's just what a singleton is.

Don't say to determine if an ItemStack is null. An ItemStack is never null. The item singletone it may be holding is null, declaring the stack being empty. That should be explained.

--- 3.4 ---

Static final variables should be in upper camel case.

Object creation is wasted again. Can just be used as an anonymous class without extending.

--- 3.5 ---

Should explain the reason of deferring the EffectInstance call.

Should not be private as other mods may want to use your food item as well.

Hardcoding parameter (3.1-1)

This could probably be covered all in one page as it is a property that could be reference in 3.1.

Data generator (3.2-1)

Upper camel case (3.4-1)

--- 3.6 ---

Copies vanilla implementation to a tea. No explanation provided.

Should explain the relevance of lazy variables. Although a Java topic, still a good review to those who are just used to algorithmic programming.

Hardcoding parameter (3.1-1)

Upper camel case (3.4-1)

Data generator (3.2-1)

--- 3.7 ---

Hardcoding parameter (3.1-1)

Upper camel case (3.4-1)

Data generator (3.2-1)

Once again, no explanation of parameters.

--- 3.8 ---

Copies vanilla implementation (3.6-1)

Lazy explanation (3.6-2)

Upper camel case (3.4-1)

Armor material name must be prefixed with mod id.

Bit of missed translation.

Needs to explain why a texture goes in a certain place.

--- 3.9 ---

Hardcoding parameter (3.1-1)

Upper camel case (3.4-1)

Data generator (3.2-1)

Choose one method to create listeners, not use multiple different ones.

--- 4 ---

Data generator (3.2-1)

--- 5.1 ---

Probably could use a better explanation between the relation of blocks and items.

Hardcoding parameter (3.1-1)

Store an object reference (3.1-3)

Upper camel case (3.4-1)

--- 5.2 ---

All blocks are blocks. It's not a good idea to think that all singletons are flyweight objects. Two distinct types. Each specific tile in the world is represented as a BlockState which holds the Block instance.

The BlockState does not store the position.

Not a clear explanation of states.

Position attributes are not unique to a block. A position is mapped to a BlockState.

--- 5.3 ---

Data generator (3.2-1)

Textures should be explained (3.2-2)

The loading process is highly oversimplified and personally not a good explanation.

--- 5.4 ---

A property should never be non-final or private. Otherwise, you will not be able to reference it outside of your current setting.

Personal note, a property should usually default to a non-initialized value (eg. boolean -> false, int -> 0). Enums are special cases.

Data generator (3.2-1)

Bit of missed translation (3.8-5)

--- 5.5 ---

No point in a static block.

VoxelShapes should be as simple as possible.

notSolid is used for a few other things as well including lighting.

They are completely explainable. The first method checks whether the block is being placed within a water fluid. The second method checks if the block is being updated with a fluid and if so schedule a fluid tick for that block. The third checks the fluid to grab from the block itself.

Upper camel case (3.4-1)

Data generator (3.2-1)

This frame texture makes relatively no sense as it literally could've just drawn a cube with a hole in the center and wrapped the UVs around that.

--- 5.6 ---

Hardcoding parameter (3.1-1)

Upper camel case (3.4-1)

Client code isolation.

Multiple different calls to the same event with no change in priority.

Needs better explanation of concurrency.

--- 6.1 ---

Hardcoding parameter (3.1-1)

Upper camel case (3.4-1)

Data generator (3.2-1)

Details on object model mapping not present. Should explain more.

All models are centered around (0.5,0.5,0.5) and should be between (0-1) or their conversion to units (0-16).


Chapter 7 and onwards are empty. No review is applicable. I probably missed a few things as I glanced over them, but these should cover the necessary major changes. Please consider updating your post to include these.

Link to comment
Share on other sites

@ChampionAsh5357 ,Thanks very mush. 
The most of your advise is useful and your review is amazing. However, I want to explain some things in this tutorial.

1. The useless Class

I know these classes looks like useless for programmers who are experinced. But, as my practice I found that using separate class can help newcomers understand code better. So I will not change it.

2. The data generation

Actually, I will introduce the Data generation in one chapter. I believe if people can not write json by hand and they will not understand the Data generation. Besides, In some case, people still need write json by hand.

3. About Event registry and other things

The top consider for me is translation, I will add contexts and explains latter when I translated this tutorial.

4. About Code Styple.

This tutorial actually be written in very short time. I will do full check about the code style.

Anyway, Thank you for your advises.

Edited by FledgeXu
Link to comment
Share on other sites

No problem. Here are my reasons for those statements if you're curious:

1 hour ago, FledgeXu said:

I know these classes looks like useless for programmers who are experinced. But, as my practice I found that using separate class can help newcomers understand code better. So I will not change it.

However, regardless you should explain that these are not versions that should be used and are only there to aid the reader in understanding. You have to remember that the target audience is those with moderate to no experience in Java and that setting them up with bad practices only pushes them towards those in the future. I just rather you give people the ability to succeed with the tools required rather than fail based on bad knowledge even though it's purely visual.

1 hour ago, FledgeXu said:

Actually, I will introduce the Data generation in one chapter. I believe if people can not write json by hand and their will not understand the Data generation. Besides, In some case, people still need write json by hand.

Actually, there is no case where a JSON should be written by hand. All data can be made into providers and generated manually. My belief is that this is a decent entry-level barrier for those who want to get started in modding. It teaches people that they need a decently moderate level of understanding within Java to be able to mod it correctly. It will discourage those who think they can do it with no Java knowledge and entice them to take the time to learn before getting started. This is how I've been approaching my rewrite of the text tutorial explanations. We're not trying to cater to all audiences, just those who have the determination to see this through to the end regardless of the starting point. Making it seem easy to start and pick up in useful, but with little moderation to know there are standards.

1 hour ago, FledgeXu said:

The top consider for me is translation, I will add contexts and explains latter when I translated this tutorial.

That's fair enough. If you ever need some grammar review or information checks, I'm happy to provide.

1 hour ago, FledgeXu said:

This tutorial actually be written in very short time. I will do full check about the code style.

Fair enough. Code style is one of those things you seem to be consistent with so I wouldn't be too worried. Conventions are what need a bit of work.

Link to comment
Share on other sites

4 hours ago, diesieben07 said:

It's never null either. It would be AIR.

It can be null if for some reason you decide to pass it in (which you should never do). However, any null value will be received as AIR due to the condition checks or serialized to AIR when writing. My bad on the miswording.

4 hours ago, diesieben07 said:

To check if an ItemStack is empty use the isEmpty method.

This was mentioned in the tutorial, hence why I didn't mention it when I wrote the above statement.

Link to comment
Share on other sites

  • 2 months later...
  • 1 month later...

@FledgeXu Hey, I followed your tutorial to the end of 3.1, however when I run my code I don't see the obsidian ingot in the miscellaneous tab. I did a search for "ingot" and "obsidian" to see if they maybe were in another tab, but found nothing. I tried looking at your source code to see any differences in the code I had from your tutorial, and well there are a lot of differences.


1) First off the neutrino class doesn't exist in your source. Nor do the references made in that class exist elsewhere. I don't understand what the neutrino class even is really in relation to the obsidian ingot.


2) Next I expected the source code at the end of 3.1 to be snapshots showing what I should have at the end of this segment of the tutorial. Instead your source code link takes me to everything for the entire tutorial, start to finish. That makes it near impossible for a new guy like me to read and find my errors or differences. Could you go back and follow your own tutorial to make these end of lesson snapshot files so I have something to go off of here, with my missing obsidian ingot item?


I have attached my code snapshot files from the end of following your tutorial through 3.1 for reference. Maybe that will help you spot something I missed in your tutorial that you could maybe add more emphasis on, if that helps.


Thanks so much for your very hard work! It is invaluable to me!

Section 3.1 code snapshot.zip




I tried working backwards from your complete Source code. I was able to see the obsidian ingot. Then I tried deleting everything that wasn't in the tutorial up through 3.1. The big difference I found is that the registry code found in the tutorials Neutrino class was actually was included in the constructor for the Boson class instead, and broken into two lines. See the code snippet below.


I have attached the 3.1 snapshot I was talking about... hope this helps the next person. Section 3.1 snapshot.zip.


public class Boson {
    public Boson() {
        IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus();
Edited by scifiaholic
found solution
Link to comment
Share on other sites

  • 1 month later...

I'm pretty sure you're Chinese or at least speak Chinese, since the English version is not completed, could you please send me the Chinese version or at least tall me where can I find it? Thanks a lot, and by the way, your tutorial is amazing and really helped a lot.


I've found it, it's really good, and reading Chinese is much easier than reading English, thanks again!

Edited by JankinT
I've find what I need
Link to comment
Share on other sites

3 minutes ago, alice009 said:

wow, i came here for some modding tutorials, as i am quite a noob in that, and honestly i am not disappointed at all. i dont think anywhere has a detailed description as this. thanks a bunch, i'll wait for more.

this is really a good tutorial, too bad it's not finish, I'm lucky to find the Chinese version which is completed

Link to comment
Share on other sites

42 minutes ago, JankinT said:

this is really a good tutorial, too bad it's not finish, I'm lucky to find the Chinese version which is completed

is it possible that i can translate the chinese version to english? if so, then can you please share it here? it will be really great

Link to comment
Share on other sites

  • 1 month later...

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.

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.

  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Minecraft java and forge seem to have it out for me, any ideas? I have had issues with exit code 1 while loading forge -fabric was having the same issues, but I seemed to fix it in these repairs? (tried different versions upwards from 1.19 to 1.20.2 for forge, nothing worked and I'm confident older versions wouldn't either) -The launcher itself loads fine, it will load the game within the launcher, and then crash the moment it tries to load outside of the launcher. I have tried the default launcher, legacy launcher, and the curse forge launcher, none have worked! (all have had the same problem) I think this started when I took a break and upgraded to windows 11 and wonder if that changed anything? I have tried the following: uninstalled & reinstalled java, (I have having issues where I download jdk 17 but only 8 would show up (would not show up anywhere but the control panel, not even the official uninstaller, I *think* I got that fixed) tried jarfix uninstalled & reinstalled minecraft tried alternate launchers -forge & legacy, & repaired them too. tried without mods updated game drivers uninstalled and reinstalled forge -including completely wiping it from my system changed java excutable path followed everything in the error code 1 post completely reset my pc I tried to change the launch path but couldn't seem to get it to work -the default launcher wont let me even see properties as an option, i have yet to try with the other two (i did try on legacy but it was being weird) I want to include my debug log; but its over the max size? sorry my brains gone numb from trying to fix this for the past 2 days
    • I personally create registries using DataPackRegistryEvent.NewRegistry. It's pretty powerful as long as you know how to make codecs. In some class, make a registry key like so: public static final ResourceKey<Registry<MyDataType>> MY_REGISTRY = ResourceKey.createRegistryKey(new ResourceLocation(MyMod.MOD_ID, "registry_name")); This will make a registry that holds objects of type "MyDataType". JSON files stored in data/<datapack_namespace>/modid/registryname/ will be parsed and put into this registry. Note that the directory structure has a folder named after your mod inside your datapack directory, so the actual path would look like: data/my_mod/my_mod/registry_name (or if another mod uses your registry: data/their_mod/my_mod/registry_name. To register this registry, subscribe to the DataPackRegistryEvent.NewRegistry event on the MOD event bus and call event.dataPackRegistry() for every registry you have. An example of what I'm doing for my mod (this is in the constructor for the main mod file): IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); bus.addListener((DataPackRegistryEvent.NewRegistry event) -> { event.dataPackRegistry(ModRegistries.INSULATOR_DATA, InsulatorData.CODEC); }); CODEC is a public static field inside the class for the custom data type I am registering. It holds a Codec<InsulatorData> that tells Minecraft how to serialize/deserialize the data. Most of my data so far can be represented by records, so I use RecordCodecBuilder.create() to do this: public static final Codec<InsulatorData> CODEC = RecordCodecBuilder.create(instance -> instance.group( // Yadda yadda ).apply(instance, InsulatorData::new)); What exactly to put here depends on what you're trying to do, so that's up to you. But basically you're just defining a list of codecs that correspond to the parameters of the record (data type). Most primitive data types have records in the Codec class (ex. Codec.INT) that you can use, and other classes like ResourceLocation have their own codecs as a static field (ex. ResourceLocation.CODEC). Hopefully this is what you're looking for, and that this helps.
    • Good days  I finnaly manage to fix and get a working gui from BlockItem and from BlockEntity the next issues i have to fix is this the block Entity model for some reason is moved to the south west  this briefcase model must be centered but is moved to a side, i have nothing weird in the code but this is happening // ########## ########## ########## ########## @Override public RenderShape getRenderShape(BlockState blkstate) {     return RenderShape.MODEL; } the block model is out of place However The hitBox of the block is right in place   ########################################################################################################### This next issue  Mi gui also adds the 5 slots from the player equipment the thing is theres no filter to determine whats can be put in an armor slot and what not      i have this method that draws the slots for the armor, the part i dont get i slike wheres the code that responds when you set an item in a item slot to do checks and allow the item to be set or not  //########## ########## ########## //Draw Player Armor private void addPlayerArmorSlots(Inventory playerInventory) { // 36 this.addSlot(new Slot(playerInventory, 39, 8, 8)); this.addSlot(new Slot(playerInventory, 38, 8, 26)); this.addSlot(new Slot(playerInventory, 37, 8, 44)); this.addSlot(new Slot(playerInventory, 36, 8, 62)); this.addSlot(new Slot(playerInventory, 40, 26, 53)); }   theres must be a method that triggers when you set a itemstack inside an slot and allows to do a check if its a valid item for that slot                                             
    • No like how do I use my new PreperableReloadListener, I know how to set it up now and register it, I just need to know how to use it in other classes.
    • Completely out of the blue my forge loader is lagging, although at 120 fps. Like when I turn it lags, or hit mobs it lags, or run sometimes although staying at 120 fps. I found another person having a similar problem:  But there was no solution I dont think. I tried everything from: 1. Updating my computer 2. Updating/reinstalling forge 3. Testing if allocated memory was problem (if it was low or high or mid nothing changed) 4. Adding various performance mods 5. Deleting most of my profiles if storage was a problem.   Really not sure what to do next or if forge is just broken for ever for me now.  
  • Topics

  • Create New...

Important Information

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