Tết (aka Vietnamese New Year)

Today is the holiday known as Tết (aka Vietnamese New Year), a day with much celebration amongst the Vietnamese people, including those who fled from Vietnam after the communist takeover and their posterity.

Read More

1,000,000 Downloads of PlusTiC

I started PlusTiC back in December 2016, when I was just learning to use the Forge modding API. A novice at the time, I mainly used it to experiment with new Tinkers Construct materials (I especially wanted materials for the Biomes o’ Plenty and Mekanism mods), and I did not release PlusTiC to the public until February 11. I did not expect the mod to become as popular as it is now, having reached over 1,000,000 downloads today on CurseForge!

Read More

Missing the Iteration Forest for the Modloading Trees

Not long ago, there was a bug in my mod PlusTiC that sometimes erratically disabled the osmiridium material. Thinking that it was a modloading bug, I wandered aimlessly through the trees to find which mods were loading in a strange order. It wasn’t until today that I found that I had missed the iteration forest for the modloading trees—the modloading was fine, but I used a THashSet to store the modules when I should have used a LinkedHashSet instead! Using the THashSet caused great unpredictability in the iteration order of the modules—sometimes causing the ModuleMekanism to load before the ModuleBasewhich is not what I wanted!

Read More

On Mod Content Register Order and the CompletableFuture

A particularly annoying aspect of the Minecraft Forge registry event system is that it is difficult to detect when a block/item/oredict/et cetera is registered without having to write a plethora of scattered, disorganized code. In order to do so, one is often stuck with writing code in places distanct from closely related code that needs to run at a different time. Consider a snippet of code that must integrate and add items for a darkwood Tinkers material after the item is registered, but before FMLInitializationEvent:

@Mod.EventBusSubscriber(modid = ModInfo.MODID)
class InitMaterial implements IModule {
  public void init() {
    Material darkwood = new Material("darkwood", 0x000099);
    darkwood.addTrait(DarkTraveler.darktraveler);
    // do all the initialization stuff here… except for item adding and integration
    //
    //
    //
    //
    //
    //
    //
  }
  
  @SubscribeEvent(priority = EventPriority.LOWEST)
  public static void onReg(RegistryEvent.Register<Item> event) {
    Material darkwood = findDarkwoodMaterialFromSomeLocalRegistry();
    darkwood.addItem(darkwoodPlanks, 1, Material.VALUE_Ingot);
    // add log and sticks
    //
    doIntegrate(darkwood);
  }
}

The main problem with this approach is that some code that is used for initalizing materials is separated from the rest of the initialization code—it is in an event method, which is separated from the initialization method. This can severely hinder maintenence, as one has to remember jump to the two areas of code. This quickly gets worse the more of these one has.

Read More