Jump to content

target.san

Members
  • Posts

    88
  • Joined

  • Last visited

Posts posted by target.san

  1. 1) Why not? The only reason i see is backwards compatibility. And TileEntity is in fact just a separate place for part of state and part of logic. It concludes IMO to moving logic to Block and state to BlockState.

    2) I mean, ItemStack now holds NBTTagCompound directly. (De)serialization is done less often than property access. So, let's allow having some data structure instead, so Item can do one checked cast and then access properties directly. Less NBT-related code around.

     

    Ultimately this goes down to rewriting all with some kind of Object-Data-Behavior system. i know, not gonna happen.

  2. Hi,

     

    i noticed (heh :) several major changes in Minecraft logic, which although look incomplete. I'm talking about BlockState, where block type and its meta were in fact packed into semi-opaque structure. So, what if bring this to logical conclusion?

    1. TileEntity ceases to exist as separate concept. All logic is moved into Block class, and state is persisted inside IBlockState thing, which is NBT-serialized as it wants too. Though, it's still a question on how to separate meta-only and NBT-ful blocks states and where to store NBT-based ones.

    2. ItemStack will hold some kind of IItemState object, which represents its state and also NBT-packed as it wishes.

     

    i know such changes are dictated by Minecraft.

    But, any thoughts?

  3. Okie, so that wasn't that smooth for me.

    To be clear, I'm using Forge 1.8.9-11.15.1.1722 (latest stable AFAIR)

     

    Frankly speaking, the only way of attaching model to item which worked for me was

            Item item = WorldRift.instance.itemRiftWand;
            Minecraft.getMinecraft().getRenderItem().getItemModelMesher()
            .register(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory"));
    

    invoked in client proxy's init event specialization. Now, some details.

     

    1. Resources structure

     

     

    + assets
    + worldrift
      + blockstates
       - rift.json // my block, not related 
      + models
       + block
        - rift.json // my block's model, also not related
       + item
        - riftwand.json // my item model
      + lang
       - en_US.lang // just lang file
      + textures
       + block
        - rift.png // block texture, not related to my case
       + item
        - riftwand.png // item texture
    

     

     

     

    2.

    models/item/riftwand.json

     

    {
      "parent":"builtin/generated",
      "textures": {
        "layer0": "worldrift:item/riftwand"
      },
      "display": {
        "thirdperson": {
          "rotation": [ -90, 0, 0 ],
          "translation": [ 0, 1, -3 ],
          "scale": [ 0.55, 0.55, 0.55 ]
        },
        "firstperson": {
          "rotation": [ 0, -135, 25 ],
          "translation": [ 0, 4, 2 ],
          "scale": [ 1.7, 1.7, 1.7 ]
        }
      }
    }
    

     

     

    Now, to my findings

    1. Adding

    blockstates/riftwand.json

    without any Java-side code doesn't do any good. File text I used, just for reference

    {
      "variants": {
        "normal": { "model": "worldrift:rift" },
        "inventory": { "model": "worldrift:rift" }
      }
    }
    

     

    2. Attempt to load via

            Item wand = WorldRift.instance.itemRiftWand;
            ModelResourceLocation loc = new ModelResourceLocation(wand.getRegistryName(), "inventory");
            ModelLoader.registerItemVariants(wand, loc);
            ModelLoader.setCustomModelResourceLocation(wand, 0, loc);
    

    also gives no result. I tried putting model name manually, using empty variant, putting this into both pre-init and init etc.

     

    If you ask what were the errors - I encountered either no errors at all or

    FileNotFound

    for

    blockstates/riftwand.json

    when loader apparently falled back to blockstates as thelast resort.

     

    Several mods I checked on Github also use

    getItemMesher

    approach.

     

    So I'm a bit lost at the end, with recommended ways failing.

  4. One can register block without registering related item, i.e. passing

    null

    for item class.

    It might be appropriate if some block doesn't make any sense in item form.

    The question is, is it safe? Won't it produce some random NPEs because some code would want "item for that bock"?

    Or I'd better make stub item for this purpose?

  5. No. Minecraft will automatically load the model with the

    Item

    's registry name if you don't call

    ModelBakery.registerItemVariants

    for it, but it won't use that model unless you tell it to.

     

    You must call

    ModelLoader.setCustomModelResourceLocation

    or

    ModelLoader.setCustomMeshDefinition

    to tell Minecraft which model to use for an

    Item

    .

     

     

    I think that's the problem I'm facing. I was somehow thinking that MC will utilize model which it loaded automatically. A bit surprising, but nothing too hard. Thank you for your time.

  6. Started modding after a break and a bit confused.

     

    As I understand, the preferred way to load block models is through blockstate.

    Though, it's not clear what's the one for items. Which seem to not load any model data automagically based on their registry names. I found following variants:

     

    1.

    Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register

    from BedrockMiner's tutorials

    2. Use

    ModelBakery.registerItemVariants

    3. Use

    ModelLoader.registerItemVariants

    (which looks like #2)

     

    Can anyone point to some mini-guide? Google shows too much info, and Forge docs are rather slim

     

    Thanks

     

    Sidenote: It'd be nice to have some common entrypoint for all Forge stuff, like root

    Forge

    class with methods/fields like

    gameRegistry

    ,

    modelLoader

    etc.

  7. Yes, indeed. Although I am not sure why you mean by "block flyweights".

    Block classes. They're essentially 'flyweight' pattern.

    How do you mean?

    By having some kind of

    private lazy val dispatcher = if (worldObj.isRemote) ClientDispatcher else ServerDispatcher
    

    then delegating all methods through that dispatcher

    Usually you have to check, there is no other way. Some methods are only called on the server or on the client though, checking would be unneeded there.

    I mostly mean methods like onNeighborBlockChange, which are called both on logical server and logical client. Though I'll have no other option for blocks anyway, as I can't check whether specific block instance construction happens on client or on server.

  8. ...

    Conclusion:

    World.isRemote

    is the way to go.

     

    Ok, thanks, got it.

    Though I have another stupid question. Do we always have 2 instances of tile entities, normal entities, block flyweights etc. for logical client and server? Or there's one instance in case of integrated server? What I need to know is, can I have some kind of central dispatch point for 'client' or 'server' methods? Or do I need to check for World#isRemote every time, and there's no other way? Because, TBH, it's annoying to have "if (worldObj.isRemote) return;" in each method.

  9. Hi!

     

    I've noticed in my mod that I have too much stuff like if (worldObj.isRemote).

    So I decided to move to some more unified client/server logic decoupling. With this, I came to two possible solutions

    1. Use FMLCommonHandler.getSide, which effectively returns side. Then have some private var in my TE's or blocks which would reference client or server implementation, then delegate all calls there.

    2. Use SideOnly annotation. The problem is, it's said to be used for Forge's internal use only.

     

    So, which way is considered more convenient? Aside from fact that approach 1 allows for different logic on the same actions, where approach 2 doesn't.

     

    Thanks.

  10. Hi again!

     

    I'm now in process of providing support for several types of TE's in my linking block. The idea is, we have two blocks, in different positions and possibly in different dimensions. At example, we put some pipe on the north side of 1st linker, and on the south side of 2nd linker, and two pipes connect like they're adjacent. Sort of.

     

    So, can anyone please provide some insight on what interfaces should I implement to make ME cables work, i.e. create valid network? I suspect it's somehow related to appeng.me.helpers.IGridProxyable.

     

    Thanks.

  11. Then you'll have to use the ChunkEvents instead to mark your cache invalid, but it should not be too hard, either.

    That's not a problem actually. I already use own tiny chunk watcher which notifies linkers that their linked entities are unloaded

    I know. But that is not why you should use a WeakReference. Imagine the following scenario:

    A TileEntity that is in your cache becomes invalid because it's Block is removed. But your TE is not currently "in use" (transporting items, etc.), therefor it does not check it's cache and the (strong) reference to the invalid TE keeps it from being GC'd, which a WeakReference would not.

    I've workarounded this by making my own tiny cacheable resettable wrapper. It's dropped when anything changes. Actually, each of wo linkers in a pair notifies second one that it has blocks changed around, or it's unloaded, or whatever. Then second one drops its caches, freeing TEs. Though WeakRef might really make code cleaner. Or not, since I don't always expect TE to be there. And WeakRef doesn't allow to distinguish 'null ref' from 'dead ref'.

     

    Anyway, I thought a bit on a problem and decided to not enforce chunks loaded around portal. Since it's rather generic-use, and there might be many of them. Effectively exceeding per-player or per-mod chunk load limit.

     

    Thanks.

  12. AFAIK TE isn't marked invalid when it's unloaded, only when it's actually dead. Otherwise I'd stumble upon such behavior much earlier, having my portals disassembled on each chunk unload.

     

    WeakReference, as I wrote earlier, isn't deterministic due to GC. It won't get null immediately after last strong reference to object is removed.

  13. Hi fellow modders

     

    I have kind of architectural dilemma at the moment.

    I may make my portals load certain chunks in vicinity, and simplify my code significantly.

    Or I may not enforce this requirement, which would make my code significantly more complex.

     

    I'm developing kind of better portals mod in my spare time.

    One of the features I'm implementing now is transparent inventory/pipe/fluid/redstone connection through portal. The logic is, you place one of connected entities at specific position adjacent to portal frame (let's call it so), and the other on the other side, and they should be able to communicate like they're adjacent to each other.

     

    This is done via tile entity methods delegation.

     

    To make this thing reasonably fast, I'm caching certain TE references. Though, as you know, chunk may unload, and so all TE instances will become dead objects and subjects to GC. So I need to refresh those references, which involves not-so-trivial event handling, chunk watching and so on. I cannot use WeakReference since GC is non-deterministic.

    Or, as I wrote above, I may force load chunks which contain blocks of potential interest to me, thus making TE references always valid, except cases when they're changed. As a side-effect, it would make travel a bit smoother. As a drawback, players would have some chunks being always loaded.

     

    So, is it ok to make portal a permanent chunkloader or not?

     

    Thanks

  14. @rypofalem Thanks for your interest. Though I can't call my solution very elegant.

     

    Code is here https://github.com/target-san/Gateway

    The main problem is - it's Scala, and not very clean.

    The classes of interest are TileSatellite, ChunkWatcher and EventHandler.

     

    The main idea:

    1. Satellite TE (the watcher) asks ChunkWatcher to register itself as a watcher for specific block. In fact, a whole chunk is added to its internal multimap.

    2. EventHandler catches ChunkEvent.Unload, then calls ChunkWatcher.onChunkUnload. The latter finds set of watcher 4D coordinates by their chunk coordinate key, then calls onWatchedChunkUnload for those which are loaded at the moment.

     

    Please note that there's a bug in my code elsewhere, so you won't be able to run the whole mod from master now.

  15. The case is, I'm interested not in linked blocks themselves, but in their immediate neighbors. So I can't rely on my linkers' onChunkUnload, because their neighbor blocks might reside in different chunk.

     

    Anyway, I've already devised a not so bad logic, with ChunkEvent.Unload and a custom chunk watcher. This allowed me to watch for tiles of interest right from the linker on the other side.

  16. Please read javadoc on IEnergyHandler. It's written pretty well.

    In particular extractEnergy/receiveEnergy should return the amount of energy being transferred out/in. And you're returning 0 from extractEnergy. No wonder you're getting no RF output.

    Please also note that EU and RF aren't 1:1. AFAIK the ratio is usually 4 EU to 10 RF.

     

  17. Hi!

     

    I'm having two linked blocks in different dimensions. Each of these blocks is a connector which tries to behave on some of its sides like a tile which is adjacent to its partner's opposite side. For performance reasons, I'm caching those tiles being represented by partners by reference.

    Here's the question goes. How can I detect that some instance of TileEntity object is invalid in the sense that some chunk was unloaded, then loaded, and so I need to reacquire TE reference.

    The problem is, TE in question and connector might reside in different chunks. So I cannot rely on connector's onChunkUnload.

    I cannot also rely on isInvalid, since TE isn't invalidated on unload.

    Maybe there's some way to detect chunk unload of adjacent tile?

     

    Thanks.

     

  18. A sample for TE which changes its set of behaviors is any multipart. Any multipart-enabled pipe or power conduit. See my prev. topic on this issue.

    Basically, it's anything complex enough to be composed of several parts and thus having several behaviors which might appear and vanish.

     

    As for neccessity. Sure, we can live without it... but it's a painful life. And the solution I propose won't only allow to do some new stuff, but also simplify existing stuff significantly.

×
×
  • Create New...

Important Information

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