Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ General ➜ Possible problem with timers in MUSHclient?

Possible problem with timers in MUSHclient?

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1  2  3 4  

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #30 on Fri 03 Dec 2010 04:23 AM (UTC)
Message
Nick Gammon said:
For another thing, the rooms down the bottom overwrite the area name. Some minor tweaking would be needed before this amended version went live.

Which is another excellent reason to use layers to separate the content. Draw the room graph to one image, and the overlays (room name, options button, golden circles, etc.) to another. When you update the visible window, merge the layers together.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Fiendish   USA  (2,551 posts)  Bio   Global Moderator
Date Reply #31 on Fri 03 Dec 2010 04:48 PM (UTC)

Amended on Fri 03 Dec 2010 04:49 PM (UTC) by Fiendish

Message
Thanks for the update, Nick. :)

David Haley said:
I think it's pretty clear that MUSHclient's rendering etc. are not responsible for the slowness. It doesn't take a lot of processing in plugins that interrupt the GUI drawing for a program to appear very slow and unresponsive.
What's the difference between being slow and unresponsive and appearing to be slow and unresponsive?

https://github.com/fiendish/aardwolfclientpackage
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #32 on Fri 03 Dec 2010 08:48 PM (UTC)
Message
It's the difference between actually running inefficient code, perhaps in GUI rendering, versus the bad practice of running code in the GUI thread thereby preventing the GUI from updating frequently enough. If you render the GUI 5 times per second it will feel less responsive than if you render it 30 times per second. This is different from rendering the GUI 5 times per second because the rendering operation is actually expensive. This is why it is important to understand if perceived slowness is due to actual rendering cost, due to the bad practice of running unrelated code in the GUI thread, or due to something else.

In other words, the appearance of slowness can be due to actual slowness (slow code) or simply not rendering the graphics often enough (bad practice). These are very different things.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Nick Gammon   Australia  (23,166 posts)  Bio   Forum Administrator
Date Reply #33 on Sat 04 Dec 2010 01:55 AM (UTC)

Amended on Sat 04 Dec 2010 03:04 AM (UTC) by Nick Gammon

Message
Potential problems with mapping during speedwalking are that:


  • You compute a large map (hundreds of rooms in the case of outside areas) that are not even shown, because the window is not redrawn. Hence that is wasted CPU power.

  • You compute a large map which the player can barely see (eg. for 25 frames per second you would be hard pressed to register each map redrawing in any meaningful way)

  • The player isn't interested anyway - they only want to know when they have arrived

  • Blitting the map to the output window takes extra CPU time, on top of the time taken to calculate it in the first place

  • All this CPU time takes available power away from processing keystrokes, MUD output, triggers etc.

  • The processing causes timers to fire more slowly then they otherwise might


My suggested amendment (based on David's idea of coroutines) alleviates that somewhat by breaking the computation up into smaller pieces, which are then abandoned if no longer required.

Another approach would be to simply give a different user experience. For example, knowing they are speedwalking, draw the "big map" instead, with a big yellow line showing the progress from the start to the end point.

When I first did the map in Lua, I was pleasantly surprised that the map seemed very fast and responsive - however that was for "manually walking" around, where you might tap "north", and then review where you were. Or even walking reasonably quickly by using the keyboard. Some MUDs impose a limit (IRE ones do I think) of around 0.5 seconds per room, and if you attempt to walk faster than that the MUD declines to act.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Fiendish   USA  (2,551 posts)  Bio   Global Moderator
Date Reply #34 on Sat 04 Dec 2010 04:15 PM (UTC)

Amended on Sat 04 Dec 2010 04:23 PM (UTC) by Fiendish

Message
Nick, I like the amendment. I'll try it out. In the meantime, though, I did already put in to practice your suggestion of cutting down the search space during speedwalks to 4 rooms. It works pretty well, but the coroutine stuff will give me more free overhead to add in other plugins.

David Haley said:
...If you render the GUI 5 times per second it will feel less responsive than if you render it 30 times per second...

No, it will BE less responsive. In terms of responsiveness, there is no metric OTHER than how it appears. So a program cannot "be fast and responsive" but "appear unresponsive". If it appears unresponsive, it is unresponsive.

https://github.com/fiendish/aardwolfclientpackage
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #35 on Sat 04 Dec 2010 06:53 PM (UTC)
Message
Fiendish, you are taking my posts in a rather disingenuous way and it's becoming somewhat unpleasant. :( I think I made some serious points to address the difference between appearance of slowness and actual slowness, and all I get back is a sound-bite argument that ignores the point. I'm not sure what your goal is. You talk to me of metrics and measurements yet you provide none. Well, I'm glad Nick is doing the right thing.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Nick Gammon   Australia  (23,166 posts)  Bio   Forum Administrator
Date Reply #36 on Sat 04 Dec 2010 08:53 PM (UTC)
Message
Fiendish said:

No, it will BE less responsive. In terms of responsiveness, there is no metric OTHER than how it appears. So a program cannot "be fast and responsive" but "appear unresponsive".


I think you are confused here. From my understanding of English, "responsive" refers to how well the program responds. However "fast" (although not really defined by you here) would indicate to me how quickly it does something.

So for example, by keeping Redraw rather than Repaint the program may update the screen slowly (since that is a low priority event). You might say the screen updating is "not fast" (again I would prefer a measurement, eg. "it only updates ever 2 seconds").

However to be responsive it might quickly respond to keystrokes, menu items, triggers etc. even though you might not see that response.

Now if you throw in a lot of Repaints then after a particular event (such as moving rooms) it may immediately draw the new room. However during the time it does so it may respond less quickly to other events.

In the olden days, when PCs were a lot slower, I did a lot of work in programming things like Macs where you paid a lot of attention to this sort of thing. In fact, you normally would not invalidate a whole screen.

Even today you see web browser designers compromising responsiveness and speed. For example, rather than waiting for everything (eg. every graphic) on a page to arrive from the web server, they start drawing what they can. And then, if you decide to change pages, they may abandon that page entirely and start drawing a new one (effectively similar to the coroutine idea with the mapper).

So what probably happens is that the page starts drawing sooner (thus feeling responsive) but finishes drawing later (due to redrawing parts as image sizes cause things to be relocated), which means the overall time to draw the page is slower. So, more responsive, but slower.

In an earlier thread you wanted me to speed up the drawing of gradients because they were slow. Well, gradients will tend to be slow, because they involve a lot of calculations. You could simply not use them. But you didn't want to do that.

Your design decisions about how the end-product looks are going to impact its speed.

Personally I would be designing so you had speed to spare - not everyone will have a PC as fast as yours.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Fiendish   USA  (2,551 posts)  Bio   Global Moderator
Date Reply #37 on Sat 04 Dec 2010 11:36 PM (UTC)
Message
First of all, this has all gotten very academic. None of this is likely going to get us very far. But I do find it interesting so perhaps let's press on. :)

David Haley said:

Fiendish, you are taking my posts in a rather disingenuous way and it's becoming somewhat unpleasant. :(
I don't know. Maybe both of us should start over. I felt you were being hostile. I apologize.

Nick Gammon said:
I think you are confused here. From my understanding of English, "responsive" refers to how well the program responds. However "fast" (although not really defined by you here) would indicate to me how quickly it does something.
No, I think we're just not talking about the same thing. Let's back up a bit and try to get on the same page. "Responsive" as I'm using it is short for "apparently responsive", as in if something happens outside of the window where I care then I can't call it responsive, because to me it's as if it didn't respond. It's not good enough to handle input at some point in the future. If I say "Hi Grandma" to my grandmother and she does nothing, and maybe I say "Hi Grandma" again, and she does nothing again, it doesn't do me any good if after I leave she perks up and says "Hi Grandson. Hi Grandson." That wouldn't really be responsive, because the response doesn't come inside of the window of immediacy (the point by which the user expects to see a response). I'm already out the door. To me it's as if she never responded. So if you want to say that that's just "slow", fine. I'll change my words around. Whatever word you want to use for that phenomenon is fine. :)

Quote:
However to be responsive it might quickly respond to keystrokes, menu items, triggers etc. even though you might not see that response.
That's a matter of perspective. From my grandmother's perspective, there was a response. From my perspective, there wasn't. I'm not ok with measuring from a perspective other than the user's window of immediacy.

Quote:
Now if you throw in a lot of Repaints then after a particular event (such as moving rooms) it may immediately draw the new room. However during the time it does so it may respond less quickly to other events.
Which is why I now buffer repaints.

Quote:
In fact, you normally would not invalidate a whole screen.
Actually, I've been wondering about this. Is there a way in MFC to only repaint part of the screen?

Quote:
In an earlier thread you wanted me to speed up the drawing of gradients because they were slow. Well, gradients will tend to be slow, because they involve a lot of calculations. You could simply not use them. But you didn't want to do that.
And then you made them faster. So, what can we learn from that exercise? My desire for increased performance ended up with getting increased performance. And you figure that's going to get me to realize the error of my ways and stop? ;)

Quote:
Personally I would be designing so you had speed to spare - not everyone will have a PC as fast as yours
I try to. That's why I'm never satisfied when you say something is fast enough. Hence the exercise with the gradients. :) But I'm also not willing to sacrifice aesthetics. Figuring out how to have both is the way to move forward.

https://github.com/fiendish/aardwolfclientpackage
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #38 on Sun 05 Dec 2010 12:35 AM (UTC)

Amended on Sun 05 Dec 2010 12:39 AM (UTC) by David Haley

Message
Sorry if you felt I was being hostile. My main goal is just to identify where the problems are coming from because I've been seeing a trend on the forums where people point the finger at Nick for "slowness" where it's not really his fault. Hopefully starting over will work. :-)

Let's start from basic principles. Firstly, I think we all agree that what the user sees matters for the user's experience.
What Nick and I are saying though is that why the user might see a delay can happen for several reasons. Perhaps the CPU is overloaded and can't draw fast enough. Perhaps the CPU is overloaded and is doing some necessary and uninterruptible task before it gets the chance to draw. Perhaps some task is taking a long time and isn't giving the GUI routine a chance to run, but could. Basically, there are many reasons why a program could appear slow.

You want to measure the user's window of immediacy. That's fine, as an end goal. But when trying to fix the problem, you need to get to the underlying cause of the slowness.

I'm not trying to be coy when I talk about the difference between the appearance of unresponsiveness and actual unresponsiveness. I realize that the statement might sound odd or even foolish at a quick glance. But this is an important distinction, because once you know which situation you're in, you know where you need to fix things. If something merely appears unresponsive but in fact is working under the hood on user input and so forth, you know that you need to give your GUI routines more chances to draw. But if something is actually slow under the hood, then you shouldn't be looking to the GUI but instead at the code that is slow. Sometimes these problems can be combined, which is why I suggested the coroutine idea, an approach that seems to be giving Nick good improvements based on his empirical measurements.

I think that it's unlikely that MUSHclient's rendering speed needs improvement here, because based on Nick's measurements, it can render an awful lot of things awfully quickly. You said early on that you're running a lot of search routines. Those are a great place to start looking, because while they are running you aren't updating the GUI.

Regardless, until we identify the culprit(s) through empirical measurement, any optimization is premature, and we know what they say about premature optimization. :-)

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #39 on Sun 05 Dec 2010 12:46 AM (UTC)

Amended on Sun 05 Dec 2010 12:47 AM (UTC) by Twisol

Message
In other words, it's the difference between slowness due to task backup and slowness due to inefficiency.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,166 posts)  Bio   Forum Administrator
Date Reply #40 on Sun 05 Dec 2010 03:20 AM (UTC)
Message
Fiendish said:

Actually, I've been wondering about this. Is there a way in MFC to only repaint part of the screen?


Absolutely. I used to do that before miniwindows came along. But it can be tricky to get right. And in any case, since the end result is one big bitmap, and the text scrolls, there isn't a huge amount of point.

Let's assume that the map window overlaps the text output, at least by a bit. As the text scrolls up you at least have to invalidate the text part, and then redraw it, and then blit the miniwindow back on top of the text. Which is what happens now, without all the complex calculations about which part should be redrawn.

If you have a pure text window (which we don't) then there is an API call (ScrollWindow I think) that internally shifts the bitmap vertically (or whichever way) so it doesn't need to be redrawn, and then you invalidate the last few lines, and redraw those. But you can't shift the bitmap vertically if it is even slightly overlapped by a miniwindow, because that would jump up as well, looking really really bad.

So basically to implement miniwindows I decided to get rid of selective invalidating, and just redraw the whole thing. The miniwindow are reasonably efficient themselves, because they aren't recreated, just blitted back on top of the text.

Fiendish said:

If I say "Hi Grandma" to my grandmother and she does nothing, and maybe I say "Hi Grandma" again, and she does nothing again, it doesn't do me any good if after I leave she perks up and says "Hi Grandson. Hi Grandson."


Scenario.

Your grandmother is driving you in her car down a slippery mountain road (ice, sleet that sort of thing). She is concentrating hard on the road, and responding quickly and efficiently to the curves in the road, and keeping you both alive.

So it actually does do you good that she doesn't immediately respond to your saying "Hi Grandma", it is keeping you alive. She is processing a higher priority task. When the higher priority task allows it, she responds.

I understand what you are saying about it being important for the player to feel things are responded to. In fact one of the things I like about WoW is the way that things feel very responsive. And the way they do that is, for one thing, to let you move your toon around at the client end, instantly. And then it transmits your updated position to the server. So if you happen to play alongside another player, the images on the two screens can be out of sync. On one screen you might be ahead of your friend, on another, behind him.

Ditto for inventory. If you look at your inventory it immediately appears, because it is cached locally. And the map. And quests. And I'm pretty sure even mobs have a "initial reaction" coded into them, which makes them respond and run towards you, even before the server has told them to. Eventually the server kicks in and has the final say, and sometimes you then see mobs jump around to different places.

I'm all in favour of fast-appearing responses. But I think that to a certain extent they need to be designed in. As in my suggestion of a different way of displaying speedwalks, one that is less processor-intensive.

Similarly for the spellups. I think a while back Lasher and I agreed on a protocol where you found what spellups (buffs) you had on you, and then the server just advises of changes (gain, lose one or more). That way the client always had a local picture of the spellups, and could display them promptly.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Fiendish   USA  (2,551 posts)  Bio   Global Moderator
Date Reply #41 on Thu 09 Dec 2010 09:16 AM (UTC)

Amended on Thu 09 Dec 2010 09:17 AM (UTC) by Fiendish

Message
Nick,
I finally tried out your suggested coroutine changes, and I'm not seeing what you show in your video. Maybe it's a consequence of my setup, but for every room I walk through the mapper window disappears and then reappears when the drawing is done. I don't see a starburst. I see the mapper window flickering. Are we using the same mapper code? I think I'll just stick with setting the search depth to 4 during speedwalks for now, since that seems to work well.

https://github.com/fiendish/aardwolfclientpackage
Top

Posted by Nick Gammon   Australia  (23,166 posts)  Bio   Forum Administrator
Date Reply #42 on Thu 09 Dec 2010 11:41 AM (UTC)

Amended on Thu 09 Dec 2010 11:42 AM (UTC) by Nick Gammon

Message
As I said on the earlier page:

Nick Gammon said:

I also moved around the drawing loop (above, with the yield in it) to lower down, otherwise you don't see the map, border etc. at all until it is finished.


If you don't do that, yes you will get that effect. The relevant part was moved down here:


 -- 3D box around whole thing
  
  --draw_3d_box (win, 0, 0, config.WINDOW.width, config.WINDOW.height)
  draw_edge()

  add_resize_tag()
     

  -- make sure window visible
  WindowShow (win, not hidden)

  rooms_traversed = (rooms_traversed or 0) + 1

  while #rooms_to_be_drawn > 0 and depth < config.SCAN.depth do
    local old_generation = rooms_to_be_drawn
    rooms_to_be_drawn = {}  -- new generation
    for i, part in ipairs (old_generation) do 
      draw_room (part.uid, part.path, part.x, part.y)
    end -- for each existing room
    depth = depth + 1
    if depth % 3 == 0 then
      coroutine.yield ()
    end -- if
  end -- while all rooms_to_be_drawn
  
  for area, zone_exit in pairs (area_exits) do
    draw_zone_exit (zone_exit)
  end -- for
  
  last_drawn = uid  -- last room number we drew (for zooming)


For one thing, you need to at least do a WindowShow before yielding in the coroutine, and by moving the room drawing part down, you get the borders, room title etc. first.

Only problem is the lower rooms might overlap the title or area, but I thought I would leave that as an exercise. Maybe make drawing the area and title in a separate function, and do it once at the start (so you see it during the updating) and then again at the end to plonk on top of any rooms that went near the edge.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Fiendish   USA  (2,551 posts)  Bio   Global Moderator
Date Reply #43 on Thu 09 Dec 2010 05:52 PM (UTC)
Message
Ah, I missed that part. Thanks.

https://github.com/fiendish/aardwolfclientpackage
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #44 on Thu 09 Dec 2010 08:30 PM (UTC)
Message
Nick Gammon said:
Only problem is the lower rooms might overlap the title or area, but I thought I would leave that as an exercise. Maybe make drawing the area and title in a separate function, and do it once at the start (so you see it during the updating) and then again at the end to plonk on top of any rooms that went near the edge.

Is there something about layering that you really want to avoid?

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


157,951 views.

This is page 3, subject is 4 pages long:  [Previous page]  1  2  3 4  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.