If you have not seen it, Roblox’s Alpha Strike Group released an official experience “The Mystery Of Duvall Drive”
You can play it here:
And Alpha Strike Group also produced a great set of documentation on how they built it here:
It boasts future lighting and advanced materials and streaming enabled, and it looks absolutely fantastic.
But, frankly, it just doesn’t run very well, especially at max graphics settings…
So in this breakdown, I’m going to run through some things I did to take this from a 20fps experience on max gfx on my modest nvidia 1080ti, to 60fps, and hopefully explain why in a useful way for optimizing your own projects.
First up - my ground rules:
- "max graphics" settings only! Even games like this can be optimized to run well under those conditions, which is the whole point of this article.
- I’m not going to replace/remake any of the art assets or take away any features - for the most part it should stay visually identical
- StreamingEnabled will be turned off, we won’t need it.
- I’ll leave suggestions for things that can be further improved to the appendix.
Let’s start with the base experience:
Sitting at this area near the car and looking towards the house is going to be my test spot, it’s about the worst performing place in the whole map.
It’s got about 7.2 million in-scene triangles, and runs at about 20fps at max settings. Look at how many shadow tris its rendering - almost 12.5 million! Turning the quality settings down disables shadows, so you get a lot of performance back by turning shadows off.
If you just wanted to “make it run better” for no extra effort, turn shadows off and call it a day. But we can keep the shadows AND make it run a lot better, which is what we’ll do.
Key Observation 1: players don’t want to turn the settings down just to make your experience run nicely. You should get used to optimizing your experience with max graphics settings turned on, and learn how to make that run well. By the same token, having an experience that barely works at max graphics settings should be considered a broken experience.
[Warning, the rest of this post is just an outline, I plan on continuing this at a later point, but the highlights are here]
Observations:
Some authoring mistakes:
- Unanchored Physics objects everywhere (7ms cpu just for that…)
- Lack of primary parts on most models (cant distance cull them with no position…)
- Server scripts to do rotations on objects is not a good idea eg: cloud rings, these days you can simply use a localscript for this and save bandwidth (goes from 15kb/s → ~0.3 kb/s)
- Terrain is crudely put together, can at least slice the bottom flat and get rid of a lot of visible caves and cliffs
Observations:
- Most of the outside map is detail objects like trees plants and rocks
- You really can’t see very far which we can use to our advantage
- The map is already broken up into some useful regions such as the motel, the house interior, the grounds, the solarium, the treehouse etc.
- Can’t really see inside the house very well from outside the house until you get close
So first, up, I went and made a few minor changes:
- I turned streaming enabled off.
- I allowed 3rd person view again, just because I don’t like the fps controls when developing in studio
- I went and rearranged a bunch of the folders so that windows belonged to the exterior of the house.
- I edited the contents of some folders for interior sections so that the bounds made more sense (some large volumes that could be moved to exterior etc)
Then I used an existing module I made to tag every single rock, bush and detail object out in the world and set it as a big detail (400 unit culling radius) or small detail (200 units and it culls).
These are quite conservative values, and you shouldn’t ever be able to spot an object being popped out by this. Using tighter values saves a lot more triangles but reduced it from about 7 million in the starting scene to 4.4 million. You could argue that streamingenabled is meant to do this but honestly, streamingenabled is expensive and unreliable, as opposed to just handling it yourself on the client.
Finally I made it so the interior regions, motel, and treehouse only appear if you’re within 50 studs or entirely within them, otherwise they get deparented on the client.
This took the starting area triangle count down to 2.5 million(!)
Link to the optimized project:
The remaining things to do:
-
Properly tidy up the authoring boo-boos like the floating physics objects.
-
Clean up a lot of the moving/flickering lights that cast shadows - one solution for this project would be to possibly turn shadow casting off on lights until they’re within nearby range like < 100 units.
-
Add Tree LOD models, especially important for the gigantic trees - they can’t just be deparented because their popping is noticeable. 1/2 the scenes triangles in trees, so effort here is worthwhile.
-
Add house exterior /solarium LOD models - replace them with simpler models when the player is further away.
-
Possibly wire up a full portal visibility system to reduce rendering when inside/outside the house, although wasn’t really required for this project
-
write more of a breakdown on what you can do to region-ize your own games, and how to hide/show various things like terrain or models.