Jump to content

Zaerudath

Members
  • Posts

    34
  • Joined

  • Last visited

Everything posted by Zaerudath

  1. Observe other PRs carefully. Read the comments and see what gets accepted and what doesn’t and why. Write more code until you understand.
  2. Wow, man. That is a harsh reality. I've been burned before, too, long ago. Use this episode as your reminder in the future to follow a simple rule: check your code in. Always and forever, no exceptions. Following this rule has saved my butt more times than I can count. This saves you from more than just random deletion or failed hard drives. Maybe you stay up all night rewriting a core system thinking you're the next Donald Knuth or John Carmack because your code is SO BRILLIANT - only a few "minor issues" that you'll fix next session. But when you drag your groggy ass back to the keyboard with the benefit of some sleep you realize your code will never work - there's a reason nobody has done it this way before and it's obvious now in the clear light of day. Ah well, an unfortunate waste of time but at least it's easily undone. Without source control your embarrassment would be compounded by another whole day of backing our your changes and the fixes all the defects that come from it. So... if you aren't set up to check in your code, fix that first before you do anything else. It used to be harder. Nowadays source control is so excellent and effortless (and usually free!) that you really never have an excuse not to use it.
  3. Respectfully, this forum is for Forge modding. There is no need to use MCP directly if you are using Forge. I'll note that I do all my MC modding on OS X, and aside from having to endure the occasional gratuitous denigrating comment from Lex about how Macs are garbage, it works great. For more information on getting started with Forge, go here https://mcforge.readthedocs.io/en/latest/
  4. Check the vertex format of the baked quads you are generating. Item rendering requires normals for correct lighting and so you need to generate quads with ITEM vertex format that include proper normals. Quads in item format can also be used for block rendering if you don't need lightmaps.
  5. I have created dynamic flowing terrain blocks for a volcano that is part of mod I've been working on since 1.7. The code is currently on 1.12. Each terrain block has approximately 2^55 possible shapes, but many are redundant or not used. Blocks are mapped to IBakedModel delegates of a centralized model dispatcher that dynamically generates, bakes and caches models on demand. All dynamic model generation/dispatch is multi-threaded. Collision boxes are also generated on demand and cached. Terrain blocks are NOT tile entities. Shape is determined dynamically from neighbors. The exception is when the player breaks a block. When that happens, the shape of all nearby blocks is frozen and persisted in a tile entity so that mining basalt blocks doesn't cause the terrain to change shape. The volcano itself involves a hybrid celluar-automation/eulerian grid-based fluid simulation that runs on a separate thread pool between server ticks. All world access/udpates occur during server tick but are buffered and bundled to minimize the number of chunk updates / rebuilds. The simulation automatically loads chunks as needed. The volcanic lava behaves in a semi-realistic fashion, pooling and filling basins, overflowing, running into tunnels. It can even flow upwards through U-shaped channels to equalize surface levels globally. Viscosity and surface tension are also emulated, albeit very crudely. Cooling of lava to basalt happens when flow velocity slows. The volcano pauses lava ejection when CPU utilization of the simulation gets above a configured percentage. No ASM. No access transformers. It has been every bit the pain in the ass you would expect. At this time, the terrain blocks are limited to volcanic lava and basalt. It would be straightforward to implement world gen that replaces surface blocks with dynamic flowing versions. However, it would not be well-behaved with trees, grass, flowers, etc. And currently it does not handle MC fluids well. To do it right would require multi-part support and multi-part fluids. I would like to add broader terrain features at some point, but right now I'm focused on other aspects of the mod. I'm expecting to have the first alpha release for this mod on Curse within several weeks. Source code is here: https://github.com/grondag/Hard-Science
  6. Just a guess, but those patches of water may be decorations. (LAKE is what they are called in code, IIRC.). I wouldn't expect MC to generate lake decorations in a swamp, but I guess they normally just don't do anything. There is a way to disable decorations in a biome, but I don't recall offhand what that is.
  7. Yes, but range should not need to be that big. What is in BlockUpgC and what does your model look like? Does this thing have multiple render layers? I've also seen similar weirdness when trying to create blocks with multiple render layers where one of the layers is fully lit and others not.
  8. Try calling markBlockRangeForRenderUpdate instead of the block notify method in your onDataPacket method. You want to force a rebuild of the scene, which I am guessing may not happen if the block states updates, on their own, don't affect rendering. This works for me in a similar case where block color is stored in a tile entity and this information tends to show up at the client after the scene is already rendered. It may also be needed in the client-side onLoad() method.
  9. Getting blocks to not render isn't too difficult: place a non-colliding block that says it occludes neighboring faces and then don't render it. But this isn't actually very helpful in 1.8 because it is much smarted at culling caves and other faces that aren't visible to the player. So you can do it, but there isn't much to see. If you want to highlight hidden blocks with an outline, you could render that as an overlay, but it will still require OpenGL as Ernio points out. Rendering anything other than pre-defined block/item models is likely going to require OpenGL. Also, X-Ray mods are lame.
  10. Okay, I added a simple TileEntity to my block and used it to cache my extendedBlock state, which consists of two integers. I didn't handle persistence or synchronization because it wasn't needed for this test and the state will only change when a block of similar type if broken or added within a one-block distance. I built a little redstone/piston contraption on a largish platform of my blocks that I had placed earlier, and timed getExtendedState both using the TE cache, and with computing new state each time. Computing block state each time with getBlockState on neighbor blocks leveled off at 480 nanoseconds. This is lower than before because I'm excluding data from game initialization. When the scene first loads each call can take 20,000 ns or so but that only lasts a few seconds. 480 ns is great performance. Using cached block state in TE however, leveled off at a mere 76 ns per call. As before, times were longer at startup. Some blocks displayed a default texture for a fraction of a second because of null TE values before everything could be initialized, but I could live with that. I did not test over a network, but given that we're talking maybe twenty bytes of data per block (including the TE base class data) with very infrequent updates, I wouldn't expect it to be bad. So, there still may be arguments for not using tile entities in quantity to hold block appearance parameters that can't fit in block ID/metadata, but performance doesn't appear to be among them.
  11. That's been my design assumption all along. After going over the TE code last night, I'm not as certain. Now I'm itching to benchmark it. I'll post my results. Good point. I believe state for both blocks and tile entities is cached client-side and updates to either will require packets. I would assume block updates are more efficient, but in this particular case I'm not generating updates. That's actually what led me to the question: I have to query many block states to provide extended state, potentially multiple times a second, but in the vast majority of cases none of the block states I query will have changed.
  12. Looking at your code, but can't tell much cuz away from my computer. Did you walk it through in the debugger? The substitution code doesn't seem very hairy, so should be possible to follow what it is doing.
  13. Question for anyone with more experience: I've got some handsome blocks with connected textures that are meant to be used in quantity. Rendering happens via an ISmartBlockModel that returns the appropriate pre-baked faces depending on neighboring blocks. Each call to extended state requires a block state lookup for six to twelve (rarely more) neighboring blocks. The additional checks are needed to know if outside corners should be rendered and are skipped if both faces on a given axis are obscured. On my PC in debug the lookups for a single block cost about 3000 nanoseconds on average. Calculation of the unlisted property is simply looking up an integer in an array and I don't think I can make it much faster. That doesn't seem excessive, but I was wondering: how would performance compare if I instead cache this value in a tile entity? Obviously comes with some memory overhead, but it's only one hash map lookup, no ticking required, and I only have 4 bytes of data to load/save from NBT. I believe Carpenters Blocks took a similar approach. If I have a scene with lots of block updates occurring (moving pistons for example) the number of calls to getExtendedState could be much higher. I read that Algo had a similar challenge with Chisel and Bits, but block state there is going to a couple orders of magnitude more complex, so it may be a bad example. I'll have to use tile entities anyway for some of my blocks (stairs, slabs, various other parts and probably micro blocks) so that I don't completely consume all the block IDs. If I simply use tile entities for all of them I could create more variations in appearance (especially color) without consuming more block IDs. I'd also have a more consistent way to handle block state for all my blocks. That sounds nice for me, but creating blocks that essentially encourage the placement of tens of thousands of tile entities, even if they are very small in memory usage, seems...dangerous. On the other hand, I've seen many builds on video using tile entities with reckless abandon and their worlds didn't implode (much), and hash maps are quite robust, so... why not? I'm going to try it and profile it this weekend, so I guess I'll find out the hard way but I am curious if anyone else here has experience/advice to offer.
  14. If only there were a place we could go to report defects, hopefully with detailed instructions to reproduce and sample code... https://github.com/MinecraftForge/MinecraftForge/issues
  15. Changing world gen is probably not the best place to start if you are just getting started, and I would guess that you are. It isn't clear from your code what you're trying to do.
  16. During model bake event call... event.modelLoader.getModel(new ResourceLocation("your_mod:block/your_model_name.obj")); Thus endeth the tutorial.
  17. You can render this with ISmartBlockModel, though of course you'll still need a tile entity to know what fluid is stored in the tank. You'll need to construct a SmartBlockModel that returns a different model from handleBlockState (or from getQuads) depending on MinecraftForgeClient.getRenderLayer(). Presumably you would use SOLID or ALPHA for your inner fluid model and CUTOUT or ALPHA for the external tank. I suppose you could render both the tank and fluid with alpha, but you'd have to merge the baked quads from both models and return them via getFaceQuads or getGeneralQuads. I'm not exactly sure how you'll get the fluid texture because I haven't done that myself, but look at the new forge bucket - they had to do it somehow. One you have the fluid texture, call retexture on your fluid model before baking it. You could also dynamically bake a model or quads for each handleBlockState but there really aren't going to be so many fluids that you can't just pre-bake them and cache them all up front. You could cache them right in the SmartBlockModel and return the appropriate baked fluid model in handleBlockState.
  18. Nuchaz may be on to something. Also, update to latest forge if you haven't already. I recall there were a number of issues related to uv coordinates on OBJ models that got resolved relatively recently.
  19. The OBJ loader doesn't like negative UV coordinates, but it yells at you when that happens. (Or at least it did not long ago. Things change.) Anything in the logs? You can also look at the configuration in Blender for texture coordinates. Blender's militant unusability is too irritating for me, so I can't help more on the specifics. If I recall correctly, the loader expects values between 0 and 1.0.
  20. I am retexturing OBJ models, but I am pre-baking all the models during model bake and cacheing them in an ISmartItemModel class that returns the appropriate pre-baked model during handleBlockState. It should be possible to do this dynamically, but you'll likely want to cache your results and all your code will need to be thread-safe. So far the memory usage of pre-baked model variants seems acceptable even with relative large numbers of variants. The most relevant code is this: NiceCookbook.Ingredients ingredients = style.cookbook.getIngredients(substance, recipe, alt); IRetexturableModel template = (IRetexturableModel)event.modelLoader.getModel(new ModelResourceLocation(ingredients.modelName)); IModel model=template.retexture(ingredients.textures); this.models[alt][recipe]=model.bake(ingredients.state, DefaultVertexFormats.ITEM, textureGetter); The ingredients.textures call Returns an immutable hash map of textures to be used for baking. The template .OBJ model is loaded using a straightforward file system reference that includes the .OBJ suffix. For example: "adversity:block/col_round_four_faces_full.obj". Cast it to (IRetexturableModel) and then call .retexture with your textures. Your textures should all have been included during texture stitch so that they are available in the texture atlas. This is easily done with event.map.registerSprite. For the replacement textures to map correctly, use names without a # prefix in the .MTL file. Use those same names (again without a # prefix) as keys in the hash map of textures you pass to .retexture. As I'm typing this, I vaguely recall that the #prefix either was or is at some point going to be required, but it doesn't seem to be needed in the latest forge. Remember that your .OBJ models can share a .MTL file if you're going to be using the same material names in all of them. You can look at my working code if you promise not to laugh: https://github.com/grondag/Adversity. Code above is from NiceModel.handleBakeEvent.
  21. Thank you so much! I'm sure I was still days away from figuring that one out. Had not even thought to look there yet. You just made my day! Also, really appreciate all the work you've done on forge rendering. Some really powerful tools you've given us, and having lots of fun working with them so far. I have to take nap after only 30 minutes of quaternions and matrices, so I don't think my mod would even be possible if you hadn't done most of the heavy lifting already. Thanks again!
  22. Examine and compare the build.gradle files that ship with 1450 and 1563. If I recall correctly, there were other changes besides forge version.
  23. Try this: gradlew cleanCache setupDecompWorkspace --refresh-dependencies
  24. Well, it broke in build 1632, but going through the changes I can't see what would have caused it. My .OBJ models render fine in build 1630. Still guessing the bug is on my end. Nobody else is having this problem?
  25. You will need a way to rotate your block model. Probably the easiest way is via the forge extensions to blockstate files. However you do it, you'll then need to override your block's onBlockPlaced method and check the axis to return the appropriate block state. It will need to have code that does something like this: switch (facing.getAxis()) { case X: return blockX.getStateFromMeta(meta); case Y: return blockY.getStateFromMeta(meta); case Z: return blockZ.getStateFromMeta(meta);
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.