Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Drop feature to lower minimum requirements?

  • 31-12-2013 11:16pm
    #1
    Registered Users, Registered Users 2 Posts: 454 ✭✭


    Hi,

    I’m currently well into the development of a 2D shooter, using Unity. I decided to try the build on another computer, and found the frame rate was poor, as in fluctuating between 30 – 50 fps. This machine has a decent CPU (1st gen quad core i5), but a toy GPU (Radeon 6450).

    I found out that lights were the key factor in diminishing performance, and without them, or limited use, the game ran fine. I can more or less completely avoid use of lights by removing a feature, night missions.

    I added night missions in the first place to add some variety to the game.

    I’d appreciate your views on whether I should:
    1) remove this feature altogether, and probably lower the bar to a 3-4 year old laptop with integrated graphics
    2)Offer performance settings (current solution) in which the player can determine what level of visual quality they want (There are 4 levels: Highest uses 21 light sources, medium 14, low 3, lowest 0, ie no night missions)
    3) Was also considering not officially supporting night missions, but allowing the user to enter a command to unlock them. Not sure about this one.

    My concern is primarily that people will think indie game, pick the highest setting, then get irritated if it runs slowly, or that if the game is reviewed, that the relatively high requirements of the highest setting will be a black mark against the game.

    My own rig is a 1st gen i5, 4GB, with a 460GTX. It would also run fine on full settings on significantly older hardware, but full lighting isn’t going to be possible on a lightweight GPU.

    Advice?

    Oh, and Happy new year!


Comments

  • Registered Users, Registered Users 2 Posts: 3,831 ✭✭✭Torakx


    What type of lights are you using?
    Are they dynamic or static?
    If static can you just bake them instead?
    If they are switched on or triggered can you switch on one at a time and the unused ones off?

    Unity does have some issues with lights. too many area lights I think 3 lumped together and the Engine automatially switches the least used or furthest one away off and so you get this flicker efect when moving in and out of a certain range.
    Not sure if this also applies to spot lights.
    A screenshot would possibly help to see what your working with.
    I have no idea what these lights are being used for.

    Oh just checking too, you are using Time.deltaTime for your timers right? If not the timers and framerate and game speed can be heavily effected depending on the speed of each pc running the game.


  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    Mix of lights. Think spots are the worst performance wise , have quite a few of them for flashlights attached to guns, at most 7 mid settings (and another 7 at highest setting which switch on and off to add to the muzzle flash effect).

    The low settings just use 1 point light instead to light up a circle around the player character.

    1 directional light in 1 scene to simulate lightning, used occasionally.

    Using them to light up the area characters & are looking at in night missions. All attached to moving objects, so dynamic (that's what you mean?)

    Always switched off completely when not in use. Yeah, pretty sure I'm using time.deltatime for FPS counter. The game's also noticably jumpy, and confirmed frame rate in stats.

    Strongly leaning toward abandoning night missions at this point.

    Screen added. Should add that the average fps is not being properly calculated, but the current and minimum are.


  • Registered Users, Registered Users 2 Posts: 3,831 ✭✭✭Torakx


    Awkward issue alright.
    It should be able to run a scene like that. Lights shouldn't be giving you so much trouble especially if you have tried each type for performance testing.
    I would have thought at least one type of dynamic light would would work ok for this.
    Is it possible your code is partly the issue? Is there a lot of complicated code and in Java script maybe?
    Grasping at straws here haha
    I know Java lets you get away with stuff C# wouldn't allow and with a lot of code could slow down the game without throwing up an error.

    Also not sure if a very high detailed texure on the ground for example would make a dynamic light have to do more work. Or if high poly objects would stress it out too much.
    I have taken a week or two break from dev work and kinda rusty.

    Actually thinking about textures, if you had a high def texture with high def bump map that should create more work for the engine calculating dynamic lights.
    I'l get back to you if I can think of anything else.

    Oh just noticed also you have a mini map, I presume your using a second camera above the player and it is rendering the dynamic lights too?


  • Registered Users, Registered Users 2 Posts: 2,021 ✭✭✭ChRoMe


    How many drawcalls in the scene? what are the garbage collector stats like?


  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    Torakx wrote: »
    Awkward issue alright.
    It should be able to run a scene like that. Lights shouldn't be giving you so much trouble especially if you have tried each type for performance testing.
    I would have thought at least one type of dynamic light would would work ok for this.
    Is it possible your code is partly the issue? Is there a lot of complicated code and in Java script maybe?
    Grasping at straws here haha
    I know Java lets you get away with stuff C# wouldn't allow and with a lot of code could slow down the game without throwing up an error.

    Also not sure if a very high detailed texure on the ground for example would make a dynamic light have to do more work. Or if high poly objects would stress it out too much.
    I have taken a week or two break from dev work and kinda rusty.

    Actually thinking about textures, if you had a high def texture with high def bump map that should create more work for the engine calculating dynamic lights.
    I'l get back to you if I can think of anything else.

    Oh just noticed also you have a mini map, I presume your using a second camera above the player and it is rendering the dynamic lights too?

    It's very possible that code is a contributing factor. Haven't done much optimisation work yet, and I'm still very much in the learning stage. Using C#, but I don't think there's a huge difference between that and JS.

    Your right about the second camera rendering the light. Player can (could) drop flares to reveal enemy position on the minimap. I'll disable the second camera and see if it works.

    One thing I noticed is that one light (on the 6450) was fine, ran at a fairly consistent 50fps. Add another light and it's down to 30fps. Would suggest that lower end cards seriously struggle with lighting. Should also add that this computer is connected to a big screen, and resolution is 1920 x 1080.

    Map is fairly high resolution, but not bump mapped.


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    ChRoMe wrote: »
    How many drawcalls in the scene? what are the garbage collector stats like?

    Max 250 in night missions. Maybe 150 in day missions. Most info I've read suggests this shouldn't be too taxing. Think this is right enough?

    Don't have full version of Unity, so don't have access to garbage collection stats. But, you've hit on something. I'm not using object pooling (yet) and incurring overheads for instantiate/destroy and more frequent garbage collection.

    Know it's difficult to answer, and it depends on what's happening in game and the implementation, but what sort of performance increase could be expected for using pooling? Have read cases where it can actually decrease performance.


  • Registered Users, Registered Users 2 Posts: 2,021 ✭✭✭ChRoMe


    Max 250 in night missions. Maybe 150 in day missions. Most info I've read suggests this shouldn't be too taxing. Think this is right enough?

    Don't have full version of Unity, so don't have access to garbage collection stats. But, you've hit on something. I'm not using object pooling (yet) and incurring overheads for instantiate/destroy and more frequent garbage collection.

    Know it's difficult to answer, and it depends on what's happening in game and the implementation, but what sort of performance increase could be expected for using pooling? Have read cases where it can actually decrease performance.

    Yeah those draw calls seems reasonable enough, I'd have a look through the code and check for any loops where you are creating a large amount of objects and then they are dereferenced. Sometimes a simple change to just having one object which has its values in the loop modified rather than creating a new object everytime can make a big difference.


  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    I'll check through the code for derferenced objects. This would be anything that is either set to null or that has had the destroy method called on it? If so, the two biggest offenders would be bullets and enemies.

    Think I'll look at doing some optimisation first, and then decide whether to drop night missions. Have set up a worst case test scene and fixed the fps counter to calculate averages properly. Will start experimenting with pooling, and report on the results.


  • Registered Users, Registered Users 2 Posts: 3,831 ✭✭✭Torakx


    I'm not actually tat experienced a programmer and a lot of my knowlede is from a ton of research.
    I did read that when referencing objects it can be better to name the biggest offenders in the start function so they are cached for reuse instead of reinstantiating them over and over, maybe bullets would be one object for that.
    I am not experienced or well read on object pooling yet, so maybe this covers that subject already.
    If your lights are making such a big difference there must be a connection there with performance.

    Also even 1k draw calls should be acceptable on a final build(I read 2k would be hitting near the limit of what you should have for a 3d game for example), well depending again on the platform, your doing well for having 250 anyway. if you manage to finish up at around 800 I think you are doing good. Again depends on the scale of your game and whats happening.


  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    Haven't implemented an object pool yet, but what you have described covers the geist of it. Draw calls probably shouldn't go much higher, as the game is close to feature complete.

    Did some tests on my own comp and a laptop i got a loan of. The test isn't 100% accurate, as there are random elements, but it gives a good indication.

    Frame rate in my own comp is fairly decent, average of 59.78 (capped by vsync at 60.36) See High attachment.

    Got a 4 year old laptop, unplayable at medium and high. Not really playable at low with an average frame rate 37.94, considering the fast paced nature of the game. In low setting, there is only one light. See Low attachment.

    Change the test level to a day level, getting rid of the light. Was a lot more stable with an average of 49.66 (capped at 50 to reduce effect of lag spikes). That's an average cost of 12 fps for a single point light! See lowest.

    To me this would suggest that although the code may not be the most efficient, I probably haven't done anything incredibly stupid if its running 50 fps on an old laptop. Not sure how much optimisation will achieve if lights are a resource hog on unity. Will have a go at object pooling and report back. Open to suggestions.


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭Genghiz Cohen


    Haven't implemented an object pool yet

    Was just about to recommend a pool for enemies and bullets.

    Could you remove bullets altogether? Since they move so fast you can't see them anyway.

    What's your clipping like? If things are on screen do they have to move around or can they just follow very basic rules until they are on screen?


  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    Was just about to recommend a pool for enemies and bullets.

    Could you remove bullets altogether? Since they move so fast you can't see them anyway.

    What's your clipping like? If things are on screen do they have to move around or can they just follow very basic rules until they are on screen?

    Yep, have just set up basic object pooling for some bullets to see how it goes. Still some odd behaviour, but unlikely to be a major issue to fix. Impression is that it's smoother, but waiting on getting a lend of an old laptop to do some tests.

    Guess it would be more efficient to raycast, but don't like the idea at of dropping bullets at this point. Kinda like the visual effect of bullets flying around, but mainly because pretty much everything in the game either shoots or can be shot, and it's likely to be a headache replacing something so fundamental.

    I don't think there's any difference in how enemies behave on and off the screen (unless unity is doing something behind the scenes on the visual side). The rules are fairly simple for enemies: spawn, assign objective, pursue objective. In terms of movement and targetting, the behaviours are pretty much as simple as you can get.

    Are you suggesting something like having a very simple process, like a timer until enemy reaches screen, and only instantiating the enemy just before then, or trying to save on draw calls by not rendering, or something like this?


  • Registered Users, Registered Users 2 Posts: 3,831 ✭✭✭Torakx


    You are using collision to detect bullet hits?


  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    Torakx wrote: »
    You are using collision to detect bullet hits?

    Yep, that's right


  • Registered Users, Registered Users 2 Posts: 3,831 ✭✭✭Torakx


    I was told by another developer(coder) it slows down the engine a fair bit using that method.
    Might make a noticeable difference to take collision off the bullets and register the hit by code.
    I didn't get a chance to test this, but it makes a lot of sense to me.
    Not sure how easy this is without raycasting. Maybe it isn't so hard to add a random number generator within a limit to account for accuracy/misses.

    Since it's top down or seems to be, you probably won't need the bullet registering hits on the environment like I was doing in 3D and could just set a timer or distance to destroy them.
    But sure see how the object pooling works out first I suppose.


  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    Torakx wrote: »
    I was told by another developer(coder) it slows down the engine a fair bit using that method.
    Might make a noticeable difference to take collision off the bullets and register the hit by code.
    I didn't get a chance to test this, but it makes a lot of sense to me.
    Not sure how easy this is without raycasting. Maybe it isn't so hard to add a random number generator within a limit to account for accuracy/misses.

    Since it's top down or seems to be, you probably won't need the bullet registering hits on the environment like I was doing in 3D and could just set a timer or distance to destroy them.
    But sure see how the object pooling works out first I suppose.

    Yeah, it's certainly and option, and it's always good to have those. The tests on pooling bullets suggest just under a 1% increase in average frame rate, and just over 2% on minimum frame rate. Just from looking at the fps counter, it seems that instantiating enemies causes a larger performance hit than bullets. Enemies are more complex objects, but they spawn at a max of 1 per 1.5 seconds, whereas up to 15 bullets can be instantiated per second in late game.

    Will try pooling enemies on monday, and should have a better idea of how much good pooling does.


  • Registered Users, Registered Users 2 Posts: 7,182 ✭✭✭Genghiz Cohen


    Are you using a tree to track bullet collisions?
    I have a basic understanding of it myself as I didn't pay attention in class.
    But you would place all objects that can collide together into a tree so you only have to test objects that might actually be colliding. It's orders of magnitude faster than brute testing everything.


  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    Are you using a tree to track bullet collisions?

    No, afraid not. There are 2 sets of bullets, ones fired by player & allies and ones fired by enemies. Using layers so player bullets ignore allies (and vice versa), and bullets fired by enemies pass through other enemies. When a bullet fired by the player hits an enemy, it checks if it is an enemy gameobject, then applies damage/effects etc.

    There's no terrain to speak of, so if a bullet actually hits something, it's guaranteed (AFAIK) to be a viable target. Will take a look at the idea of placing objects which collide into a tree though. Thanks.

    Tested object pooling with enemies today, and the improvement was pretty minimal. Average frame rate actually dropped 1/10 frame, but minimum was up 1/2 frame. Will also need to add some additional logic to handle cases were the next enemy in the list is not inactive, and to handle not having a free enemy to activate.

    In saying that, the difference on a fast comp is likely to be less than on older hardware, so will try on an older comp first before deciding whether to keep pooling or revert to instantiate/destroy.


  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    Ran some tests on old laptop. 4 years old, Dual core amd, with low end graphics, 4 gb ram. The game scene is pretty hectic, loads of enemies coming in from all sides, several automatic turrets holding them off.

    No optimisation: Average FPS: 59.34 / Min FPS: 56.75

    Bullets Pooled: Average FPS: 59.88 / Min FPS: 57.99

    Enemies and Bullets Pooled: Average FPS: 59.94 / Min FPS: 58.16

    Compared to a 12FPS drop for adding a light, the gains here are trivial. There's about 2 days work to extend object pooling to the entire game. Is it actually worth it? 1 con is that the methods I'm using to handle the pooling are depreciated in Unity 4, another is that there is a greater risk of error and greater code complexity. Any advice appreciated!


  • Registered Users, Registered Users 2 Posts: 1,481 ✭✭✭satchmo


    The very first thing you should do when starting an optimization pass is to determine where your bottleneck is. If the bottleneck is the GPU, no amount of CPU optimization will help raise the framerate. This appears to be the case here, as you say adding another light has a significant impact on framerate. Dynamic lights are generally almost free on the CPU side, but can cost a lot on the GPU.

    Are you running forward or deferred? If you don't know what I'm talking about, read this and the pages linked from there. I'm guessing you're using forward, as deferred lighting is a pro-only feature. Unity gives you some control over the performance of forward rendered lighting... basically you want as few lights as possible being per-pixel, the rest being per-vertex or (ideally) SH.

    Some random pointers:
    - Small lights are cheaper than big lights.
    - Point lights are cheaper than spotlights.
    - Beware of very soft lights, you might be surprised how many pixels they touch. A sharper falloff or smaller penumbra can be a good way to reduce the number of pixels touched without changing the look too much.
    - Cookies & normal maps will add to the cost of per-pixel lights, cut them if you can.
    - The cost of vertex-lit lights is directly proportional to the number of vertices on the geometry they light, so make sure your vertex counts are sane, and you're using LODs properly.
    - Split up the ground geometry into tiles so that one small light won't cause every visible pixel of the ground to have to calculate that light's contribution.
    - When all else fails, reduce the number of lights.


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    As you say, it would appear the bottleneck is in the GPU, when tested on the older laptop. Lights and particles kill the frame rate, whereas frequent instantiate/destroy has minimal impact.

    Yes, it is forward lighting. I did experiment with vertex lights, but the position of the lights changed and the effects were somewhat unpredictable (some objects remained completely dark, whereas others were too bright), but maybe this can be fixed with tweaking. Guess could add a second set of vertex lights for low performance, and decide which set of lights to switch on depending on the user's quality settings. Will have a look at this tomorrow. Thanks for the advice.

    Finding it really hard to decide whether to build the object pooling system beyond the test level, or revert to the old system. Leaving something in a halfway state really bugs me. Do you think a minimal improvement to framerate (0.5% - 2%) is worth i) possible issues when/if migrating to Unity 4 (and by extension, releasing on Linux) & ii) increased code complexity & chance of error?


  • Registered Users, Registered Users 2 Posts: 1,481 ✭✭✭satchmo


    Guess could add a second set of vertex lights for low performance, and decide which set of lights to switch on depending on the user's quality settings.
    Definitely sounds like a good idea.
    Do you think a minimal improvement to framerate (0.5% - 2%) is worth i) possible issues when/if migrating to Unity 4 (and by extension, releasing on Linux) & ii) increased code complexity & chance of error?
    Yeah I know what you mean, increased code complexity without an associated increase in performance or functionality is rarely a good thing, and could well bite you in the ass further down the road. On the other hand, pooling gameobjects is generally a good idea if you frequently create & destroy them.

    This is where source control comes in. That code will live on in the revision history so you can safely delete it now to keep things clean, and then resurrect it later if necessary.

    ....you are using source control, right?!


  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    Set up vertex lights today. Vertex spots don't really look so good, but point lights work well. Got a brief chance to test it while visiting a relation, and it performs quite a lot better than per pixel lights.

    Reverted the pooling system for now. Waiting to get my hands on an old laptop, and I'll look at it again. Source control... you caught me out. I have 60 subsequent versions of the code on a hard drive. Never actually installed version control software, mainly just saved the code every 3-7 days when the build was stable and moving in the right direction. That doesn't work so well when the code diverges in 2 paths, though. It's something I really should look into.

    I've revised the quality settings, attached. No night missions or dust storms on low. This should allow the game to be played on an old laptop with integrated graphics.

    Medium has night missions using vertex lights. Seems to run okay on a several year old laptop.

    High introduces dust storms, and replaces a single vertex light centred on the player with a per-pixel spotlight for each ally in the scene (max 6). Will definitely need a mid range dedicated graphics card for this.

    Highest adds one per pixel point light to simulate muzzle flares, and may also add higher quality particle dust storm. The specs for this will be fairly high, but my 3-4 year old gaming desktop handles it just fine.

    This should accomodate a fairly wide range of hardware, but I'm a little nervous that the requirements for the high and highest settings may be a bit steep.


  • Registered Users, Registered Users 2 Posts: 1,481 ✭✭✭satchmo


    Nice work, looks good.

    Do yourself a favour and put aside a few hours to get source control set up. If you don't want to take the dive into learning Git or Mercurial (although you then also get free offsite backup via BitBucket or GitHub), at least set up a local Perforce depot on your own machine - it's free for up to 20 users. The basic functionality is a much easier model to understand than a DCVS, and it's the software that the majority of major studios use (including us).

    Whichever you choose, you'll be glad you did. You can make code changes with impunity, if you find yourself in a dead-end a quick revert gets you back to where you started, and you have a history of various bits of work at a glance. Also, checkin descriptions are immensely useful when looking back over old work - it's amazing how quickly you forget why you made some particular change that seemed obvious at the time.


  • Registered Users, Registered Users 2 Posts: 454 ✭✭Kilgore__Trout


    It's one of those things have been meaning to do. Apart from being useful now, it will be good to know if my own game development ventures don't work out, and I seek employment with another group.

    Have downloaded perforce. Hopefully get it set up in the next few days.


Advertisement