AEModernMCPort / Applied-Energistics-3-Fork

A Minecraft Mod about Matter, Energy and using them to conquer the world..
http://ae-mod.info/
Other
37 stars 12 forks source link

Model code changes #10

Closed dpeter99 closed 7 years ago

dpeter99 commented 8 years ago

So @elix-x , what do I need to do to make:

to work?

Elix-x commented 8 years ago

There's a one problem though: if we want for resource packs to be able to do things depending on something (like 2*2 cube of cells), we have to explicitly pass that data from TE. Eventually, we can't give jsons everything, so there will always be things that resource packs won't be able to do.

Also, question was: why blocks that have no point of being rotated should be? For example ones listed by @dpeter99.

CreativeEnergyCell DenseEnergyCell EnergyCell tile.BlockCellWorkBench tile.BlockCondenser tile.BlockEnergyAcceptor tile.BlockIOPort tile.BlockSecurity tile.BlockSpatialIOPort Molecular Assembler Crafting Storagges

yueh commented 8 years ago

Not in terms of multiblocks or connected textures.

Just say every tile entity has a rotation available and here is an example for the states, if you want to use it fine. If not also fine. Way easier then say "ok, some tile entites can be rotated, some not. Here is an outdated list, which might contain a complete list of them. Or not".

E.g. a texture pack might just change the texture to a simple background and a straight horizontal line across it to indicate the energy level. You do not like horizontal lines, but want a vertical? Just rotated it.

Would we bake the rotated models at runtime, the artist does not even have to care about it, maybe even not realise it is possible at all. It would just work.


Edit

Elix-x commented 8 years ago

Ok. Got it. Next question: specific reason why rotation was implemented in forward-facing,up-facing way instead of x-rotation,y-rotation? I see reasons to implement it rotation way, but not the facing way.

yueh commented 8 years ago

How would a x,y-rotation look like? Rotate 90 degree around x and -180 on y?

Elix-x commented 8 years ago

Kinda. Instead of having 2 EnumFacing's, we have ints: rotation around axes (either in full degree form or to-be-mutiplied-by-90).

Elix-x commented 8 years ago

I just checked... You can't ignore block states unless you write custom state mapper... Which will have to load ignored properties from somewhere, if we want them to be configurable.

yueh commented 8 years ago

It should not really save space. Enums are still ints internally.

We also need it to rotate the whole TE not just the rendering. Thus the enums are still the sane solution for serverside. Otherwise we have to constantly map between both.

Iirc the renderer actually uses a rotation matrix and maps the enums accordingly.

Otherwise the enums are mostly to serialise them.

And as said it is easier to debug front facing north, top facing up than calculate them each time from the rotation matrix.

Elix-x commented 8 years ago

Maybe, but then when we want to rotate on an axis, we have to convert to rotations, rotate and then convert back. With 1.10, rotation and mirror methods were introduced, so if we want to be compatible with vanilla, we have to implement them. So it's now just a question of how to better store this (rotations or facings). And yes, by asking about why it was implemented in facings, i did ask about whole system (not just rendering).

Elix-x commented 8 years ago

Another question is concerning information do we pass to jsons. Sure, we can pass rotations... And network state... And precise charge... And if the block on top is the same... And id+state of block located on [x=159,y=21,z=-1149] in case if somebody wants to make cell blend with block located on [x=159,y=21,z=-1149]... And we can also pass ([count of ender crystals in the end]+[level of fortune on first diamond pickaxe with 1 damage left in inventory of random player])*[world total time]>>[average simulated amount of drops of diamonds per chunk in 10 chunk radius from player]... The question is, when do we stop???

yueh commented 8 years ago

Not ignoring a single property. Simply ignoring everyone by not having variants. Or do the variants need to be exhaustive?

Also what about the forge blockstates? They should allow something like

"variants": {
    "front": {
        "north": {},
        "south": {}
    },
    "up": {
        "north": {},
        "south": {}
    }
}

Regarding the rotation. There is absolutely not difference between storing the rotation as int or Enum. It will still be mapped through some way to the real rotation used by the model. It is mostly about how expressive it should be. Is "south" better than -180 degree or -2 (*90)? "north" is perfectly unambiguous. Storing 180 degree is only relative, so you need to know what the default. Was it north? or south?

Currently I really do not see any difference at an abstract level. In both cases we are passing 2 variables to the json.

As Enums the are still ints, but mostly typesafe. So it is impossible to pass an invalid enum to it. It can only use invalid combinations, but these are easily to identify.

As x,y rotation, it is still an int. Nothing really saved in terms of space. But we can now pass invalid data do it. Someone could pass 123 degree to it, or -5 when used as factor for 90 degree.

It is mostly about, should we store it as [-2,2), [-180,180) or [0,5].

Can we even use x,y rotation? It should be only 4 states per axis, so 16 permutation. But we need 24 permutation in total. So either it has to be more than 4 states per axis and have some special handling for them. Or we need x,y,z rotations. If so actually more space required.

Data Just what is needed. Rotation for pretty much anything. Power state, channel state for most network blocks. Or whatever else is needed. Like valid crafting cpu and such. No useless stuff about my non existant neighbour.

Elix-x commented 8 years ago

Regarding the rotation.

Ok. I'm leaving it as it is.

Data

So if somebody comes and asks us to include to cell properties whether block to the side is also a cell, we "gently" tell him "no"?

Also what about the forge blockstates? They should allow something like

They were shine of sunrise for the modders... In times of 1.8. 1.9 introduced similar system, in some ways even better.

Not ignoring a single property. Simply ignoring everyone by not having variants. Or do the variants need to be exhaustive?

It ignores properties by name, and may ignore multiple. These files also can go with resource packs. Is it useful? Definetly. For example, in "vanilla" AE resource pack, we don't care about rotations of energy cell. So, we ignore up and forward properties and use only energy ones. But, if resource pack author wants to use them, he just has to remove them from ignore file (or delete them completely) and he has access to these properties. If it would not exist, we would have to make 24 times extra lines in cell's blockstates, because we have to specify every state in variant. Considering cell has 7 looks of charge (or 8?), that's 168 lines. Now if we ignore rotation properties, it's only 7.

yueh commented 8 years ago

They were shine of sunrise for the modders... In times of 1.8. 1.9 introduced similar system, in some ways even better.

I remember reading something about conditional states, but never really researched, if the actually added it.

ignoring data.

One of the reasons I recommend to dynamically bake the models at runtime for rotations is exactly that. Energy cells are still simple. But drives have about 1200 permutations. Dynamically baked models would at least reduce it to about 50.

Elix-x commented 8 years ago

I remember reading something about conditional states, but never really researched, if the actually added it.

Only if... Yeah, that would be useful... It would also be if we could use variables from blockstate (groovy-ish like). Kinda "normal": {"model": "model", "y": "${yRotation}}. That would be extremely helpful. But fry never did it. And, writing block state loader like that... Hmm, isn't too hard actually. Only time will required.

One of the reasons I recommend to dynamically bake the models at runtime for rotations is exactly that. Energy cells are still simple. But drives have about 1200 permutations. Dynamically baked models would at least reduce it to about 50.

I totally agree with you, models that NEED to be baked dynamically, will be. So drives will be baked, cells won't. PS: By need, i mean like too dynamic&detailed for jsons to handle. Maybe like 250+ states.

yueh commented 8 years ago

Would it really be that complicated to apply a dynamically baked rotation for every model? So we can simply say for resource packs, just make your model, we handle the rotational stuff. The models could also only be baked when needed (LoadingCache whatever), should we want to save some memory.

Elix-x commented 8 years ago

Yes... And no... That's a question of how resource packs will want to handle rotations. Maybe they want to flip them? Or rotate on z instead of y?

yueh commented 8 years ago

We already handle flipping them or rotate on z instead of y. There current system can handle every possible rotation of a 3D block when using 90 degree angles. (Except having multiple permutations per for the same result)

The only thing which will not be possible, is that they cannot change it to rotate counterclockwise instead of clockwise. Or some other random rotation, which does not match the internal rotation.

Actually it would be way better. A resource pack does not have to care about the rotation, they cannot mess up the visual representation to be different from the internal one, and we already cover ever possible permutation.

Elix-x commented 8 years ago

You totaly can, with resource pack, implement all rotations. Rotating models in code means we have to cache models somehow for performance, and copy-pasta part of vanilla code to ignore non-rotational properties... is that really THAT needed?

yueh commented 8 years ago

Potentially yes. Pretty much all network tile entites will need about 1632 different states as baseline and on top the additional states for a specific TE. A few could get away with 812 states, but that does not make it easier. Just handling the rotations dynamically, would at least reduce it to 68/34.

But the best option would still be using forge blockstates to reduce it further.

Elix-x commented 8 years ago

Why 1632? 24 rotations * 3 off/on/online = 72?

Forge blockstates won't help us there. And as i said, now vanilla models loader is better in some ways.

yueh commented 8 years ago

24 rotations * 2 active * 2 channel * 17 colours (not currently but on the list and it just requires a way to color them. Internally it already works).

You could argue that !powered & channel is an useless state for rendering, but internally it does exists and is needed.

Elix-x commented 8 years ago

242217=1632 colors -> IBlockColor 2422->96 powered+channel-> EnumState { OFF, POWERED, ONLINE } 243 -> 72

yueh commented 8 years ago

We are not talking about a colour multipler applied to the texture. It will only colour a specific area of the model.

On cables it only colours the cable and panels, but not buses, facades or whatever. On chests or crafting monitors it only colours the screen, nothing else. Other blocks like drives are currently not supporting it. But if they would only colour the case, not the drives. Or maybe just have different led colours. Or maybe a status led on the back. Something like that.

They are even coloured in a way that you cannot use a separate texture with a multiplier. It needs use at least 1 different textures for each of the 3 brightness level of a colour and you will most likely need a colour triple for every single texture. Because you will need different multiplier per texture per block. Or 3 different colour textures per tile.

powered+channel cannot be merged into a 3 state enum. It needs all 4 states internally. So either you waste effort and space by duplicating it for the rendering and keeping it in sync. Or you need to merge 2 different properties, who need to be handled independently into one state, but still have to handle them separately. Like abuse the enum as bitset and flip a specific bit with bit operations and then use that as index for the enum before setting it.

Elix-x commented 8 years ago

We are not talking about a colour multipler applied to the texture. It will only colour a specific area of the model.

In model, you specify tintIndex per face (same way you can specify uvl map with uvl loader). Then this index is given to IBlockColor implementation to determine color. Color is not even configured per area or quad, but per face.

yueh commented 8 years ago

Per face is not sufficient. We need it per quad, area, or whatever you want to call it. Or even just to pass it down to a submodel for a dense cable. Pretty much the same behaviour as the uvls just for 3 different colours per AEColor

dpeter99 commented 8 years ago

Could somebody help me with: #17 ? @elix-x

Elix-x commented 8 years ago

Per face is not sufficient. We need it per quad, area, or whatever you want to call it. Or even just to pass it down to a submodel for a dense cable. Pretty much the same behaviour as the uvls just for 3 different colours per AEColor

When we speak of quads, faces and other things, apparently we speak of different things.

In green are: Model: Model Quad: Quad Face: Face

yueh commented 8 years ago

In this case we need exactly 1 AEColor per model, which applies 3 shades of the same (rgb) colour to some but not all faces. And these colours needs to be exposed for resource packs.

Elix-x commented 8 years ago

Configurable indexed color mapping. Huh. Doable.

yueh commented 8 years ago

Actually it would be indexed colour mapping per face and not model.

Or just pass the AEColor as property and use it to select the right texture for a face.

I would recommend looking at something like the dense cables. Black and fluix (transparent) use pretty similar shades, but a different order. Further you will notice that the are differences between fluix and colored cables in some details. So tinting/multiply them is not really an option. Or at least not without a different texture for fluix and for coloured.

Elix-x commented 8 years ago

I can pass isColored and color properties to models for fine tuning. Considering they can be ignored, they won't cause problems if they will. Color mapping though, works a bit in a different way: Each face has tintIndex -> passed to IBlockColors when model is rendered in world along with IBlockState, IBlockAccess, BlockPos, which returns color -> to render face with.

yueh commented 8 years ago

We should probably assess what data we actually need for blocks, cables, part, etc before making any plans. Common properties for decorative blocks (skystone can be rotated for example), normal blocks/tile entities and/or cables. Like cables have a different rotational behaviour. Itself they cannot be rotated, but every outer part can be, thus we have 6 parts each with 4 different rotations.

Elix-x commented 8 years ago

We will do cables when we're done with everything else, so let's leave them (and parts) for later. All blocks that aren't TEs already pass everything they should. We need to decide which data TE blocks have and which they pass to models.

dpeter99 commented 8 years ago

@elix-x For the block models there are 2 problems:

  1. 17

  2. if I make the ignore.json then it still will be able to rotate it with a wrench and it will show the missing model
Elix-x commented 8 years ago

17

We're in 1.10. I'm checking this / what may be causing this.

if I make the ignore.json then it still will be able to rotate it with a wrench and it will show the missing model

Working grinder example was included in last commit.

dpeter99 commented 8 years ago

Working grinder example was included in last commit.

https://youtu.be/Uik9q_0RLsk

Elix-x commented 8 years ago

It was partially working. I only precised forward=[north,south,east,west], so when forward=[up,down], it does not work. Hint: right click on front side, to rotate only up without rotating forward.

dpeter99 commented 8 years ago

OK I will make the models to support this and latter, the other rotations, that's why I would need all 3 axis.

Elix-x commented 8 years ago

Yeah i know about 3 axis and stuf... Checking...

yueh commented 8 years ago

That is why I meant we should assess first what data we need. Even if we do not need the cable parts now, some things will be shared between. Might even be used as documentation for resource pack makers later on.

Elix-x commented 8 years ago

@yueh in https://github.com/AEModernMCPort/Applied-Energistics-2/commit/0809ac5625cfb6eef89db1676c017ae585e8c67d, i imlemented automatic rotation. Now, i have 2 questions:

  1. Why does Light Detecting Fixture need to extend AEBaseTile and need 24 fcaing rotations + 6 torch type rotations? This kinda makes no sense.
  2. In theory, can charger contain item blocks that use built in models (TileEntityItemRender for instance)?
yueh commented 8 years ago
  1. Mostly because it has to be a tile entity. The 6 torch rotations seem to be unnecessary as the 24 facing rotations. But if I recall correctly, they use a meta based rotation system, not the 2 facing based one. (16 states should be enough to cover every rotation in this case).
  2. They can pretty much contain every subclass of Item, same as the inscriber. The are a bit more limited to only chargable things, so it is less likely. But the inscriber has to render everything a player throws at it. So why waste time to handle both differently when they need exactly the same functionality.

Regarding the facing/rotation stuff (that new enum etc).

If you introduce a custom enum, why even add invalid options? Some idiots will use them. For completeness it might make sense to add the 12 invalid as comments. But really not as valid options.

Further we will need two separate EnumFacing, there is absolutely not way around it. So we have to maintain redundant data for these cases. The splitted version is pretty much needed for a massive amount of repeating accesses/calls. While the rendering one should pretty much only be accessed once or at least not before the cached model becomes invalid. Keeping redundant data is a really bad idea, but removing the EnumFacing ones means, we have to compute just the front facing side pretty much many times for every single tileentity in every tick. Especially as the rendering based one does uses Vec3, which needs constantly be mapped to BlockPos provided by EnumFacing.

I am also not really a fan of this *.ignore.json. It will always be limited to rotations and pretty much identical for any block. So it would mostly just add more work to create two or more files, it can be a source for bugs because someone forget to create it, resource packs can still modify it and mess with it resulting in wrong rotations and so on. So it does not provide any real benefit of having it handled automatically besides reducing the json filesize, but still keep pretty much every keep every downside, if not even introduces more.

Basically we need a model generator, which is able to pass a subset of blockstates to a model loader to obtain the right model for this case and then afterwards apply the common states like rotation to it. There is no way around it for the cable rendering, In this case we even have to pass different blockstates per part and even allow the parts to maintain their own blockstates. For example we need to pass different states about power, channel or rotation to a part. While normal blocks are statisfied with 6_4 states for the final rotation and 4 states for power/channel, a cable will need at least 12_4 rotation states + 7*4 power/channel states per block. Probably even more.

Maybe it would be a better idea to write the cable model generator first as it needs to be pretty flexible to combine 13 different parts each with different states. So I would assume it should not be that difficult for it to combine just one model with a rotation. Would it not be better to have just one generator handling everything as it pretty much already has to provide nearly all functionality to render cables compared to have a custom one for cables, another one for drives and another one for chargers/inscribers, use forge blockstates for some a bit more complex blocks and just vanilla for the decorative blocks. Vanilla models are probably still valid for the easy decorative blocks or tools/items, but these are really separate from AE2, so it might even be an idea to move them to their own mod.

Elix-x commented 8 years ago

Mostly because it has to be a tile entity. The 6 torch rotations seem to be unnecessary as the 24 facing rotations. But if I recall correctly, they use a meta based rotation system, not the 2 facing based one. (16 states should be enough to cover every rotation in this case).

Right now, it has 2 te facings + meta based rotation. Which one do we keep?

They can pretty much contain every subclass of Item, same as the inscriber. The are a bit more limited to only chargable things, so it is less likely. But the inscriber has to render everything a player throws at it. So why waste time to handle both differently when they need exactly the same functionality.

Well, for sake of performance, we can combine block model and item model and render it once, it will cache the model and we don't have to render item each tick. Meanwhile, it will not be compatible with items using TileEntityItemRender. To be compatible with those, we need to have TESR rendering items each tick on top of the model.

If you introduce a custom enum, why even add invalid options? Some idiots will use them. For completeness it might make sense to add the 12 invalid as comments. But really not as valid options.

Further we will need two separate EnumFacing, there is absolutely not way around it. So we have to maintain redundant data for these cases. The splitted version is pretty much needed for a massive amount of repeating accesses/calls. While the rendering one should pretty much only be accessed once or at least not before the cached model becomes invalid. Keeping redundant data is a really bad idea, but removing the EnumFacing ones means, we have to compute just the front facing side pretty much many times for every single tileentity in every tick. Especially as the rendering based one does uses Vec3, which needs constantly be mapped to BlockPos provided by EnumFacing.

I am also not really a fan of this *.ignore.json. It will always be limited to rotations and pretty much identical for any block. So it would mostly just add more work to create two or more files, it can be a source for bugs because someone forget to create it, resource packs can still modify it and mess with it resulting in wrong rotations and so on. So it does not provide any real benefit of having it handled automatically besides reducing the json filesize, but still keep pretty much every keep every downside, if not even introduces more.

Basically we need a model generator, which is able to pass a subset of blockstates to a model loader to obtain the right model for this case and then afterwards apply the common states like rotation to it. There is no way around it for the cable rendering, In this case we even have to pass different blockstates per part and even allow the parts to maintain their own blockstates. For example we need to pass different states about power, channel or rotation to a part. While normal blocks are statisfied with 64 states for the final rotation and 4 states for power/channel, a cable will need at least 124 rotation states + 7*4 power/channel states per block. Probably even more.

Maybe it would be a better idea to write the cable model generator first as it needs to be pretty flexible to combine 13 different parts each with different states. So I would assume it should not be that difficult for it to combine just one model with a rotation. Would it not be better to have just one generator handling everything as it pretty much already has to provide nearly all functionality to render cables compared to have a custom one for cables, another one for drives and another one for chargers/inscribers, use forge blockstates for some a bit more complex blocks and just vanilla for the decorative blocks. Vanilla models are probably still valid for the easy decorative blocks or tools/items, but these are really separate from AE2, so it might even be an idea to move them to their own mod.

  1. Model rotations are now handled internally.
  2. I'm currently working on cable model baker - assembler - blender - whatever.
  3. Not much models need internal baking (for other reasons than rotation). Currently concerned models are cables and ones that contain items, if we go item model + block model way.
  4. If one day, we will add a property that is applicable to all blocks/items and is too much for jsons, it can be added any day to current model rotator.

Model rotator (in case you missed 0809ac5).

yueh commented 8 years ago

Right now, it has 2 te facings + meta based rotation. Which one do we keep?

Meta based rotation is pretty useless currently with blockstates. So get rid of it for now. The same probably also applies to the normal light fixture. Basic blockstate rotation might be used again for decorative blocks. But for now not important.

TileEntityItemRender

I have forgotten the assembler. Caching the whole model should actually be bad. In terms of the assembler we are talking about invalidating the cache every two ticks or at least update the model to another cached one. (Does this not require a full chunk rerender each time?). Static model + TESR for the item is probably the better solution in terms of performance (If still possible). Also the cache might get a bit large to store every assembler + item combination. Or without a reasonable size, it might constantly purge often used models. Caching our own models might still create a large amount, but at least that is mostly under our control. Like we know how many permutations we need depending on the parts and these need to be registered via our API for addons. A bit easier to handle than scanning every item registered to minecraft and try to guess a reasonable cache size for every item variant.

Model rotations are now handled internally.

I have referred to this. But it still exposes the ignorable states via the json (or that json is useless). So a resource pack can still decide to not ignore these states and we apply a rotation potentially twice. Or whatever else state we might need internally, but do not want to expose externally.

Not much models need internal baking (for other reasons than rotation).

Which actually means nearly every model needs baking for the rotations. We do not need baking multiple submodels together except for cables/parts, drives, chests and a few other blocks/items. It is just that a model generator, which could handle rotations and combine 1 to N submodels should cover most use cases and even if it itself is pretty complex, it still reduce the overall complexity by just having one rendering path and not different ones for potentially every single block. Also there is always the idea of reintroducing facades for block interfaces. Being able to extend this to other blocks might also be useful, e.g. cover drives with a different texture.

Elix-x commented 8 years ago

Meta based rotation is pretty useless currently with blockstates. So get rid of it for now. The same probably also applies to the normal light fixture. Basic blockstate rotation might be used again for decorative blocks. But for now not important.

Ok. Removing it.

I have forgotten the assembler. Caching the whole model should actually be bad. In terms of the assembler we are talking about invalidating the cache every two ticks or at least update the model to another cached one. (Does this not require a full chunk rerender each time?). Static model + TESR for the item is probably the better solution in terms of performance (If still possible). Also the cache might get a bit large to store every assembler + item combination. Or without a reasonable size, it might constantly purge often used models. Caching our own models might still create a large amount, but at least that is mostly under our control. Like we know how many permutations we need depending on the parts and these need to be registered via our API for addons. A bit easier to handle than scanning every item registered to minecraft and try to guess a reasonable cache size for every item variant.

Why each 2 ticks?

I have referred to this. But it still exposes the ignorable states via the json (or that json is useless). So a resource pack can still decide to not ignore these states and we apply a rotation potentially twice. Or whatever else state we might need internally, but do not want to expose externally.

"You have to write additional code to hardcode ignore some properties" hence i didn't write it, in case properties will be needed.

Which actually means nearly every model needs baking for the rotations. We do not need baking multiple submodels together except for cables/parts, drives, chests and a few other blocks/items. It is just that a model generator, which could handle rotations and combine 1 to N submodels should cover most use cases and even if it itself is pretty complex, it still reduce the overall complexity by just having one rendering path and not different ones for potentially every single block. Also there is always the idea of reintroducing facades for block interfaces. Being able to extend this to other blocks might also be useful, e.g. cover drives with a different texture.

Whole model baking pipeline is similar to what you said, though there are some differences. It has to be written (i'm working on it, but it's not working yet), and tested on cables.

Some words concerning entire thing: I think that we should follow another philosophy. Right now, with both mods and RP, we are like "you can do only this, this and this, and you can only do with these things, what we allowed you to", which is not ideal. It might be better if we followed this "you can do anything that you can do, but if you mess something up, you're responsible and we won't help". It simplifies what has to be done for us, we don't have to code additional thigns to limit activity. We don't have to close interfaces and other things. If we follow limiting and closing, eventually people will want to do things, to which we said no... And you know that this will end up with similar thing to Thaumcraft: addons ASMing mod's code just to add things beyond their limits.

yueh commented 8 years ago

Why each 2 ticks?

A crafting operation takes 2 ticks or so at max speed. Considering that there are usually multiple ones per chunk and they could be staggered, you can expect 1 chunk redraw/tick when using static models. Even chargers or inscribers are every few seconds.

"You have to write additional code to hardcode ignore some properties" hence i didn't write it, in case properties will be needed.

We will need it for parts. Each one will need their own part/block state and you have to pass them in a generic way. Not pass the full block state and let the part figure out where it is and select the correct data from a few dozen values. The rotation could even be handle without them knowing. But that still means there are like 12 different rotation states to be ignore per cable.

I think that we should follow another philosophy.

I personally think this is a very unprofessional/troublesome approach. It is essentially saying: OK, we know this will break and will cause issues for players. Who will not even know that resource packs can do it. We would be able to prevent it, we are just too lazy to do anything.

It is even more problematical that we would have to introduce an API version for the resource packs and have breaking changes. Like someone could copy the ignore files around, we change something and now the whole texture pack is non usable.

We simply cannot assume resource pack makers are able to read. There are some who can, but these are not the people, who will report these bugs. Most will simply copy&paste the folder, change a few textures and publish it. We change something, players will see AE2 crash and report it. While we are not even able to determine, if it is a real crash, a buggy resource pack or just an outdated one, because there are no such things as resource pack versions or dependencies.

Elix-x commented 8 years ago

A crafting operation takes 2 ticks or so at max speed. Considering that there are usually multiple ones per chunk and they could be staggered, you can expect 1 chunk redraw/tick when using static models. Even chargers or inscribers are every few seconds.

Ok, that explains it.

We will need it for parts. Each one will need their own part/block state and you have to pass them in a generic way. Not pass the full block state and let the part figure out where it is and select the correct data from a few dozen values. The rotation could even be handle without them knowing. But that still means there are like 12 different rotation states to be ignore per cable.

I personally think this is a very unprofessional/troublesome approach. It is essentially saying: OK, we know this will break and will cause issues for players. Who will not even know that resource packs can do it. We would be able to prevent it, we are just too lazy to do anything.

It is even more problematical that we would have to introduce an API version for the resource packs and have breaking changes. Like someone could copy the ignore files around, we change something and now the whole texture pack is non usable.

We simply cannot assume resource pack makers are able to read. There are some who can, but these are not the people, who will report these bugs. Most will simply copy&paste the folder, change a few textures and publish it. We change something, players will see AE2 crash and report it. While we are not even able to determine, if it is a real crash, a buggy resource pack or just an outdated one, because there are no such things as resource pack versions or dependencies.

Parts are different from all other blocks, they aren't not blockstates, but alike. Way data is passed is different too. As i said mutiple times already, parts aren't blocks (techincally they are, but the way they are handled is not the same) and when speaking of one, we hsould not speak of another, as things differ completely.

I agree, it will cause us hassle with crash reports. But then we need to find a middle between 2. If we allow everything, we will have untraceable issues, caused by resource pack. But if we limit too many things, people will find a way to break limits, thus causing even more untraceable crashes.

yueh commented 8 years ago

Parts are different from all other blocks

As things yes. But on an abstract level we basically need these things for pretty much both:

  1. Something to load models.
  2. Something to pass the state or a subset of it to the model (maybe part of 1.)
  3. Something to rotate a single part or block.
  4. Something to merge everything together and ideally cache it.

So my question is mostly, could we handle everything like parts? Load them, pass the needed states to it, rotate, merge, done? The rotation is pretty much the only data I currently can imagine of being hidden from the models. But that should probably be the only one ever.

Handling just the rotation in a static way is fine. The ignore functionality is also fine for optional things. Say if someone wants to ignore the color (these will never be replaced). The rules should probably be

  1. Is it something we use internally, to make it easier for resource packs? Do not expose it ever. (rotations)
  2. Is it something, which the resource packs need to consider to expose for the player? Leth them handle it. If we can make it easier to handle variants, do it. (is active, has channel, color, or whatever else like amount of channels for smart/dense cables, but never expose this to the other cables or machines).

I am not talking about addons, if these mess up that is not our problem. Also crashlog will contain them including their version. So if in doubt, we can also use a policy like "AE + addon X is not support, bug them about problems". But resource packs should be rock solid, that is just data and when something crashes because it encounters invalid data, it is simply an issue of the programmers being to lazy to validate it correctly. Of course their might be bugs, but they should be fixed and not just say "not our fault".

Elix-x commented 8 years ago

As things yes. But on an abstract level we basically need these things for pretty much both:

Something to load models. Something to pass the state or a subset of it to the model (maybe part of 1.) Something to rotate a single part or block. Something to merge everything together and ideally cache it. So my question is mostly, could we handle everything like parts? Load them, pass the needed states to it, rotate, merge, done? The rotation is pretty much the only data I currently can imagine of being hidden from the models. But that should probably be the only one ever.

Yes, sure. It's totally possible. Technically current model rotator already does 1, 3 and 4. But this was temporariry solution so that @dpeter99 can work on models without worrying about rotations, while i extend it to model baking pipeline (basically, with everything you mentionned + some other things).

Handling just the rotation in a static way is fine. The ignore functionality is also fine for optional things. Say if someone wants to ignore the color (these will never be replaced). The rules should probably be

Is it something we use internally, to make it easier for resource packs? Do not expose it ever. (rotations) Is it something, which the resource packs need to consider to expose for the player? Leth them handle it. If we can make it easier to handle variants, do it. (is active, has channel, color, or whatever else like amount of channels for smart/dense cables, but never expose this to the other cables or machines). I am not talking about addons, if these mess up that is not our problem. Also crashlog will contain them including their version. So if in doubt, we can also use a policy like "AE + addon X is not support, bug them about problems". But resource packs should be rock solid, that is just data and when something crashes because it encounters invalid data, it is simply an issue of the programmers being to lazy to validate it correctly. Of course their might be bugs, but they should be fixed and not just say "not our fault".

Ok, then, i'm not passing rotations to Rps. But there should be nothing else (for blocks), right?

Addons & RPs, yeah that's fine. But still, if RP has invalid jsons or jpegs instead of pngs, it's their problem.

Elix-x commented 8 years ago

@yueh why does stair block has separate feature handler?

yueh commented 8 years ago

If I recall correctly, stairs and slabs use a different parent class. Thus there are multiple handlers per parent class (block, tiles, cables, slabs, stairs).

With 1.8+ we can most likely get rid of them and just have one of simple blocks including stairs and slabs. (Not sure about the slabs and their special behaviour). Also I think the feature handlers could need a small refactoring, like there is clearly an abstract implementation missing, which handles the common thinks every handler is currently duplicating. Like say just use a template pattern for register/enabled and have a abstract class with a final register() handling enabled and calling abstract doRegister(), similar for isFeatureAvailable or getDefinition.

Further it really needs a pass over the item names, some of them are not following a common convention and this needs to be changed. But we could not do it in 1.7 as it would destroy items.