Jump to content

Looking for a "tick" guide [1.18.2]


virtualoxygen

Recommended Posts

Hi, I'm trying to set (reset) a blockstate after a certain amount of ticks. I can't seem to find any examples on how ticks are used in general.

The below method is for an item. If a block is clicked with the item, it changes the block to another one. I want to implement a timer that resets this block to its original state.

 

    @Override
    public InteractionResult useOn(UseOnContext pContext) {
        if (!pContext.getLevel().isClientSide()) {
            BlockPos positionClicked = pContext.getClickedPos();
            BlockState originalBlockState = pContext.getLevel().getBlockState(positionClicked);
            pContext.getLevel().setBlock(pContext.getClickedPos(), Blocks.PUMPKIN.defaultBlockState(), 3);
            // TODO reset to originalBlock after ticks (e.g. 10 seconds)
        }
        return super.useOn(pContext);
    }

 

A little code snippet or a pointer to a few examples would be very helfpful.

Link to comment
Share on other sites

Normally there are 2 ways to get a block to tick.

Use a BlockEntity (like a furnace keeping track of burn time) or have the block implement random ticking (like crop growth).

You can also use the LevelTickEvent to implement more generic things, but for your usecase you will then have the problem of where to keep track of per block state.

You might for example attach a capability to the LevelChunk that contains the block to hold the data?

See DataStorage here: https://forge.gemwire.uk/wiki/Main_Page

Edited by warjort
  • Thanks 1

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

3 hours ago, diesieben07 said:

In general "tick" means a game update, the game updates 20 times every second, so there are 20 ticks every second. If you wait 40 ticks, you have waited 2 seconds (assuming the server thread is not lagging).

You have to remember the position, most likely in a Level capability and then use LevelTickEvent (note that it fires twice every tick) to check if there is a position to reset this tick.

    @SubscribeEvent
    public static void countTicks(TickEvent event){
        if(!ticking) return;
        ticks++;
        if(ticks == 100){
          // do stuff and reset
        }
    }

Ok, thank you. I managed to get it to work with the above code. I could not find `LevelTickEvent` in the codebase. Not sure if its the same as `TickEvent`

Link to comment
Share on other sites

In 1.18.2 it is called WorldTickEvent

I think if you subscribe to TickEvent you will get all tick events; server, level, player, etc. ? So you will get a lot more events than you want.

 

As described above, you need to look at event.phase (either START or END) otherwise you will be doubling counting.

Similarly, you might want to check event.side if you don't want your code to run on both the logical client and server, usually ticking is only done on the client to support things like animations.

 

Finally, you can't store the ticking/ticks like you are probably doing.

What if there are 2 blocks that you need to tick?

What if somebody restarts the game while it is ticking. What is going to save/reload the ticking/ticks state?

See the comments above about capabilities for how to solve this.

Edited by warjort
  • Thanks 1

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

14 minutes ago, warjort said:

In 1.18.2 it is called WorldTickEvent

I think if you subscribe to TickEvent you will get all tick events; server, level, player, etc. ? So you will get a lot more events than you want.

 

As described above, you need to look at event.phase (either START or END) otherwise you will be doubling counting.

Similarly, you might want to check event.side if you don't want your code to run on both the logical client and server, usually ticking is only done on the client to support things like animations.

 

Finally, you can't store the ticking/ticks like you are probably doing.

What if there are 2 blocks that you need to tick?

What if somebody restarts the game while it is ticking. What is going to save/reload the ticking/ticks state?

See the comments above about capabilities for how to solve this.

Hi, I was just responding to your other comment.

Ok, I changed it to this. Is this what you mean?

@SubscribeEvent
public static void countTicks(TickEvent.WorldTickEvent event) {...

On saving the ticks: I know its not the right way and only works for one block. Its meant for testing only at the moment. I will have a read thru the capabilties in the link you provided. I also had a look at the Furnace and BlockEntity, but find it hard to understand how the FurnaceTicker is working. (I'm fairly new to the minecraft codebase).  Anyways thanks for the help.

Link to comment
Share on other sites

Yes for the event name.

 

For the furnace ticker look at BlastFurnaceBlock.getTicker() and how its helper method creates a server side ticker for AbstractFurnaceBlockEntity.serverTick()

The "litTime" in the BlockEntity would be equivalent to your ticks.

  • Thanks 1

Boilerplate:

If you don't post your logs/debug.log we can't help you. For curseforge you need to enable the forge debug.log in its minecraft settings. You should also post your crash report if you have one.

If there is no error in the log file and you don't have a crash report then post the launcher_log.txt from the minecraft folder. Again for curseforge this will be in your curseforge/minecraft/Install

Large files should be posted to a file sharing site like https://gist.github.com  You should also read the support forum sticky post.

Link to comment
Share on other sites

2 hours ago, warjort said:

Yes for the event name.

 

For the furnace ticker look at BlastFurnaceBlock.getTicker() and how its helper method creates a server side ticker for AbstractFurnaceBlockEntity.serverTick()

The "litTime" in the BlockEntity would be equivalent to your ticks.

Ah ok, so in my case, litTime could be hardcoded becuase it is not depending on a fuel type. 

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



×
×
  • Create New...

Important Information

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