increpare / PuzzleScript

Open Source HTML5 Puzzle Game Engine
MIT License
891 stars 157 forks source link

move realtime_interval from beta to proper #120

Closed increpare closed 10 years ago

increpare commented 10 years ago

I'd like to make this a big release, might as well slot in this feature as well, at last. Lots of thinking to do.

The way I see it there are three possibilities

realtime_loose [frame length] that's the current one - constant realtime tick, and players move however they want - as fast as they want by repeatedly pressing the key. This is, to my knowledge, how zzt worked - with the exception that in zzt key repeats were probably synced up to the realtime tick. [i don't know what I mean by that last bit - I should just go check out how works]

realtime_throttled [frame length] you can't move faster than key_repeat_interval interval - if you press a key you move instantly, but if you jam on a key multiple times, all bets are off. not sure if you'd want repeat_interval to be different

realtime_rigid [frame length] you don't automatically move when you press a key, only when the realtime ticks does it check to see what you've held down.

other possible things to consider - right now (though it's not live) when a rule is doing 'again', all realtime stuff stops until it's done. i think this is just the simple solution to quite a complicated problem.

list of games that use realtime_interval: chaos wizard - http://ragzouken.itch.io/chaos-wizard

spooky pumpkin game - http://www.puzzlescript.net/play.html?p=7242443

What worries me about a lot of these decisions is that I'm working blind - I don't have a clear giant matrix of games that I think people are going to make, so it could be that some of these modes are going to be useless, which would suck - ideally I want every feature in puzzlescript to be good. Ideally for each realtime mode, I want three games that could be made with it.

If you can think of any feedback for the above, or have made any games using the current realatime_interval stuff, or might make such games in future, let me know.

increpare commented 10 years ago

Feedback from someone (quoting != agreement - just filing it here for easy reference)

https://groups.google.com/forum/#!searchin/puzzlescript/realtime_interval/puzzlescript/fR4OisAknOA/dFYw4oCge60J

"This realtime_interval mechanic has been very useful, it works well for puzzles where you want to be able to keep moving the player while things are happening. In fact, am having a lot of fun designing a puzzle game based on Boulder Dash. It is not meant to be primarily an action game, and there are some good puzzles I can make work very well with this system. However, it has a quirk which I really hope can be fixed. I understand that everything has to move a step with the player, so that all rules be run. However, It makes things move faster than normal when you move the player as well as having the interval tick. Not only does it make animations speed up strangely, but it can negatively affect gameplay.

For example, let's say you tried to hold "right" with a monster following the player, to lure the monster into a trap. They both move one tile at a time. At every realtime_interval tick, the monster moves 1 extra step. How quickly this monster will catch up relates directly to how long the realtime_interval is compared to key_repeat_interval.

My suggestion is as follows. In order to make animations look smooth, reprogram realtime_interval to move the player once when the next interval comes if a key has been pressed previous, rather than moving an extra step when the player moves. This would mean there might be a slight lag between when the key is pressed and player movements. However, this lag would likely only be noticeable with a long interval. This behavior would cause everything to animate at a constant speed. If the user holds down a key, the player should step once every realtime tick.

I hope you will consider my proposal to improve this fine game engine. I am writing with this style because I am taking a college Technical Writing class and it seemed like a good a chance as any to practice writing. I also hope this can be released as an official feature soon, so that I can make tons of levels and release a game with it.

Ragzouken commented 10 years ago

I think the games I've seen use EITHER real time gameplay OR animations, so it might not be an issue for that; just crank up the rigid frame length if you're using animations? I'm thinking games that "need" real time are going to be quite complex and probably won't have objects to spare for animation frames anyway? ("again" didn't cut it in chaos wizard because i had the prisms which could make indefinite spells)

On the other hand there is the [stationary Player] [actual rule] work around which seems to be Good Enough if you don't mind the player walking between frames (in chaos wizard it doesn't really matter how fast you can walk except for the silly levels at the end, it's just that real time is necessary for the prisms to work); though I seem to have a lot of trouble getting it right and it makes my code harder to maintain.

I also made this (http://www.puzzlescript.net/play.html?p=7176630) for the 0h game jam (I improved upon it but sadly lost the source :( ). It would be ideal in this game if the input were delayed until the next turn (giving the player a small interval to choose the right move before it's executed), but I think this kind of gameplay is really pushing the edge of what is it appropriate for PuzzleScript :p

My inclination would be for realtime_rigid though it is evidently possible to create the games I have without it. It avoids having to use the [stationary Player] [ rule ] work around, which makes the code easier to read, and I've always had trouble getting that quite right anyway.

increpare commented 10 years ago

"I think this kind of gameplay is really pushing the edge of what is it appropriate for PuzzleScript :p" Agreed - whatever features this game might require to achieve a state of semi-playability are ones this game would serve as a reason to not implement.

Animations are de facto unimportant in puzzlescript - as much as the candle anims are nice, I have no trouble unsupporting them.

So, for realtime_rigid - what happens if I want a high framerate and low player speed? Should I cap the player's movement speed to key_repeat_interval in this mode? what sort of game would want high framerate and low player speed anyway? I don't know.

There's a variation on realtime rigid whereby pressing keys makes ticks go faster - that way the game will feel more responsive, however you can speed it up by mashing keys (with no effect on gameplay).

Ragzouken commented 10 years ago

I suppose by low player speed we are talking other objects making multiple moves between player moves? Perhaps use of token objects and "again" is enough to support that?

Perhaps you could support the whole range of that variation with something like: realtime_rigid min max (frame lengths) - there must be at least min time between turns but after max the turn will advance; if they are equal it acts as the original realtime_rigid idea. If you didn't want to do that, then perhaps it's best to settle on the side of responsiveness.

Just to clear this up in my head: the difference between realtime_interval and it is and realtime_rigid with responsive ticks is that a player move in that latter resets the time until the next tick, whereas realtime_interval just ticks periodically regardless of manual player turns?

increpare commented 10 years ago

"the difference between realtime_interval and it is and realtime_rigid with responsive ticks is that a player move in that latter resets the time until the next tick, whereas realtime_interval just ticks periodically regardless of manual player turns?"

realtime_rigid has a fixed clock - it ticks every second, and on that tick it checks what's held down. If you press a key in between frames, nothing happens (but maybe it should. I don't know :S)

realtime_interval : the realtime tick has a completely separate (Except for again, which interrupts it) existence from the input stuff. Input triggers in response to keypresses immediately, realtime triggers a move ever X seconds.

increpare commented 10 years ago

"[in realtime rigid] a player move in that latter resets the time until the next tick" actually no, that's not what I had in mind. That's what I meant by "There's a variation on realtime rigid whereby pressing keys makes ticks go faster - that way the game will feel more responsive, however you can speed it up by mashing keys (with no effect on gameplay)." but reading it again it isn't very clear. For this variant I mean what I think you mean - you have a realtime ticking clock - if you press a key, it triggers the clock immediately, and resets the realtime clock, sure, maybe. (I'm a bit confused).

Maybe I need to draw some pictures...

mechturk commented 10 years ago

When I was playing around with making use of the analytics at the start of Feb, I kept a local cache of the puzzlescript gists that I looked at. Of those gists, I've put together a list of those that use realtime_interval. Hopefully might help you get a better idea of what people are currently using it for:

[stephen: I removed the list, but am working through it now. I think some people have wip games on it that they wouldn't feel comfortable being listed publicly. best to be safe]

mechturk commented 10 years ago

Also not really sure what you had in mind for intended uses of realtime, but I prototyped a puzzlescript shmup a little while back? But I think it might be along the same lines as Mark's example in that it's also pushing the boundaries for what is appropriately done in puzzlescript.

Touhouban I think works really well in some of the later levels using [stationary player] and bullets moving in realtime. It lets you mash keys to get through tricky situations, but Aaron has set the interval low enough that mashing correctly is quite hard? I'm not quite sure how this fits into the loose/throttled/rigid framework, but whatever it's doing seems pretty nice IMO.

increpare commented 10 years ago

haha, thanks so much Dennis - this is lots of data to work with :)

Draknek commented 10 years ago

So if picking just one system, I think the current implementation is best.

The reason being: I think you can, with varying levels of hassle, probably twist it to do anything else that might be wanted.

Touhouban-style games and games using realtime just for animation can use the [ stationary Player ] trick.

If wanting the player to only move at the same speed as the moving objects (realtime_rigid), you can do something like:

[ left Player ] -> [ GoL Player ]
[ right Player ] -> [ GoR Player ]
[ up Player ] -> [ GoU Player ]
[ down Player ] -> [ GoD Player ]

[ stationary GoL Player ] -> [ left Player ]
[ stationary GoR Player ] -> [ right Player ]
[ stationary GoU Player ] -> [ up Player ]
[ stationary GoD Player ] -> [ down Player ]

What this can't do is realtime_throttled with key repeat interval != realtime interval. But I don't think anybody so far has asked for this?

Now maybe we don't want those workarounds to be necessary. In that case we're talking about adding settings to control which realtime behaviour is desired. Which settings? Not sure, but it's a markedly different question compared to "what is the single definitive version of realtime behaviour we should be allowing?"

mechturk commented 10 years ago

Before you thank me, I must apolgise in advance for any WIP/non games you might find in there. I thought of filtering through them, but it thought it might be useful so you have an idea of what people had tried to do with it. Also, there are quite a few which from memory just use realtime for animation purposes. The above is pretty much just a grep with duplicates removed. Again, super sorry... :(

rmmh commented 10 years ago

What if keyrepeat_interval on realtime games set the ratio of player movements? Keyrepeat .2 realtime .4 means up to two player movements per realtime tick. This would let people set the ratio between player speed and monster speed. Detecting difference between a player tick and a realtime tick might require another phase, though...

Another thing to consider while adjusting timing code is making the update loop less jittery. Currently framerate is dependent on both interval times and update times, while it would be better if it were locked to the interval times.

Draknek commented 10 years ago

Possible settings:

I think with both of the above you get all three of the proposed behaviours in the first post.

Possible added syntax:

increpare commented 10 years ago

Dennis, I edited out the list. I think one or two games on it are WIP and think it possible people wouldn't like them being posted publicly. However, I'm still finding it enormously useful - getting a lot of very very useful information from it.

mechturk commented 10 years ago

Yes, I think that's probably for the best. Probably should have just shot it to you via email, to be honest. :blush:

increpare commented 10 years ago

So, I've gone through dennis's list, assigned them to the real-time function where I think they'd work west, and have come up with

realtime_loose : 11 realtime_throttled : 2 rigid : 0 semirigid : 3 (rigid, but where it responds immediately when you press a button down and resets the automatic timer to go in sync with the atmosphere)

Obviously some of this is because games were made to fit to the animation system I had in. The main thing I don't like about the semirigid approach is that you loose any sense of rhythm.

Anyway, all of the games would work OK with realtime_interval as currently it's in, and I'll think of adding in an input_throttle command, that will not allow you to press keys any more quickly than is allowed by key_repeat_interval - that would cover @Ragzouken's game ok.

increpare commented 10 years ago

https://github.com/increpare/PuzzleScript/commit/37a221b2468d06ee20b266bc03e9cab336fa6228

jjmajava commented 10 years ago

Here are my two (and a half) games using realtime_interval.

I think they're fine as it is, but realtime_rigid would be how someone playing any of them would expect them to work. That's also how I though realtime would work starting the first game.

Hand-E-Food commented 10 years ago

Maybe rule keywords rather than interval models is more appropriate.

So currently, realtime_loose doesn't include any of these keywords. In the example, the fire animates when the player moves or the interval triggers.

=====
RULES
=====
(Push crates)
[> Player | Crate ] -> [ > Player | > Crate ]
(Animate fire)
[ Fire ] -> [ action Fire ]
[ action Fire1 ] -> [ Fire2 ]
[ action Fire2 ] -> [ Fire3 ]
[ action Fire1 ] -> [ Fire1 ]

realtime_rigid is implemented with the first rule being input delay. This example only allows the player to act on the interval based off of the last keypress.

=====
RULES
=====
input delay
(Push crates)
[> Player | Crate ] -> [ > Player | > Crate ]
(Animate fire)
[ Fire ] -> [ action Fire ]
[ action Fire1 ] -> [ Fire2 ]
[ action Fire2 ] -> [ Fire3 ]
[ action Fire1 ] -> [ Fire1 ]

Another case is where the player can move quickly and animations (or enemies) move at a set pace. This example only activates the fire animation when the interval trigger occurs.

=====
RULES
=====
(Push crates)
[> Player | Crate ] -> [ > Player | > Crate ]
(Animate fire)
interval [ Fire ] -> [ action Fire ]
[ action Fire1 ] -> [ Fire2 ]
[ action Fire2 ] -> [ Fire3 ]
[ action Fire1 ] -> [ Fire1 ]

Any I'm sure there's a reason why you'd use input for a rule, but I can't think of a good example right now.

=====
RULES
=====
(Push crates)
input [ > Player | Crate ] -> [ > Player | > Crate ]
(Animate fire)
interval [ Fire ] -> [ action Fire ]
[ action Fire1 ] -> [ Fire2 ]
[ action Fire2 ] -> [ Fire3 ]
[ action Fire1 ] -> [ Fire1 ]

The big issue is when the rules are presented in an odd order. What should happen when input delay is specified after an input is processed? Should the rule processing pause until the interval triggers? Should the rule processing restart?

=====
RULES
=====
(Push crates)
[ > Player | Crate ] -> [ > Player | Crate ]
input delay
(Animate fire)
interval [ Fire ] -> [ action Fire ]
[ action Fire1 ] -> [ Fire2 ]
[ action Fire2 ] -> [ Fire3 ]
[ action Fire1 ] -> [ Fire1 ]
octoConnors commented 10 years ago

https://groups.google.com/forum/#!topic/puzzlescript/oKOhFiTaiOM This uses loose but doesn't step anything else when the player moves. I really liked it. I think it would benefit from using "throttled".

octoConnors commented 10 years ago

example for loose: https://groups.google.com/forum/#!topic/puzzlescript/3FiyGHWwJWs

increpare commented 10 years ago

Thanks for the feedback. This issue is closed now - I went ahead and left in realtime_interval as is, with an option to throttle player movement.

On Wed, Apr 16, 2014 at 1:44 AM, Connorses notifications@github.com wrote:

example for loose: https://groups.google.com/forum/#!topic/puzzlescript/3FiyGHWwJWs

— Reply to this email directly or view it on GitHubhttps://github.com/increpare/PuzzleScript/issues/120#issuecomment-40551671 .

octoConnors commented 10 years ago

aww but I liked the idea of rigid >u<

Draknek commented 10 years ago

@octoConnors See above for my suggested way of doing that: https://github.com/increpare/PuzzleScript/issues/120#issuecomment-40368102