#WIP
Last updated: Wednesday, April 6
This is a quick primer for the cool 1.8.9 kids. Knowledge of 1.8.9 assumed.
-
Notable class remappings:
- See https://github.com/kashike/migration/wiki/1.8.9-to-1.9
- If you use IntelliJ IDEA, import this migration mapping and it will zap half of your compile errors! :P
-
TE Syncing in 1.9.4: Important! See: https://gist.github.com/williewillus/7945c4959b1142ece9828706b527c5a4
-
Registering things (Forge 1819+)
- The registries have been cleaned up!
GameRegistry.register(<object>, <res location>)to register everything- Blocks, Items, Potions, PotionTypes, SoundEvents, Enchantments, Biomes, etc.
- Will all be ID-assigned and synced by FML
- You can also add your own registries to be managed by FML but I'm not sure on the precise details
- Instead of
GameData.get<X>Registryjust use the fields in the class now (Block.blockRegistry, etc.) - IMPORTANT: Blocks and their ItemBlock forms are no longer registered together (Which was dumb anyway). Simply register the Item separately by constructing your own ItemBlock and registering it with the same name as the block. A side effect of this is that ItemBlocks are no longer restricted to having a single parameter Block constructor, since you are responsible for constructing it now.
-
Model/rendering changes
- Block.shouldSideBeRendered has changed: "The given position is now the position of the block itself and no longer the adjacent block as it was in 1.8 or earlier. So people should change code with pos.offset(side)" (McJty)
- Looks like Block.colorMultiplier and Item.getColorFromItemstack have disappeared...what?!
- Don't fret, they've just been split out into a separate interface (allowing the same logic to be used for multiple block/item types
IBlockColorandIItemColorcontain those two old methods.BlockColorsandItemColorsare where you register instances of the above interfaces to Block and Item instances.- The
BlockColorsandItemColorsinstances can be obtained fromMinecraft, and both contain methods to scan all registered Blocks/Items to apply coloring to an unspecified Block or Item.
- ISmartBlockModel and ISmartItemModel are both gone
- WHAT? OMG RIOT ༼ つ ◕_◕ ༽つ RIOT ༼ つ ◕_◕ ༽つ
- oh wait...because vanilla has it now
IBakedModel's methods have changedgetFaceQuadsandgetGeneralQuadshave been merged intogetQuadsgetQuadsis side sensitive (face quads here!) and state sensitive :D- Morever,
getQuadsnow returns aList<BakedQuad>. This means you can pass a custom IBakedModel directly into vanilla rendering methods and they will retain their "smartness". (Almost) no more dummy models that return an empty list in getFace/GeneralQuads!
- So for blocks, just change your implements and do some fixups
- For items, vanilla has added item overrides
IBakedModelreturns anItemOverrideList. If you need full control, a laISmartItemModel, implement and return a subclass here.ItemOverrideListhas thehandleItemStateyou know and love.- For situations where you don't need as much control, in your
Itemconstrucor, calladdPropertyOverride. You pass it first a unique identifier (which will determine how its specified in json), and aIItemPropertyGetter. This is essential a function from (stack, world, player) -> float. This float is then used in json to determine the model. A good example of how to use this is the vanillaItemBowandbow.json. - The above replaces
Item.getModeland most usages ofModelLoader.setCustomMeshDefinition. The former has been removed, but the latter is still there, in case you need it.
- IPerspectiveAwareModel is still there.
- IFlexibleBakedModel was removed as the vertex format has now been moved to the
BakedQuadlevel. The implications of this are unknown right now. - The first person and third person camera transforms have both been split into left and right hand variants. Adjust accordingly.
-
Dual wielding and
PlayerInteractEvent- Vanilla's interaction trace is really messy
- The gist is:
- If you want processing to "continue", return PASS, or false (from boolean methods)
- If you want processing to "terminate", return SUCCESS, FAIL, or true (from boolean methods).
- Whenever the client "continue"s, it keeps running other logic and then other hands
- The server doesn't really "continue" since it does things in packet handlers.
- Thus, it's safer to terminate early clientside than terminate early serverside and let the client keep going doing other things.
- In other words, be optimistic on the client (prefer returning SUCCESS and true if you don't want processing to continue to other hands), and be truthful on the server.
- I've rewritten PlayerInteractEvent to hopefully be a lot clearer and useable, and it's just been pulled into forge. Please help me test it!
-
EntityDataManager(aka DataWatcher)- Starting with 1.9, int-based datawatcher ids have been replaced with
DataParameters, which can be obtained by callingEntityDataManager#createKeywith the targetEntityclass, and the appropriateDataSerializer, which defines how the data should be serialized to the packet stream. - There are a number of pre-defined
DataSerializers which can be found inDataSerializers, and additional serializers may be registered usingDataSerializers#registerSerializer. - Notable method changes:
DataWatcher#addObject->EntityDataManager#registerDataWatcher#updateObject->EntityDataManager#setDataWatcher#getWatchableObject*has been replaced withEntityDataManager#get
- Check vanilla entities for concrete examples
- Starting with 1.9, int-based datawatcher ids have been replaced with
-
Loot Tables:
ChestGenHookshas completely been deprecated, and for very good reason.FishingHookshas also been deprecated.- The vanilla loot table system is much more powerful and flexible. In the coming days Forge will evaluate what changes are needed so modders can use it effectively. Read up on the vanilla wiki and the 1.9 code if you want to contribute to the discussion.
- Some terms follow
LootTable: All it does is hold a bunch of LootPoolsLootPool: Holds multiple LootEntry's. Holds multiple LootCondition's that must all be met for the pool to yield loot. Has fields rolls and bonusRolls to specify how many times the pool is queriedLootEntry: A loot entry itself. Can be of subclass empty, an item, or another LootTable entirely. Also holds its own collection of LootCondition's that are checked by the LootPool before querying the entry for items. Item loot entry subclass also has a collection of LootFunction's.LootFunction: Simply put, are functions that transform a stack into another one. These also have LootConditions that must pass for application. Vanilla provides a variety: Enchant randomly, enchant at level, boost drops with looting, set attribute modifiers, set count, set damage, set meta, set NBT tag, and smelt.LootCondition: Conditional check for all the above classes. Is a predicate that takes a Random and a LootContext. Vanilla provides: Entity has LootProperty, Entity has scoreboard score, Entity was killed by player, Random chance, random chance modified by looting.LootProperty: Used solely for the above mentioned LootCondition. Vanilla provides one: Entity on fire.LootContext: Contains the full context of this loot gathering event. Has the world, LootTableManager, looted entity, player involved if any, DamageSource of the killing blow, and luck level of the killer, and aSet<LootTable>to use.- The JSON syntax for all of these can be looked up on the vanilla wiki (search "Loot tables")
-
Datafixer:
- Vanilla way of changing NBT tags on things from an old format to a new one
- Probably very useful for us mods!
- Not documented yet
-
Potions:
- Now has full registry like blocks and items. REMOVE ALL YOUR INT ID'S!!!!!
- Vanilla potions are now held as static fields in
MobEffectsinstead of inPotion PotionEffectno longer uses int ID's (thank god)PotionType's are added- Defined as a list of
PotionEffect's - Also registered to a registry
- For example, PotionType minecraft:strong_regeneration is defined as one PotionEffect of Potion regeneration, with amplifier 1 and duration 450 ticks
- All registered PotionTypes are added to the potion creative tab in normal, splash, and lingering form, as well as in Tipped Arrow form.
- (Will we get a hook to disable this?)
- Defined as a list of
- Vanilla's way of defining brewing recipes has completely changed
- Now in
PotionHelper - You can register "potion items", items that can provide potion effects
- You can register conversions between potion items. E.g. Items.potionItem + gunpowder -> Items.splashPotion. All Potion effects are carried across.
- You can register conversions between potion types. E.g. regeneration + redstone -> long_regeneration. The potion item is retained.
- As you can see, the logic has been separated!
- "Conversions" are of type
MixPredicate<T>, which in its constructor takes an input<T>, aPredicate<ItemStack>that matches the reagent, and the output<T>- NOTE: The implementation of the predicate provided,
ItemPredicateInstance, uses -1 as the wildcard meta value instead of Short.MAX_VALUE, which is the value Mojang uses for crafting recipes (and also OreDictionary.WILDCARD_VALUE). goddammit -.-
- NOTE: The implementation of the predicate provided,
PotionUtilshas the whole range of NBT<->Potion interaction utility methods, as well as util methods to generate potion tooltips, etc.
- Now in
-
Enchantments:
- Now has full registry like blocks and items. REMOVE ALL YOUR INT ID'S!!!!!
-
Biomes:
- Now has full registry like blocks and items. REMOVE ALL YOUR INT ID'S!!!!!
- The weird +128 quirk seems to have been removed [citation needed]. If you know what this means then sigh a sigh of relief :D
-
Misc
EntityFX's are no longer real entities to remove the overhead that comes with being one.
Block.shouldSideBeRendered() has changed meaning. The given position is now the position of the block itself and no longer the adjacent block as it was in 1.8 or earlier. So people should change code with pos.offset(side)