ID:1770952
 
BYOND Version:507.1274
Operating System:Windows 7 Home Premium 64-bit
Web Browser:Chrome 40.0.2214.91
Applies to:Webclient
Status: Open

Issue hasn't been assigned a status value.
Descriptive Problem Summary:
When running the webclient without any macros defined, in either a .dms or .dmf, the movement is really jumpy and doesn't compare to how smooth Dream Seeker's is. There is a very annoying, noticeable pause that occurs after pressing a key, which delays the command.

If this bug affects the webclient in its default state, I have to wonder if it could be deep enough that fixing it could resolve other hidden defects somewhere. This is mostly just speculation, but I don't want to judge a bug by how minor it may seem on the outside. Although, this could make a bad first impression of the webclient, and deter some developers from using it, which is never a good thing.

Numbered Steps to Reproduce Problem:
1. Create a new project with no .dms or .dmf files.
2. Make an icon for the mob, so that you can see it move.
3. Add this code to the project:
client
verb
FixMacros()
if(connection == "web")
winset(src, null, {"command=".skin \\"eval('\
fixmacros();\
function fixmacros() \\\\\\{\
var macros = byond.getMacros();\
var fixedmacros = \\\\\\{\\\\\\};\
for(var m in macros)\\\\\\{\
fixedmacros\[m\] = macros\[m\].command;\
\\\\\\};\
byond.userMacros(fixedmacros);\
\\\\\\};')\\"""}
)

4. Compile and host, then connect through the webclient.
5. Move your mob around using the arrow keys and notice how jumpy it is.
6. Click on the FixMacros() verb in the panel, and try moving again. The movement should now be smooth, and much more like it is in Dream Seeker.

Expected Results:
The default macros behave the same in the webclient as they do in Dream Seeker.

Actual Results:
There is a delay before the commands run.

Does the problem occur:
Every time? Or how often?
It happens every time you press a key with a macro.
In other games?
It would happen in any game that uses the default macros.
In other user accounts?
Obviously.
On other computers?
Obviously.

When does the problem NOT occur?
It doesn't occur when you recreate the default macros in a .dms or .dmf file.

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? (Visit the Build Index to download old versions for testing.)
I don't actually know.

Workarounds:
You can either recreate the default macros in a .dms or .dmf file, or you can use the code included above.
In what way are they jumpy? I haven't noticed this at all in testing games with default macros. Does this maybe occur only in high-FPS projects?

It seems to me that any jumpiness in macros would also be due to keyboard event handling, timing, and/or when they execute on the server. Refreshing the macros wouldn't seem likely to impact anything, except if it's some kind of weird issue with timers.

I did notice that the key repeat handler in macro.dart in our code would not be responsive to ticklag changes until after it's created. (The key repeater also doesn't clear itself once no keys are held.) This could be a possible explanation for why your JS code is fixing the issue, although it's kind of weird to me because the repeater shouldn't be created until something happens to trigger a need for it. I'll definitely have to look into this.
Now that you mention it, I had left in the new project template code, so the FPS was 25. I tried it with 10, and while the problem is a bit less noticeable, I can still see it happening quite clearly. At 5 FPS I'm not even sure if I would catch the problem if I wasn't looking for it, but it looks kind of jumpy anyway when it's that low. I believe that the problem becoming less noticeable at lower FPS settings is only an illusion.

With that said, you should test this at an FPS of 25+, because it should be easier to see the issue in action.

I think I may need to clarify some things.

What I said about the .dms or .dmf file wasn't worded very well. What I mean is that just including a .dms or .dmf, with the same macros defined in it, is enough to resolve the issue. This means the macros are being created using a different, internal method, or at least that's how it seems.

I should be more specific about how the macros are behaving. There's not exactly a "jumpiness" to them. I would describe the behavior as almost exactly the same as how keys start repeating when entering text somewhere, such as an input control. So when you press and hold a key, a single command goes through right away, followed by a delay, very much like the one that occurs in text editors, then it starts repeating rapidly, as it should. It seems like the wrong event is being used in JavaScript, such as the onkeypress event, instead of the individual onkeydown and onkeyup events.

I hope this helps narrow down the problem.
It sounds like the "oldstyle" macros--that rely on the browser key repeat--are showing iffy behavior. This distinction was added to the webclient and DS both, because it turned out DS's old default macros used a completely different method of invocation, and they had never been fully reconciled.

This is probably better to do with the timer, without relying on the browser to send the key repeats.
What is this "oldstyle" you are talking about and why is it still around? I would think that any older style of macro could be converted or simulated using the new style. What is the new one missing?

Relying on the browser for key repeats sounds like a really bad idea, and I would almost expect to see the current behavior happening because of it.
In response to Multiverse7
Multiverse7 wrote:
What is this "oldstyle" you are talking about and why is it still around? I would think that any older style of macro could be converted or simulated using the new style. What is the new one missing?

New-style repeats happen almost right away. That's different from the way key repeats are handled naturally on your system, where there's a short delay before the repeat events fire. Basically it was discovered early in 507, after I tried to reconcile the two macro schemes (the really old one and the new), that some games behaved really badly from the change. So the oldstyle repeats were done as a compromise.

The behavior you described, however, is entirely consistent with what default oldstyle macros should be doing. And it turns out I already did move them to a timer, so the first repeat happens after 1/3 s and then afterward is based on tick_lag. I can definitely confirm furthermore that only keydown/up events are used in the JS and Dart code, not keypress events.

So it sounds to me as if you're observing the correct behavior for when macros are left at their defaults. DS should be behaving exactly the same way for those same projects. In old games, the delay before repeat was expected.
In response to Lummox JR
Well if that's the case, then this turns the whole bug report upside down!

I'm not sure whether to like this or hate it, but either way, the behavior of Dream Seeker and the webclient should be consistent, and they are not. As strange as it seems, the webclient is being more backwards compatible than Dream Seeker in this case, because Dream Seeker isn't using the old macro style when it "should".

It seems as though fixing this bug requires deciding on what the correct behavior should be, assuming that it isn't already set in stone.

It could be argued that not only is there an inconsistency between Dream Seeker and the webclient, but also between defining your own macros and not. I think the behavior of this old macro style would seem quite odd to new developers who suddenly encounter it. It will leave them wondering what changed, especially since I don't think it's documented anywhere.

I think what is needed is a better compromise that balances consistency with backwards compatibility.

For example, the server could check the compiler version of the .dmb, and if it's below a certain number (that coincides with the introduction of the new macro style), then it could revert to the old macro style. Of course, you would want to phase out the old style gracefully, so the compiler could check for old .dmbs when compiling over them, and if it finds one, then it outputs some kind of warning message about the use of the old macro style. I have no idea how possible or feasible any of this even is. I don't know if you can even reasonably pick a cutoff version to catch the games that used the old macro style. I'm guessing the "line" is probably blurry, unfortunately.

It would be nice if the macro style used was somehow recorded in the .rsc or .dmb, so that the macro behavior could be conditionally set automatically, but that sounds too easy, and this problem probably wouldn't exist if that were the case. I would hope that I'm wrong about this.

This is kind of getting to be a request, but it's still very much relevant to this bug.
In response to Multiverse7
Multiverse7 wrote:
Well if that's the case, then this turns the whole bug report upside down!

I'm not sure whether to like this or hate it, but either way, the behavior of Dream Seeker and the webclient should be consistent, and they are not. As strange as it seems, the webclient is being more backwards compatible than Dream Seeker in this case, because Dream Seeker isn't using the old macro style when it "should".

Here I don't follow you. In the projects where the original default macros are used, I have not observed different behaviors between the two. DS should be doing the same thing: delay, then regular repeat. If there's a case where this isn't so, then I definitely want to deal with it, because you're right: they should be consistent.

I think what is needed is a better compromise that balances consistency with backwards compatibility.

For example, the server could check the compiler version of the .dmb, and if it's below a certain number (that coincides with the introduction of the new macro style), then it could revert to the old macro style.

It is in fact doing this, or is supposed to be.
In response to Lummox JR
Lummox JR wrote:
In the projects where the original default macros are used, I have not observed different behaviors between the two. DS should be doing the same thing: delay, then regular repeat. If there's a case where this isn't so, then I definitely want to deal with it, because you're right: they should be consistent.

In the very same test case I outlined for the webclient, where no .dmf or .dms file is included, the macros fire with no delay in Dream Seeker. I am only seeing the delay in the webclient.

It is in fact doing this, or is supposed to be.

That doesn't make sense. If it was doing as I said, and checking the version of the compiler that built the .dmb, then I should not expect to see the old style macro behavior when running a project that was compiled with the very latest version of the compiler. This contradicts what you were saying earlier, when you mentioned that I should be seeing a delay for such projects.

What I was suggesting was for newly built default projects to use macros without delays, while older .dmbs could continue to use the old macro style.