1.9 Preview

FyberOptic

New Member
Jul 29, 2019
524
0
0
I thought I'd make a topic that we can post all the interesting tidbits we discover from the 1.9 snapshots.

IBakedModel's getFaceQuads and getGeneralQuads methods now accept IBlockState and BlockPos as parameters. I've yet to dig through enough to discover how much Mojang is taking advantage of this, but either way, I think Forge's ISmartBlockModel can finally have a proper burial.

Items can now have states. The bow, clock, compass, and fishing rod are all examples. You specify an "overrides" section in the JSON, followed by "predicate" entries containing the state name and value, and can then specify a model to override the current one.

The item states are registered in your item class, apparently no dicking around with the ItemModelMesher or anything like you had to do with all your damage values (though you apparently still have to register the main model at least). You register states with a ResourceLocation for the state's name, associated to an instance of the new item state class. Mojang is just using inner classes in the item classes themselves to handle it. This new state class only has a single method that accepts the ItemStack, World, and EntityLivingBase, and returns a float. That float is what is used for the value in the JSON.

Item states seem useful, but if you just take a look in the JSONs for the items I mentioned, the clock and compass in particular, you'll see that they need dozens of models.
 

FyberOptic

New Member
Jul 29, 2019
524
0
0
Blocks have a couple of new methods and enums for structures. I've dubbed the methods getRotationFromState and getMirroringFromState, where basically it passes in a block state and a rotation/mirroring enum, and you pass out a state based on that. It appears to only be used for orienting blocks when they're inside of one of the new structure objects. It'd be useful for being able to create like redstone contraptions, saving them as structures in your assets, and then being able to orient them into the world with varying rotation and mirroring without worrying about stuff breaking.
 

FyberOptic

New Member
Jul 29, 2019
524
0
0
A little bit of extra detail on the IBakedModel changes. I'm starting to think they're less useful than I originally expected.

Originally you had three classes that implemented IBakedModel: BuiltInModel, SimpleBakedModel, and WeightedBakedModel. The latter I think they might be phasing out, actually. But they added a fourth type in 1.9, which I've dubbed LogicalBakedModel. This is the one which actually takes advantage of the block logic that they implemented in the JSONs. For example, in its getGeneralQuads(IBlockState, BlockPos) method, it checks the logic for each condition in the JSON, and if it passes, it adds the quads from the specified sub-model into the current model through a call to that model's own getGeneralQuads.

However, here's where it gets weird. The BlockPos that's passed into the sub-model's getGeneralQuads has had its X coordinate incremented by 1 at every iteration of the loop of possible logic states. It does this in both getFaceQuads and getGeneralQuads. So the BlockPos being passed isn't guaranteed to be accurate whatsoever, and seems more like it's just meant to be used as a counter and/or means of passing generic data. That, or the +1 was just added by them for testing purposes, but I dunno. They're not actually doing anything with the BlockPos values they receive regardless. In several cases I saw, a null was being passed in anyway, and when it's null it creates a new BlockPos at 0,0,0.
 

FyberOptic

New Member
Jul 29, 2019
524
0
0
I forgot to mention this initially, regarding items. The states can be largely ignored when updating, but changes to handedness will have to be acknowledged.

Methods like onItemUse, onItemRightClick, and itemInteractionForEntity now receive an extra parameter for an object I called MainOrOffHand, which is literally just an enum of those two possible values.

onItemUse doesn't return boolean anymore, it returns a new object I dubbed ItemUseResult, which is an enum of three values: SUCCESS, PASS, and FAIL. It appears to be used to allow you to pass usage to the item in the off-hand.

onItemRightClick also no longer returns boolean, but another new class I called ObjectActionHolder, which is a generic class. All that it holds is a generic object (an ItemStack type in this case) and an ItemUseResult. The intention is apparently just encapsulate a return item and a success value together. If the returned item doesn't match the one passed in, it puts the return one in the appropriate hand afterward.

The three methods that it adds regarding item states I called addItemState, getItemState, and hasItemStates. That should give you a pretty good idea of just how simple it is to work with these things. Items get a default state called 'lefthanded' that you can use out of the box in your models, which apparently is just a 0 or 1, so that you could specify a different model when held in the left hand (like maybe you want different rotations or something).



EDIT: Oh right, also regarding items. Item models in 1.8 used to rely on builtin/generated as their base. 1.9 item models use item/generated, which itself is based on builtin/generated, but does some scaling and stuff. Rendering code has also been changed to remove some of the internal scaling, as item/generated is apparently now supposed to handle all of this. The end result is that you currently can not directly port 1.8 item models to 1.9. This is even hurting Mojang's own missing-model model, as you can see here. I'm hoping that this is just a bug. It kinda sucks because I can't make items in Meddle that work fine in both 1.8 and 1.9.
 
Last edited:

ratchet freak

Well-Known Member
Nov 11, 2012
1,198
243
79
now for the main question how many independent block states can be added?

For E-util style pipes would need at least 2^6 states. For TE conduits it's 3^6 (extra state per side for connected to block). For

(not counting textures though hoping that they can be specified dynamically)
 

FyberOptic

New Member
Jul 29, 2019
524
0
0
The 1.9 snapshots seem to have introduced a new system that encapsulates the reading of any nbt data from the disk, centered around the concept of a DataVersion. A lot of "fixes" are registered for things from entities to blocks to tile entities, designed to manipulate the incoming data of a particular object into a different structure. If the saved data version meets or exceeds the game's own (15w33c seems to be data version 112 for example), then no processing is necessary. In 15w33c you can find this system returned through a getter at the bottom of the Minecraft class, for obfuscated class "om", which I called DataVersionManager.

In other words, they implemented a way to restructure nbt data, possibly to make certain things more universal, though this will obviously have a detrimental effect on using 1.9 saves in older versions.


now for the main question how many independent block states can be added?

For E-util style pipes would need at least 2^6 states. For TE conduits it's 3^6 (extra state per side for connected to block). For

(not counting textures though hoping that they can be specified dynamically)

1.9's somewhat more flexible system would improve the implementation of a pipe system over 1.8, but honestly I probably still wouldn't bother with it. I'd use custom rendering of some sort, where it's far easier to render something algorithmically.
 
  • Like
Reactions: Type1Ninja

FyberOptic

New Member
Jul 29, 2019
524
0
0
Potions are no longer limited to an array of 32. They use a registry like items and blocks. They even have a net.minecraft.init.Potions type of class now too, also like items and blocks.

The new tool cooldown can be disabled by overriding the cooldown reset method (was cg()V in 15w34a) in EntityLivingBase. I did it just out of curiosity's sake, since I kept hearing people complaining about how it'll hurt various ways of playing. I don't actually dislike the cooldown itself. The system does need some tweaks though. Changing weapons resets your cooldown, chopping trees or digging uses the in-cooldown tool position the whole time, etc. But it's still pretty new so I'm sure they'll fix it eventually.
 
  • Like
Reactions: Type1Ninja

Hlaaftana

New Member
Jul 29, 2019
304
0
0
To be honest, they're kind of patching up the 1.8 catastrophe between modders... Yet I think that's because of the general tire of updating from version to version, with mods nowadays that can replicate future versions without affecting normal code.
 

lumien

New Member
Jul 29, 2019
66
0
0
now for the main question how many independent block states can be added?

For E-util style pipes would need at least 2^6 states. For TE conduits it's 3^6 (extra state per side for connected to block). For

(not counting textures though hoping that they can be specified dynamically)

Well thankfully that was fixed by Forge last december so it doesn't really matter^^.

To be honest, they're kind of patching up the 1.8 catastrophe between modders... Yet I think that's because of the general tire of updating from version to version, with mods nowadays that can replicate future versions without affecting normal code.

Out of interest, which of the changes seem to indicate that to you?
 

FyberOptic

New Member
Jul 29, 2019
524
0
0
Mojang's ongoing process of abstracting anything and everything now applies to entity data as well. The entity DataWatcher no longer uses simple integer values as the index for a watched data object.

You now use a static method in the DataWatcher class to generate an object to work as a handle to your watched objects. I just call the handle class WatchedObject. The method to generate a WatchedObject accepts your entity class as well as a field from the new class that I called DataWatcherTypes, which is basically a big abstraction of the old DataWatcher.dataTypes map. As expected, they added some more types that you can watch now too, like EnumFacing, IChatComponent, and UUID. Weirdly though they removed short values, so if you were using those you'll have to move up to an integer I guess.

All DataWatcher methods for getting or setting these watched values now accept these WatchedObject handles instead of the old integer values.

Overall this is a good change I suppose, since you no longer have to keep up with cryptic numeric values which might overlap. Internally though it's still just a numeric value. Every time you create a WatchedObject, it pulls an integer value from a map for that entity class, increments it by one, and that's now the internal ID of that watched data object. You can have up to 254 objects per class.

Due to all of the abstraction in DataWatcherTypes, this also means mods will be able to register their own object type handlers.
 
  • Like
Reactions: Type1Ninja

Hlaaftana

New Member
Jul 29, 2019
304
0
0
Out of interest, which of the changes seem to indicate that to you?
The huge FPS increase, less complications now that everything is in place e.g. items have states too, potions are no longer really complicated items.. I just woke up, I'm not thinking well...
 
  • Like
Reactions: Type1Ninja

FyberOptic

New Member
Jul 29, 2019
524
0
0
The tessellator (or WorldRenderer as 1.8 called it for some reason) has been going through a number of changes. It's much more dependent on vertex formats now. In fact, you can't even start drawing without specifying one now. DefaultVertexFormats used to just have "ITEM" and "BLOCK" in 1.8, but there's a dozen at this point, like for "PARTICLE", but most of which I haven't labeled yet. The tessellator itself is basically pushing towards more of a vertex array/VBO direction of handling things. Some is more generic, based on the vertex format. Some of the older functionality is pulled, other stuff works differently.

A picture's worth a thousand words so how about I just give a comparison of a method carrying out rendering, between 1.8 and 1.9.

For better or worse it appears that you have to specify things like color, UVs, normals, etc, per vertex, and end each one with that method (which I took the name from the Realms renderer).
 
  • Like
Reactions: Type1Ninja

FyberOptic

New Member
Jul 29, 2019
524
0
0
Woo, 15w37a. Performance improvements etc etc, but Mojang's changelog rarely tells you about the goodies under the hood.

The IBlockState class now extends another interface which provides access to a lot of a block's functionality. The base BlockState.StateImplemenation class wraps the block's methods through this interface, which basically means that a class extending an IBlockState could now actually override a block's functionality. Blocks being abstracted in this way is potentially a big deal as we go along.

Many of the methods in the Block class now accept IBlockState parameters. This gives the vanilla block class a lot more potential without as many workarounds. Thumbs up, Mojang.

The Block class also no longer specifies its bounds by individual variables, it uses an AABB. Kind of surprised it took this long. This will mean some code changes for mods to adapt, of course. It's a good change though.

Custom block rendering appears to be here to stay, no matter how many times certain people may have tried to convince us otherwise as one of the many excuses to not allow custom rendering in 1.8. getRenderType() now returns an enum. It's also one of the methods abstracted into the block state. They wouldn't go to this trouble if they planned to remove it. The downside is that being an enum rather than a simple integer means either a different style of render hook is necessary, or the enum itself has to be modified at runtime. Not a big deal though, personally I'll just change my 1.9 render hook to use the block instance as the key in the custom renderer map rather than use the getRenderType value from now on.

Overall I'd say this is all good stuff. And this only what I managed to find from poking around for a bit! Who knows what else is improved.
 
Last edited:
  • Like
Reactions: Type1Ninja

Hlaaftana

New Member
Jul 29, 2019
304
0
0
Searge and Dinnerbone were tweeting about how they worked so much, so I was guessing this snapshot would have been awesome anyway, yet they were also talking about how their work could break the game....