Jump to content

[SOLVED] Wait (x) seconds *WITHOUT PAUSING GAME*


OnePoundPP

Recommended Posts

Got a quick question. I know using Thread.Sleep or anything as such causes minecraft to pause aswell as it is single threaded, which is obviously a nuisance...

Is there anyway to insert a delay between executing lines of code WITHOUT pausing minecraft?

 

For example:

 

KeyPresser.KeyPress(KeyEvent.VK_W);

//WAIT 1 SECOND WITHOUT PAUSING MINECRAFT

KeyPresser.KeyRelease(KeyEvent.VK_W);

 

 

I do have a tick handler class, but not really sure how this would help in this case...

Thanks in advance!

Link to comment
Share on other sites

Yes, you can, but only if you understand multithreading well. For example you cannot interact with Minecraft at all from this separate thread, for the most part.

 

I did not know that. You can't, for example, interact with a TileEntity from a separate thread?

Link to comment
Share on other sites

You have to exit out of the method, count ticks in a tick handler and then when you have counted the right amount of ticks (20 ticks = 1 second) you run the next part of the code.

 

Ok, how would I go about exiting the method and then returning at the same point?

I'm guessing i'd have to go into my TickHandlerClass and then run a command to exit the EventHandlerClass(where I'm using the Robot KeyPresser), and then run a command to re enter at the same point?

Link to comment
Share on other sites

Yes, you can, but only if you understand multithreading well. For example you cannot interact with Minecraft at all from this separate thread, for the most part.

 

I did not know that. You can't, for example, interact with a TileEntity from a separate thread?

 

TileEntities exist in the world, so no.

 

Ok, how would I go about exiting the method and then returning at the same point?

 

It's called "two separate functions."

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Does the game crash if you do that?

 

That entirely depends on a race condition and exactly what you're doing. But yes, it would, eventually. With a ConcurrentModificationException.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Yes, you can, but only if you understand multithreading well. For example you cannot interact with Minecraft at all from this separate thread, for the most part.

 

I did not know that. You can't, for example, interact with a TileEntity from a separate thread?

 

TileEntities exist in the world, so no.

 

Ok, how would I go about exiting the method and then returning at the same point?

 

It's called "two separate functions."

 

I'm pretty sure I have an idea of what I'm meant to do, just not how to do it...

 

In simple terms, in class 1 I would have:

 

KeyPresser.keyPress(KeyEvent.VK_W);

RUN METHOD IN CLASS 2

KeyPresser.keyRelease(KeyEvent.VK_W);

...

 

And the method in Class 2:

 

thread.sleep(20) (FOR ONE SECOND)

 

 

Is this how I would do it? and how would this look in code, I'm new to JAVA, appologies. If this is anything like Python, i'd make a function containing code and then call that function but its not as simple as that in java I'm gathering...

 

 

 

Link to comment
Share on other sites

That's not at all how Thread.sleep works. Thread.sleep, as the name implies blocks the entire thread for the duration.

 

As diesieben07 said, you have to use a tick handler and count the number of ticks that have passed to determine the amount of time that has passed.

Don't make mods if you don't know Java.

Check out my website: http://shadowfacts.net

Developer of many mods

Link to comment
Share on other sites

That's not at all how Thread.sleep works. Thread.sleep, as the name implies blocks the entire thread for the duration.

 

As diesieben07 said, you have to use a tick handler and count the number of ticks that have passed to determine the amount of time that has passed.

 

But I don't need to determine the amount of time that's passed? I just need to insert a delay between two commands running which doesn't pause the entire game, I don't really understand how a tick handler will help, don't really understand how ticks work, all I know is minecraft tick's 20 times per second, I'm guessing its obvious that i'm quite new but what you're saying makes little sense to me. How would i code a delay without pausing minecraft?

Link to comment
Share on other sites

Intro:

Minecraft runs on 2 (+2 network) threads (http://mcforge.readthedocs.org/en/latest/concepts/sides/), you want to do stuff on client (bot?).

Each thread tick 20 times, 1tick = 50ms.

Aside from partialTicks (rendering only), this is "planck time" (smallest) in Minecraft world.

 

What to do?

Make scheduler.

1. @SubscribeEvent to ClientTickEvent.

- Check for event.phase (pick one).

2. Create static Queue or List or whatever (its important it's elements are ordered by inserting).

- You will be throwing "commands" to that list.

- Those "commands" will be calls to execute specific key.

3. Make ClientTickEvent execute one command at time from top of ordered list above every few ticks.

- 10 ticks = 0.5sec like you want.

- You want to do:

int ticks;
Queue commands;
ClientTickEvent
{
    if (ticks % 10 && !commands.isEmpty)
    {
       commands.getFromTop().call();
       commands.removeFromTop();
    }
    ++ticks;
}

4. Throw "commands" from wherever you want (client thread) into queue.

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

But I don't need to determine the amount of time that's passed?

 

Surprise, that's what a tick handler is for.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

That's not at all how Thread.sleep works... you have to use a tick handler...

 

I don't really understand how ticks work...

 

You said yourself that you want Minecraft to continue, so you must allow it to continue ticking. However, your thinking has been at the (virtual) machine stop level, which is the wrong level of thinking.

 

I'm reminded of how DOS programmers stumbled when they first encountered the Windoze "message loop". It took a while to wrap one's head around the idea that one's "program" was really just one subroutine among many being called repeatedly by the real master program. In that case it was the OS, but in this case, it's Minecraft.

 

Since your method may not hog the CPU all to itself for several seconds of GUI interaction, you must write code that can run in a series of blinks, somehow storing intermediate results for later resolution. In effect, Minecraft keeps ticking right along, but some sequence of your actions is spread out over time.

 

That's what tick handlers do. Your logic wakes up, looks at the world and its own preserved thoughts, increments tick counters, make decisions, take actions, stores (or wipes) data for next time, and then exits to allow the rest of the program to continue.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

Intro:

Minecraft runs on 2 (+2 network) threads (http://mcforge.readthedocs.org/en/latest/concepts/sides/), you want to do stuff on client (bot?).

Each thread tick 20 times, 1tick = 50ms.

Aside from partialTicks (rendering only), this is "planck time" (smallest) in Minecraft world.

 

What to do?

Make scheduler.

1. @SubscribeEvent to ClientTickEvent.

- Check for event.phase (pick one).

2. Create static Queue or List or whatever (its important it's elements are ordered by inserting).

- You will be throwing "commands" to that list.

- Those "commands" will be calls to execute specific key.

3. Make ClientTickEvent execute one command at time from top of ordered list above every few ticks.

- 10 ticks = 0.5sec like you want.

- You want to do:

int ticks;
Queue commands;
ClientTickEvent
{
    if (ticks % 10 && !commands.isEmpty)
    {
       commands.getFromTop().call();
       commands.removeFromTop();
    }
    ++ticks;
}

4. Throw "commands" from wherever you want (client thread) into queue.

Right, this is starting to make sense... I add commands to a queue which is handled by another class on each client tick, the commands i'd add in order would be like press key D, followed by release key D and one line would be executed for each client tick, right?

 

I added this code to a separate class but its coming up with errors, possibly due to a different version?

 

int ticks;

Queue commands;

 

@SubscribeEvent

public void onClientTick(TickEvent.ClientTickEvent event){

if(ticks % 10 && !commands.isEmpty()){  *Line doesn't work*

commands.getFromTop().call; *GET FROM and REMOVE FROM top not recognized*

commands.removeFromTop();

}

++ticks;

 

}

Link to comment
Share on other sites

Right, this is starting to make sense... I add commands to a queue which is handled by another class on each client tick, the commands i'd add in order would be like press key D, followed by release key D and one line would be executed for each client tick, right?

 

I added this code to a separate class but its coming up with errors, possibly due to a different version?

 

int ticks;

Queue commands;

 

@SubscribeEvent

public void onClientTick(TickEvent.ClientTickEvent event){

if(ticks % 10 && !commands.isEmpty()){  *Line doesn't work*

commands.getFromTop().call; *GET FROM and REMOVE FROM top not recognized*

commands.removeFromTop();

}

++ticks;

 

}

 

What Ernio posted was pseudocode, you need to find the appropriate methods in the

Queue

interface yourself.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

You can't use a

while

loop to check passage of time.  They explicitly do not exit (forcing thread halt) until their conditions are met, in this case, the release of the pressed key.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

You can't use a

while

loop to check passage of time.  They explicitly do not exit (forcing thread halt) until their conditions are met, in this case, the release of the pressed key.

That makes perfect sense, but that's the point in the break; command right? To exit the loop while the condition is still invalid?

Link to comment
Share on other sites

Dude.

Seriously.

All of that code runs in a single tick.  It doesn't actually "wait" (even if real-time it takes it four seconds).

That's why the game appears to freeze.

 

In order for you to perform an operation over time you need to count ticks.

 

Open up TileEntityFurnace and look at the

burnTime

variable.  Look at what it does.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Dude.

Seriously.

All of that code runs in a single tick.  It doesn't actually "wait" (even if real-time it takes it four seconds).

That's why the game appears to freeze.

 

In order for you to perform an operation over time you need to count ticks.

 

Open up TileEntityFurnace and look at the

burnTime

variable.  Look at what it does.

 

burnTime is the amount of ticks it keeps the furnace burning for now it makes more sense, basically I need some sort of pressTime that does the same thing as burn time but for the key press.

 

Can you explain to me what 'counting ticks' actually means, how you do it, and how it will help me to perform the action over time?

 

I can sense I'm getting a little tedious, but I genuinely am grateful for the help just not really understanding how I can do this in my mod quite yet..

Link to comment
Share on other sites

basically I need some sort of pressTime that does the same thing as burn time but for the key press.

 

Bingo.

 

Can you explain to me what 'counting ticks' actually means

 

@EventHandler
public void onTick(TickEvent event) {
    //a tick happened
    //increment counter
    pressTime++;
}

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

basically I need some sort of pressTime that does the same thing as burn time but for the key press.

 

Bingo.

 

Can you explain to me what 'counting ticks' actually means

 

@EventHandler
public void onTick(TickEvent event) {
    //a tick happened
    //increment counter
    pressTime++;
}

 

So maybe something like this could work?:

 

@EventHandler

public void onTick(TickEvent event) {

    //a tick happened

    //increment counter

    pressTime++;

}

 

 

(Psuedocode)

@SubscribeEvent

on key press

if key is harvest key

pressTime = 0

press key w

if pressTime = 10{

    release key w

    pressTime = 0

}

 

Having the above in a while loop*

Link to comment
Share on other sites

Having the above in a while loop*

 

*Defeats the whole purpose.

 

DO NOT USE A LOOP ANYWHERE IN YOUR CODE.  The tick event handler IS the loop.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

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.



×
×
  • Create New...

Important Information

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