#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>Registry
just 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
IBlockColor
andIItemColor
contain those two old methods.BlockColors
andItemColors
are where you register instances of the above interfaces to Block and Item instances.- The
BlockColors
andItemColors
instances 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 changedgetFaceQuads
andgetGeneralQuads
have been merged intogetQuads
getQuads
is side sensitive (face quads here!) and state sensitive :D- Morever,
getQuads
now 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
IBakedModel
returns anItemOverrideList
. If you need full control, a laISmartItemModel
, implement and return a subclass here.ItemOverrideList
has thehandleItemState
you know and love.- For situations where you don't need as much control, in your
Item
construcor, 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 vanillaItemBow
andbow.json
. - The above replaces
Item.getModel
and 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
BakedQuad
level. 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
DataParameter
s, which can be obtained by callingEntityDataManager#createKey
with the targetEntity
class, and the appropriateDataSerializer
, which defines how the data should be serialized to the packet stream. - There are a number of pre-defined
DataSerializer
s which can be found inDataSerializers
, and additional serializers may be registered usingDataSerializers#registerSerializer
. - Notable method changes:
DataWatcher#addObject
->EntityDataManager#register
DataWatcher#updateObject
->EntityDataManager#set
DataWatcher#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:
ChestGenHooks
has completely been deprecated, and for very good reason.FishingHooks
has 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
MobEffects
instead of inPotion
PotionEffect
no 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,
PotionUtils
has 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)