Jump to content

[1.12.2] Ticking tile entity updates slot with huge latency


Legenes

Recommended Posts

So I made a block with a ticking tile entity, and a tesr. The problem is when it's done with the "work", it inserts the item in the output slot with an almost 3-5 second latency. My computer isn't lagging at all.
Here's my code of the tileEntity: (please don't critise the setWork part and above, those are WIP)

Quote

package com.konrads.deserted_utilities.blocks.tileEntities.press;

import com.konrads.deserted_utilities.DesertedUtilities;
import com.konrads.deserted_utilities.blocks.tileEntities.press.messages.PacketRequestUpdatePress;
import com.konrads.deserted_utilities.blocks.tileEntities.press.messages.PacketUpdatePress;
import com.konrads.deserted_utilities.recipes.press.PressRecipe;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemStackHandler;

import javax.annotation.Nullable;

public class TileEntityPress extends TileEntity implements ITickable {

    public ItemStackHandler inventory = new ItemStackHandler(5);
    public boolean isWorking;
    public int progress = 45;
    public int waterLevel = 0;

    public Item currentOutputItem;
    public int currentOutputCount;
    public int currentGivenWater;

    public boolean run_;

    public void setWork(PressRecipe currentOutput) {
        currentOutputItem = currentOutput.output.getItem();
        currentOutputCount = currentOutput.output.getCount();
        currentGivenWater = currentOutput.givenWater;
        isWorking = true;
        progress = 0;
        inventory.getStackInSlot(0).shrink(1);
        inventory.getStackInSlot(1).shrink(1);
        inventory.getStackInSlot(2).shrink(1);
        inventory.getStackInSlot(3).shrink(1);
    }

    @Override
    public void onLoad() {
        if (world.isRemote) {
            DesertedUtilities.network.sendToServer(new PacketRequestUpdatePress(this));
        }
    }

    @Override
    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        compound.setTag("inventory", inventory.serializeNBT());
        compound.setBoolean("isWorking", isWorking);
        compound.setInteger("waterLevel", waterLevel);
        return super.writeToNBT(compound);
    }

    @Override
    public void readFromNBT(NBTTagCompound compound) {
        inventory.deserializeNBT(compound.getCompoundTag("inventory"));
        isWorking = compound.getBoolean("isWorking");
        waterLevel = compound.getInteger("waterLevel");
        super.readFromNBT(compound);
    }

    @Override
    public boolean hasCapability(Capability<?> capability, @Nullable EnumFacing facing) {
        return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing);
    }

    @Nullable
    @Override
    public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing) {
        return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY ? (T)inventory : super.getCapability(capability, facing);
    }

    @Override
    public AxisAlignedBB getRenderBoundingBox() {
        return new AxisAlignedBB(getPos(), getPos().add(1, 2, 1));
    }

    public void endProgress() {
        waterLevel += currentGivenWater;
        if (waterLevel > 1000)
            waterLevel = 1000;
        inventory.insertItem(4, new ItemStack(currentOutputItem, currentOutputCount), false);
        isWorking = false;
        progress = 45;
    }

    @Override
    public void update() {
        if (isWorking) {
            if (progress >= 65)
                endProgress();
            else
                progress += 1;
        }
    }

}

 

What am I doing wrong? Thanks for help!

Edited by Legenes
procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

6 hours ago, diesieben07 said:
23 hours ago, Legenes said:

DesertedUtilities.network.sendToServer(new PacketRequestUpdatePress(this));

wtf is this? You do not need this in any way.

  

Interestingly, I do. My tesr uses the block's properties to render, and if I don't send this packet, my tile won't work till' I use it. (After world load it wouldn't render the things that are set in the tile, like the progress variable. Defaultly it should be 45, but without this message it's 0)

 

6 hours ago, diesieben07 said:
23 hours ago, Legenes said:

public ItemStackHandler inventory = new ItemStackHandler(5);

ItemStackHandler by default does not mark your tile entity for saving. You need to create an ItemStackHandler subclass which calls markDirty in onContentsChanged.

Thanks, I'll try that.

 

6 hours ago, diesieben07 said:

Now for your question of delay: How are you observing this delay?

First: I see it poping up with late in the gui.
Second: I used System.PrintLn at the end of the progress, and after the slot changed.

Edited by Legenes
procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

7 minutes ago, diesieben07 said:
15 minutes ago, Legenes said:

Second: I used System.PrintLn at the end of the progress, and after the slot changed.

Please clarify this.

    public void endProgress() {
	#<--- Here System.Out.PrintLn("Setting water");
        waterLevel += currentGivenWater;
        if (waterLevel > 1000)
            waterLevel = 1000;
    	#<--- Here System.Out.PrintLn("Inserting item"); (no delay)
        inventory.insertItem(4, new ItemStack(currentOutputItem, currentOutputCount), false);
        isWorking = false;
        progress = 45;
    	#<--- Here System.Out.PrintLn("Complete"); (3/5 seconds in log)
    }

 

EDIT:

7 minutes ago, diesieben07 said:
15 minutes ago, Legenes said:

Interestingly, I do. My tesr uses the block's properties to render, and if I don't send this packet, my tile won't work till' I use it. (After world load it wouldn't render the things that are set in the tile, like the progress variable. Defaultly it should be 45, but without this message it's 0)

Then the server should just send the data. There is no need for the client to request it like this.

Thanks, It's much simpler.

Edited by Legenes
procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

I made some changes, and now these things are happening at the same time. But in the gui they still show late, and if I quit the gui, then I can't rightclick the block util it finishes "updating" it.

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

17 hours ago, diesieben07 said:

Very strange. If that is really true then only the insertItem can be the slow thing. But you say you don't have any server lag? This sounds impossible.

The way my block works is that I'm searching for an Item in my custom recipe database. As it turned out, it was crappy, and I needed to reimplement it. Now the inserting itself is not instant, but it's about a quarter second (I can't see delay in log messages), and it's okay to me.

Now I have another problem. When my tile calls onLoad(), it doesn't load any of the nbt, it only works after using the block itself.

Is there any idea what's causing it?
(P.S.: Now I save every variable into nbt.)

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

Just now, diesieben07 said:

Please clarify this. How did you check that it "loads the nbt"? 

In the gui it only loaded the inventory, everthing else was 0.
 

 

1 minute ago, diesieben07 said:
18 minutes ago, Legenes said:

(P.S.: Now I save every variable into nbt.)

Why?

Not literally everything, but every variable that is needed to continue the progress after load. Like the furnace.

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

OMG, Thanks! Now the insertItem part is instant, and everything works as it should. ?

procedure WakeMeUp(Integer plusTime);
var
  I: Integer;
begin
  for I := 0 to plusTime do begin
    println('One more minute!');
    Sleep(1000);
  end;
  println('Okay, nothing to worry, I''m alive!');
  println('So... somebody can give me a coffee?');
  println('I know it''s Pascal, and not Java, but I love it :D.');
end;
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • They were already updated, and just to double check I even did a cleanup and fresh update from that same page. I'm quite sure drivers are not the problem here. 
    • i tried downloading the drivers but it says no AMD graphics hardware has been detected    
    • Update your AMD/ATI drivers - get the drivers from their website - do not update via system  
    • As the title says i keep on crashing on forge 1.20.1 even without any mods downloaded, i have the latest drivers (nvidia) and vanilla minecraft works perfectly fine for me logs: https://pastebin.com/5UR01yG9
    • Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this :  The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) :  The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock :   Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item :    @Override     public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {         if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) {             BlockPos blockPos = pContext.getClickedPos();             BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos));             if (secondBlockPos != null) {                 createFrozenBlock(pContext, secondBlockPos);             }             createFrozenBlock(pContext, blockPos);             return InteractionResult.SUCCESS;         }         return super.useOn(pContext);     }     public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) {         BlockState oldState = pContext.getLevel().getBlockState(blockPos);         BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null;         CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null;         if (oldBlockEntity != null) {             pContext.getLevel().removeBlockEntity(blockPos);         }         BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData);         pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock);     }     public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) {         BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState();         ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData);         return FrozenBlock;     }  
  • Topics

×
×
  • Create New...

Important Information

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