ID:435559
 
Resolved
Use of SIDE_MAP caused the server to tell Dream Seeker to draw more turfs than it needed to, slowing down map drawing unnecessarily.
BYOND Version:494.1125
Operating System:Windows XP Pro
Web Browser:Chrome 17.0.963.56
Applies to:Dream Daemon
Status: Resolved (494)

This issue has been resolved.
Descriptive Problem Summary:
Dream Seeker's graphical display occasionally struggles to display the objects on the screen at the desired framerate. Here are some things that might help narrow down the problem:

The world's CPU usage (measured by world.cpu) is often zero. It averages between zero and one. The game creates copies of maps so it can spike up to 10-15, but when this lag occurs world.cpu is low. The problem seems to be entirely with how BYOND draws the screen.

My graphics card is a GeForce GTX 260. It's more than capable of running Starcraft 2 (the most recent game I have) so I'd hope it could handle drawing 800 sprites at 40 fps, but maybe there's a fluke with how BYOND happens to work on this GPU.

Some of the icons aren't square, they're 32x48. Maybe there's something odd about how BYOND handles non-square icons or icons whose dimensions aren't powers of 2.

Each turf has between 0 and 3 overlays. One of the overlays uses the alpha channel, the other two don't. I can understand how this might slow things down, but again, drawing 800 sprites at 40 fps shouldn't be a problem.

The demo uses the SIDE_MAP format.

It tends to happen when moving diagonally. I've noticed before that BYOND had problems when the screen moved, particuarly when it moved in both directions (or was updated multiple times per tick).

The problem can be more noticeable at higher framerates. If I try to run the game at 80 fps (you can adjust the framerate in the demo I've provided) it slows down to 30 fps more often.

The display lag seems more noticeable when the icon mode is "stretch to fit" and the display is larger.

I fully expect this to be deemed "not a bug", but if a $200 GPU (purchased in 2009) can't run a game whose graphics are on par with games from 1993, there's absolutely something wrong with BYOND.

Numbered Steps to Reproduce Problem:
Download this and play it.

Expected Results:
The game runs at 40 fps consistently.

Actual Results:
Occasionally (at 0:19 to 0:22 in the video) the screen can't be drawn at 40 fps.



I used fraps to display the framerate seen in the video. I don't trust it completely (it drops to 20 when I'm standing still) but it does seem to accurately represent the slowdown.

Does the problem occur:
Every time? Or how often?
In other games?
In other user accounts?
On other computers?

The problem tends to occur at the same locations in the game, but it doesn't always happen at those locations.

When does the problem NOT occur?

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? (Visit http://www.byond.com/download/build to download old versions for testing.)

Workarounds:
Well, I didn't have any problems with your demo (performance wise, though the Z key didn't seem to jump), but I have had issues with a lot of the things you've mentioned here. Mostly transparent graphics, icon stretching, and running higher frame rates. Not to mention HUD related issues...

On an unrelated note; perhaps you could teach people better controls in these libraries/demos you release. WASD and Space, for example, in the demo mentioned here. Using these keys opens up much better access to the keyboard and mouse.

Forum_account wrote:
I used fraps to display the framerate seen in the video. I don't trust it completely (it drops to 20 when I'm standing still) but it does seem to accurately represent the slowdown.
BYOND only draws when necessary. The 20 FPS when standing idle is probably due to the water's animation speed.
I will test this out. As Falacy mentioned, it seems to be very machine-dependent. Also, the quality of the graphics card isn't always the deciding factor here, as hw-mode works well on one of my older machines (default card) while not so well in a newer machine. Clearly this is something on our end so I'll try to construct a simple non-BYOND demo that performs some sprite tests to get metrics.

One thing you can do is test a variety of cases to isolate. How does it work in software-mode? What about with a client <-> server setup (can be local) vs the duel client/server (which is going to be more stressed since its single-threaded and sharing workload)?
In response to Tom
Tom wrote:
One thing you can do is test a variety of cases to isolate. How does it work in software-mode? What about with a client <-> server setup (can be local) vs the duel client/server (which is going to be more stressed since its single-threaded and sharing workload)?

I'll run it later so I can give definite answers to those questions. I'm pretty sure it runs consistently slower than 40 fps in software mode. I hadn't tried running a separate client and server, but the world.cpu values are consistently low (the average is around 1.0). I'll try this out but I don't expect the performance will be different.

The demo lets you enable/disable shading and outlines. They seem to contribute to the problem. I figured shading would be worse because it uses the alpha channel (all pixels in the outline icons are solid black or completely transparent). I expected that performance would be better with only outlines (and no shading) than with only shading (and no outlines), but that wasn't the case. Outlines seemed to have worse of an effect on performance. This made me think it had something to do with the icon sizes - the shading icons are 32x32 but the outline icon is 32x48.

I'm not sure if it comes down to pure drawing power (ex: number of sprites per second), or if it's just in how things are handled. It seems like there may be some internal handling that builds up a lot of waste (spare textures, arrays, etc.) and while the drawing can be done quickly enough it's the cleaning up of these resources that slows it down. I wouldn't be surprised if this was caused by something that always happens but is made worse by the icon sizes, map format, or something else.

Falacy wrote:
On an unrelated note; perhaps you could teach people better controls in these libraries/demos you release. WASD and Space, for example, in the demo mentioned here. Using these keys opens up much better access to the keyboard and mouse.

Both the pixel movement and sidescroller libraries make it easy to change which keys you use (the PM library has demos that show alternate control schemes, WASD being one of them). You could just as easily use IJKL if it makes sense for the project. If you don't need the mouse, the arrow keys are more intuitive than WASD.
In response to Tom
Tom wrote:
How does it work in software-mode?

With the icon display set to 32x32, the framerate seems to cap out around 30. Whether I run at 30 or 40 fps it looks the same, but going below 30 I can see it slow down. If the icons are "stretch to fit" it's significantly slower.

What about with a client <-> server setup (can be local) vs the duel client/server (which is going to be more stressed since its single-threaded and sharing workload)?

The display hovers around 30-35 fps (as reported by fraps) when the server is trying to run at 40 fps.
I haven't liked BYOND's speed in any of its respects other than how quickly I can prototype. I just can't get myself to sticking with learning something else, like Java.
In response to Kaiochao
Kaiochao wrote:
I haven't liked BYOND's speed in any of its respects other than how quickly I can prototype. I just can't get myself to sticking with learning something else, like Java.

There's an implied performance tradeoff that comes with using BYOND, it's just unfortunate how bad that tradeoff is. I try to be optimistic about it but with how quirky it can be (ex: having a single screen object causes the framerate to drop by 5-10 fps but only while the screen is scrolling) I'm skeptical about it ever being fixed.
From what you're reporting, I'd venture that this is a server-side issue. The fact that world.cpu is reporting limited usage is most likely an error in how it is computing things or a misunderstanding of what it is reporting (I'd have to look into it); I'd honestly expect a non-negligible cpu for a BYOND game running at 40 fps.

There are a few ways to confirm this. One is to host the game in DD and connect to it in DS; if hw-mode and sw-mode show the same speed, then the bottleneck is on the server (since the client should be able to render 40 fps in either mode). Another test (useful regardless) would be to construct a very simple BYOND demo that just randomly displays an icon (out of two or three choices) on each tile of the view. Then up the fps until fraps shows it lagging; that would give an idea of maximum fps since the server itself is minimally occupied. You can also do all of these tests in text-mode to really isolate client v. server.

BYOND is not an efficient platform for high-speed drawing-- but that's almost entirely on the server-end. The VM is simply not optimized for this sort of thing. There are a few things we can do to improve this. I already made a few hud-related changes in 494 and there are some other pieces we need to look at.

I want to do these tests myself but, somewhat ironically, my graphics card died this morning and I am in the middle of replacing it, but I'll see what I can find when it is ready.
It looks like SIDE_MAP is what's causing this. When I use TOPDOWN_MAP it can run at 60 fps just fine, but with SIDE_MAP it can't. When I use side_map and set it to 60 fps, it bounces around between 35 and 45 fps.

Of course the layering is not correct. I'll test it later on to see if soft-coding the layering to make it work with TOPDOWN_MAP ends up with better performance.

Edit: It appears to run fine at 60 fps in TOPDOWN_MAP mode with soft-coded adjustments to make the layering correct.
I don't like how slow the game gets with an increased view size. What's funny is that you can have a large icon_size with a normal view size and use the same mob icon to have a "relatively large" view size, and the game runs at a good framerate. With a normal/small icon_size, the same mob icon, and an equivalent view size, the game is super slow.
Increasing the view size increases how much the client has to process and render, and also how much has to be processed and transferred across the network.
In response to Falacy
Falacy wrote:
Increasing the view size increases how much the client has to process and render, and also how much has to be processed and transferred across the network.

There will obviously be some slowdown, but I think the problem here is how drastic the slowdown is. If a GPU can draw millions of polygons per second, having to draw 900 turf icons (a 30x30 view) per frame shouldn't be slow.
Lummox JR resolved issue with message:
Use of SIDE_MAP caused the server to tell Dream Seeker to draw more turfs than it needed to, slowing down map drawing unnecessarily.