Knuckle Cracker

Creeper World 3 => The Coder's Corner => Topic started by: knucracker on January 31, 2014, 11:31:37 AM

Title: Operations while Paused
Post by: knucracker on January 31, 2014, 11:31:37 AM
Well...  Hmmm.
After seeing things like buttons that only operate while the game is unpaused and such, maybe I should expose paused operations.

So I have added these two commands to CRPL
OperateWhilePaused(bool)
bool IsPaused

So you could do this irritating thing and get a rating of 1 on your map if you do :)

if (IsPaused) UnPauseGame endif

:Awake
OperateWhilePaused(true)


The OperateWhilePaused function toggles a state on the core that makes it continue execution even while the game is paused.  In other words, the script will keep on executing as if the game isn't paused.  So this could be used for something irritating like immediately unpausing the game.  But it could in theory also be used for good.  You could implement a button that pops up a menu and closes the menu and it will work while the game is paused.  That sort of thing.

Now, there are probably many edge cases and things that might not work properly.  So if I decide to leave this in for tonight's build I will ask for a brief period of testing before anyone publishes a map that uses it.  If things explode and it turns into a nightmare of issues, I will remove the commands.
Title: Operations while Paused
Post by: Grayzzur on January 31, 2014, 11:50:18 AM
That's gonna be a can of worms. You may wind up having to disallow a bunch of CRPL commands while paused.. anything that modifies the state of the game (unit locations, terrain elevation, creeper amounts, etc.).

Instead of an IsPaused conditional, I wonder if it would be safer to have a paused function (:Paused), and only run that function while paused instead of the entire script. Such an approach may make it easier to disallow commands that shouldn't be used during pause, you could possibly weed them out when compiling the script. I know, more work, I guess we could enforce that ourselves, but I worry about the abuse.

However, it makes it possible to make custom player units much friendlier. Target while paused, etc. I can see a bunch of good stuff that could come from it. It could solve several UI issues with the CW1 style Drones I'm playing with.

Without such restrictions, you could do some evil stuff. Emitters that get stronger every time the player pauses. Reduces the ammo of player units every time the player clicks on them while paused.
Title: Operations while Paused
Post by: knucracker on January 31, 2014, 12:13:17 PM
I tried that for starters, a ":Paused" function basically.
But things like timers, the delay call, queued unit movements....  yeah.  It would be difficult to prevent them from progressing (or in the case of Delay, working).

But you are right... you can do some evil things.  That said you can already sort of do many of these evil things, you just have to be sneaky about it.  For instance, you can compare GetGameTimeFrames with ElapsedTime in CRPL... and from that you can tell when the game was paused.  ElapsedTime always goes up but GetGameTimeFrames only goes up while the game is not paused. I actually use this sort of thing in my Alpha:Virgilw:Brain map.  I want the actual clock time it takes to solve the puzzle, pauses and all.

Before this new feature you couldn't do things while the game was paused, but you could do them all immediately after the game was unpaused.
Title: Re: Operations while Paused
Post by: Clean0nion on January 31, 2014, 12:46:01 PM
If we're now able to control pausing, I think we should be able to control - or at least detect - time speed.
So for example, a map might give you bonus points if you paused infrequently and ran the game at x4 all the way through, whereas someone who runs the game slowly and pauses often would receive fewer points.
Title: Re: Operations while Paused
Post by: eduran on January 31, 2014, 12:55:00 PM
Awesome change, that makes working with UI elements a lot easier.

About the abuse cases: If someone wants to make a annoying map that is already more than possible (flooding areas with creeper when a savegame is loaded.... :-[). I don't think that disabling commands is necessary, unless they are buggy when used during pause.
Title: Re: Operations while Paused
Post by: pawel345 on January 31, 2014, 01:03:23 PM
I agree :D Can't wait till somebody does a player unit GUI functions, that would make CPRL allies much more probable. :D
Title: Re: Operations while Paused
Post by: Clean0nion on January 31, 2014, 01:11:34 PM
Quote from: pawel345 on January 31, 2014, 01:03:23 PM
I agree :D Can't wait till somebody does a player unit GUI functions, that would make CPRL allies much more probable. :D
Or even just those mouseover things that show an enemy cannon's range.
Title: Re: Operations while Paused
Post by: Grayzzur on January 31, 2014, 04:51:30 PM
@V: You realize most of what I'll be doing with the pause processing will be negated the moment you decide to actually release a CRPL Core type designed to be a custom player unit. :)
Title: Re: Operations while Paused
Post by: Clean0nion on January 31, 2014, 05:05:35 PM
I just realised how essential this whole thing is to my current project(s).
Title: Re: Operations while Paused
Post by: Grayzzur on January 31, 2014, 05:16:03 PM
Virgil, Something's not right. I downloaded/installed 1.71, pasted the :Awake function to the end of a script as you have it, and I get:

--ERRORS FOLLOW--
CW1_Drone.crpl: Line: 391: Invalid Token: OperateWhilePaused. Perhaps you meant ->OperateWhilePaused or <-OperateWhilePaused or "OperateWhilePaused" or @OperateWhilePaused
Title: Re: Operations while Paused
Post by: asmussen on January 31, 2014, 05:22:00 PM
Quote from: Grayzzur on January 31, 2014, 05:16:03 PM
Virgil, Something's not right. I downloaded/installed 1.71, pasted the :Awake function to the end of a script as you have it, and I get:

--ERRORS FOLLOW--
CW1_Drone.crpl: Line: 391: Invalid Token: OperateWhilePaused. Perhaps you meant ->OperateWhilePaused or <-OperateWhilePaused or "OperateWhilePaused" or @OperateWhilePaused

1.71 was released yesterday, and Virgil's post about the new functions is from today, so my guess would be that he meant that he added them to the source code, but hasn't released a beta build enabling those features yet. Maybe 1.72.
Title: Re: Operations while Paused
Post by: knucracker on January 31, 2014, 05:47:13 PM
Yeah this new stuff will be in tonight's build. That should be ready in a few hours.
Title: Re: Operations while Paused
Post by: Clean0nion on January 31, 2014, 05:49:35 PM
Quote from: virgilw on January 31, 2014, 05:47:13 PM
Yeah this new stuff will be in tonight's build. That should be ready in a few hours.
Excellent! Thank you so much Virgil.
Title: Re: Operations while Paused
Post by: Grayzzur on January 31, 2014, 06:32:26 PM
My bad. I read that wrong. 1.71 does have new functions... just not these new functions. I shall clean my glasses. And wait. And twiddle my thumbs.
Title: Re: Operations while Paused
Post by: Clean0nion on January 31, 2014, 07:25:58 PM
This probably isn't intentional therefore a new feature request:
Can you change OperatesWhilePaused to be something more along the lines of it operates during pauses, except when in editmode?
It doesn't effect me but might do to others. All it does to me is make a core a tiny bit harder to select.
Title: Re: Operations while Paused
Post by: Flabort on January 31, 2014, 07:57:19 PM
Detect when you pause or unpause:
<-state not IsPaused and if
1 ->state
@OnPause
endif
<-state IsPaused not and if
0 ->state
@OnUnpause
endif

:Awake
True OperateWhilePaused
IsPaused if
1 ->state
else
0 ->state
endif

:OnPause
#Stuff

:OnUnpause
#Stuff
Title: Re: Operations while Paused
Post by: knucracker on January 31, 2014, 08:08:01 PM
Quote from: Clean0nion on January 31, 2014, 07:25:58 PM
This probably isn't intentional therefore a new feature request:
Can you change OperatesWhilePaused to be something more along the lines of it operates during pauses, except when in editmode?
It doesn't effect me but might do to others. All it does to me is make a core a tiny bit harder to select.

I can probably do that.  In the mean time you can use IsEditMode as a workaround (most likely).  "if (IsEditMode) return" at the top of your script might do the trick.
Title: Re: Operations while Paused
Post by: Grayzzur on February 01, 2014, 12:21:22 PM
I can track mouse position while paused, but it seemed like mouse clicks and key presses aren't registering. On closer inspection, it's the *Down commands that aren't working. GetKeyDown and GetMouseButtonDown don't register while paused. GetKey and GetMouseButton do seem to work, but for my purposes, it will require some extra code to detect the initial click and ignore the rest.
Title: Re: Operations while Paused
Post by: knucracker on February 01, 2014, 01:52:11 PM
Very subtle bug on my part.  It had to do with the way "speed frames" worked.  Speed frames are the extra evaluations of the game loop that happen per game frame when you are running at more than 1x speed.  I had code in place to make sure that thing like GetMouseButtonDown only return true during one game update even when running at 4x.  There was a little bug where paused evaluations always thought they were in a speed frame (except right when a game is loaded and has never been unpaused).  But, it should be all better now for the next build.
Title: Re: Operations while Paused
Post by: Grayzzur on February 01, 2014, 02:14:15 PM
Thanks! My workaround is... messy.
Title: Re: Operations while Paused
Post by: Grayzzur on February 02, 2014, 11:58:31 AM
I noticed that this is fixed in 1.73, even though you didn't mention it in the change log.

Thanks.
Title: Re: Operations while Paused
Post by: knucracker on February 02, 2014, 02:43:47 PM
I must have forgotten to note it... but yes it should be working now.
Title: Re: Operations while Paused
Post by: Grayzzur on February 10, 2014, 10:47:46 AM
"Issue" report with OperateWhilePaused + QueueMove.

I call it a bug, but some other folks I was discussing it with believe it's fine, so I'll address their viewpoint as best I can.

The issue is highlighted in the attached sample map. Both cores, when their move queue is empty, delay 30 then queue up 4 moves. When they start moving, if you pause the map, you'll see one core pauses, and the other core (with OperateWhilePaused set) continues to move until it's emptied out it's move queue before stopping.

I do not believe this is intentional. The opposing viewpoint I mention suggest that it is. I can see the benefit of allowing queue move to continue while paused if that behavior is desired. My belief is that a core should not do anything while paused unless the map author wants it to.

Map example: The turrets in Pass the Map 2 have a range finder graphic when you hover over them. It would be nice to show that graphic on hover while paused, but adding pause operation to that code causes the turrets to continue on to the next cell when you pause the game. This is why I did not add that feature to the published map.

I don't think a map author should be forced to handle all movement by themselves and avoid QueueMove to avoid that situation. Perhaps an AllowQueuedMovesWhilePaused flag that defaults to FALSE and has no effect if OperateWhilePaused is FALSE?

EDIT: Forgot to attached the sample map. Here it is.
Title: Re: Operations while Paused
Post by: eduran on February 10, 2014, 11:22:33 AM
Quote from: Grayzzur on February 10, 2014, 10:47:46 AM
Map example: The turrets in Pass the Map 2 have a range finder graphic when you hover over them. It would be nice to show that graphic on hover while paused, but adding pause operation to that code causes the turrets to continue on to the next cell when you pause the game. This is why I did not add that feature to the published map.
Even if moves didn't execute, wouldn't the turret just keep firing from its current position?

The way I see it, you have to split the code into two scripts: one that runs while paused (UI stuff like the range finder), and another one that does not run while paused (movement, targeting stuff, shooting). You can still add both scripts to a single core.
Title: Re: Operations while Paused
Post by: Grayzzur on February 10, 2014, 11:28:08 AM
No, you can put an "IsPaused if return endif" to stop execution of things you don't want to run while paused. I can make it do ONLY the rangefinder piece and nothing else -- but I currently have no way to stop it from continuing QueuedMoves without ABORT/CANCEL -- and then there would be a bunch of extra code to remember where I was going and re-queue the moves on Un-pause.
Title: Re: Operations while Paused
Post by: knucracker on February 10, 2014, 11:35:10 AM
"Intentional or not"... is there a third option?  It feels like there needs to be a third option when I don't know or remember :)

Before I even look at the code I'm gonna say bug.  Unit movement is processed in the game update function for a crpl tower (as are some other things), so that is probably getting processed.  But I do have a vague memory of attempting to make that not be the case.

I'll add this to my notepad and take a look later today along with a couple other things.
Title: Re: Operations while Paused
Post by: eduran on February 10, 2014, 11:58:41 AM
Quote from: Grayzzur on February 10, 2014, 11:28:08 AM
No, you can put an "IsPaused if return endif" to stop execution of things you don't want to run while paused.

What about timers? If you pause the game right after the turret fired, will it fire again immediately after you unpause?

Quote from: Grayzzur on February 10, 2014, 11:28:08 AM
I can make it do ONLY the rangefinder piece and nothing else

You could move that part to a new script and have only the range finder script run while paused. Attach both scripts to the same core and you have a turret that only operates while the game is unpaused, but with a range finder that works during pause.
Title: Re: Operations while Paused
Post by: Grayzzur on February 10, 2014, 12:21:33 PM
Hmm. Delays and timers seem to process while paused as well.

That's actually not a bad idea (two scripts). There would be some communication between the scripts for variables and such. Some things wouldn't be accessible to the pause script unless the main script makes them accessible. Not too big a hurdle.

Hey V, why don't you leave this one alone for now? We'll just document the current behavior and experiment with using multiple scripts for these types of units.
Title: Re: Operations while Paused
Post by: Grayzzur on February 10, 2014, 12:42:16 PM
The more I play with it, the more I think just having two scripts is the elegant solution here. I can control whether or not queued moves continue on in paused mode by which script I queue them in.
Title: Re: Operations while Paused
Post by: knucracker on February 10, 2014, 02:53:30 PM
Yeah.... I just looked at this.  I even left myself a little note about it in the comments.
I could fix it, but it would be a little tricky based on how things are structured.  It affects timers, delays, movement, and maybe another couple things.  So my comment to myself was that I was skipping the risky work and would just recommend authors to use different cores (scripts).