I may release a small code dump or Github project or something with useful things, but I spent all freaking day today trying to hammer Minecraft and Forge into working with dynamic models, so that I could port something as simple as Hopper Ducts.
The ducts themselves can be easily pointed in any direction by the standard model system, but it needs the little connected bits which extend to a neighboring duct so that you know they're connected. Doing this by models and states would result in hundreds of possible combinations, and that's simply ridiculous to try to do by model file. In my own work at writing my own API, none of this was a problem because I hooked the block rendering, allowed my block to return a special renderer type, and could draw shapes as dynamically as I wanted with minimal effort. But this is Forge, so nothing is easy.
What I ended up doing, for starters, was ripping a bunch of code out of Minecraft and changing it for my own use, because neither vanilla or Forge gives you access to things in some of the model loading and baking classes that you actually need to do anything useful. In the end, I put together methods for loading models manually, as well as for baking them to whatever rotations I wanted. Combined with ISmartBlockModel, I made a system where I could load multiple model files, and using block state information, output combined lists of quads from multiple models to represent the final model. In this case, the duct is one model, and the connector bit is another model. I rotate them appropriately, and output as many connector models as necessary on the sides, all based on states.
The downside still to ISmartBlockModel is that you don't have access to the tile entity. There are values you simply don't need to store as a block state, such as whether those neighboring ducts are present, especially when it requires 6 bits of information to do so. But there's no way around it. Lots of block states are going to be your only option for dynamic rendering, which is extremely limiting, and very annoying to set up. And none of this is going to be particularly fast or easy on RAM.
That's another thing: Forge's system for specifying hidden properties for model baking is just dumb. Instead of a normal IProperty, you use IUnlistedProperty with Forge's system, which isn't compatible with IProperty. Vanilla Minecraft can't handle through regular means, and you have to run them through an adapter thing in Forge. This is going to be confusing for people using existing vanilla blocks to learn how to do this stuff. It's especially dumb when you consider Minecraft already provides an accessible way for hiding block properties, without doing any of that. During init, I simply do:
Code:
BlockModelShapes bms = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes();
bms.registerBlockWithStateMapper(blockHopperDuct, (new StateMap.Builder()).addPropertiesToIgnore(new IProperty[] { blockHopperDuct.ENABLED, blockHopperDuct.FACING, blockHopperDuct.CONNECTORS }).build());
Done. You can also create your own custom property handler, or use some of the other built-in ones. This is how I do it in a non-Forge environment, and it still works in a Forge environment, so I have no idea why Forge introduced its own which isn't as flexible in the long run.
Another annoying thing you might run across is Forge will destroy your tile entity any time you update your block state. You need to override shouldRefresh. In my case, I just check to see whether the block of the old state is the same as the block of the new state. If they're not, I let it destroy the tile entity. Otherwise, no, because this was eating items in the ducts every time a block update happened nearby. Took me forever to track this down, because it's not vanilla behavior.
Anyway, like I said, I'll probably put up some code so that other people don't have to fight with this mess as much as I've done today. But all in all, I think I'll be able to finish updating Hopper Ducts now without too much fuss. But good grief, what a mess of code, just to render some cubes.