How to optimize performance on Roblox — Transcript
Full transcript
- 0:00Hey everyone, it's Andrew from Roblox.
- 0:02This video looks at common performance
- 0:04problems in Roblox experiences and
- 0:06strategies you can use to mitigate them.
- 0:08Before we dive in though, two quick
- 0:10disclaimers. One, I am not an
- 0:12environmental artist. At several points
- 0:14in this video, I'll ask you to use your
- 0:15imagination because I don't have the
- 0:17time or the skill to build the things
- 0:18I'm talking about. Two, I'm not
- 0:21advocating for compromising on your
- 0:23artistic vision. Build the experience
- 0:25you want to build. But along the way,
- 0:26you might consider how these strategies
- 0:28can make your experience more performant
- 0:30and help it reach a broader audience.
- 0:32With that out of the way, let's start
- 0:33with rocks. That's right, rocks. Lots of
- 0:37rocks. We're using rocks to demonstrate
- 0:39a fundamental concept of computer
- 0:41graphics. Draw calls. Draw calls are
- 0:43commands from the CPU to the GPU to
- 0:45render something on screen. If you have
- 0:47lots of unique meshes, the Roblox engine
- 0:49has to make draw calls for each mesh. On
- 0:52mobile, you can quickly get into a
- 0:53situation where your device is
- 0:54struggling to keep up. If you were to
- 0:56look closely at the beautiful stone
- 0:58walls of Ireland, you'd of course see
- 1:00lots and lots of unique rocks. But what
- 1:03if you constructed a wall by duplicating
- 1:04four or five rocks over and over and
- 1:06then artfully arranging, coloring,
- 1:08resizing, and rotating them? Unless
- 1:10somebody really scrutinized that wall,
- 1:12would they even notice?
- 1:15A technique known as batching lets your
- 1:17CPU make a single draw call for tons of
- 1:19objects as long as they share the same
- 1:21mesh. So you can import a small handful
- 1:23of particularly excellent rocks and use
- 1:25them to build all sorts of things.
- 1:26Walls, landscapes, cliffs, rivereds,
- 1:29whatever. Here I've imported the same
- 1:30rock many, many times so that each one
- 1:32gets its own mesh ID. Don't do this. I
- 1:36only did it to illustrate the point.
- 1:38Look at all those draw calls. If I
- 1:40delete all of those duplicate imports
- 1:41and just copy the same rock over and
- 1:43over, draw calls don't increase at all
- 1:44because I'm reusing the same mesh. The
- 1:47goal here isn't to keep your draw calls
- 1:49needlessly low and build bland
- 1:50environments. Instead, this sort of
- 1:52optimization gives you the headroom to
- 1:54use your draw calls on the things that
- 1:55really matter. On a low-end mobile
- 1:57device like this one, it can be the
- 1:58difference between a game that looks
- 1:59like this, running pretty darn well, or
- 2:02a base plate with some rocks struggling
- 2:04to stay above 30 FPS. But you don't have
- 2:06to take my word for it because I've
- 2:07recruited the one and only Mr. Chicken
- 2:09Rocket for a quick discussion of draw
- 2:11calls and relative device performance.
- 2:13Take it away, Peter. Hey, thanks Andrew.
- 2:15When I create a game, I usually start
- 2:17with a basic budget. Something like half
- 2:19a million triangles and 500 draw calls
- 2:21in the scene for any given view. And
- 2:23then I stick to that budget as I build.
- 2:24It's the best way I know of to avoid
- 2:26having to go back and redo work because
- 2:28things aren't running at 60 frames per
- 2:29second anymore. And I hate redoing work.
- 2:32Staying under budget while I'm working
- 2:33in studio means I can be fairly sure
- 2:35that it'll run great on a wide range of
- 2:37devices, but every now and then I'll
- 2:39still break out an old iPhone and go
- 2:41check. When I am testing on device, what
- 2:43I'm usually looking for is making sure
- 2:44that it's still running at 60 frames a
- 2:46second. And sometimes I'll check the
- 2:48micro profile to see what's going on
- 2:50with CPU usage, too. Next, let's talk
- 2:53streaming. Streaming is enormously
- 2:55complex under the hood, but it's easy to
- 2:57enable and offers huge performance
- 2:58benefits. In essence, streaming creates
- 3:01an invisible cube around each character.
- 3:03As characters move around, parts stream
- 3:05in and out based on whether they're
- 3:07inside or outside of the cube. Streaming
- 3:09improves frame rate and join times.
- 3:11Maybe most importantly, it reduces
- 3:13memory usage on the client, which can
- 3:15help you build more expansive worlds,
- 3:17minimize crashes on low-end devices, and
- 3:19let more people play your game. The
- 3:21default values are good options for a
- 3:23wide variety of experiences, but
- 3:24streaming has a bunch of properties you
- 3:26can tune. Check the documentation for
- 3:27full descriptions of these properties.
- 3:29The key ones for today are streaming
- 3:31target radius and streaming min radius.
- 3:33Streaming target radius defines the
- 3:35outer bounds of the cube, the maximum
- 3:37distance at which players see the full
- 3:38detail of your experience. If your
- 3:40experience relies on longer viewing
- 3:42distances for visual impact, consider
- 3:44bumping this up a bit as you tweak the
- 3:46value. Test your experience and note the
- 3:48impact on memory usage and frame rate.
- 3:50There's almost always a sweet spot that
- 3:52offers tangible performance gains
- 3:53without diminishing visuals. Streaming
- 3:56min radius defines a second smaller cube
- 3:58inside the larger one. Parts inside of
- 4:00it have the highest priority when it
- 4:02comes to streaming. Because the engine
- 4:04is already trying to stream in content
- 4:05at the streaming target radius, this
- 4:07second cube is more of a fallback for
- 4:09situations in which the engine is
- 4:10struggling to keep up and has to
- 4:12prioritize parts closer to the
- 4:14character. As such, be sure to keep this
- 4:16value smaller than streaming target
- 4:17radius. If the two values are the same,
- 4:19what you've done is make everything a
- 4:21priority. And when everything's a
- 4:22priority, nothing's a priority. Yet
- 4:25again, you don't have to take my word
- 4:26for it because I've recruited
- 4:27Wellblander from our engine team to say
- 4:29more. Hey, thanks. As mentioned, I'm
- 4:31Well, Blander, a PM on the streaming
- 4:32team here at Roblox, and I want to
- 4:34quickly talk about how streaming can
- 4:36help with humanoids in your games. In
- 4:39short, humanoids can really stress your
- 4:41players devices, especially those
- 4:43lower-end phones and tablets some might
- 4:44be using. Humanoids are animation and
- 4:47physics heavy, causing high CPU usage
- 4:50while also using lots of memory and
- 4:52network bandwidth. And in really large
- 4:54worlds with lots of players and/or NPCs,
- 4:57your players devices, no matter their
- 4:59strength, will really struggle to keep
- 5:01up with all your game's characters. Hey,
- 5:04well, streaming can help here, too. If
- 5:06those humanoids are in the distance and
- 5:08they aren't impacting gameplay, then
- 5:11chances are, well, they're not needed.
- 5:13With streaming on, the Roblox engine
- 5:15will automatically stream these distant
- 5:18characters out, saving your players
- 5:20device resources, resulting in smoother
- 5:23gameplay and fewer
- 5:25crashes. But well, what if there's a
- 5:27particular humanoid that is crucial to
- 5:29your gameplay? I don't know. Um, take
- 5:32for example some opponent player
- 5:34carrying a captured flag or something,
- 5:36but they're really far away. Well, then
- 5:39you can use StreamY's persistence option
- 5:41to ensure that flag carrying character
- 5:44is always streamed in. Pretty cool. But
- 5:47beware, if you overuse persistence,
- 5:49you'll find yourself right back dealing
- 5:51with the problems that streaming was
- 5:53meant to solve in the first place. So,
- 5:55use this option sparingly. Last, I want
- 5:58to say that sometimes even streaming
- 6:00isn't enough and instead you might need
- 6:02to design your places and gameplay to
- 6:05space players out or reduce the maximum
- 6:07numbers of players per server. If you
- 6:09think your experience might have issues
- 6:11here, keep an eye on the update
- 6:13invalidated fast clusters tag and the
- 6:16micro profiler. Thanks so much, Wland
- 6:18Blander. Finally, let's talk central
- 6:20processing units, CPUs. If you owned any
- 6:23of the original smartphones, you might
- 6:24have fond memories of how revolutionary
- 6:26they felt. But you also might remember
- 6:28that they were so slow. Smartphones have
- 6:30made extraordinary strides over the past
- 6:3215 years. But due to thermal
- 6:34constraints, their CPUs are still only
- 6:36about one quarter the speed of powerful
- 6:38desktops in longunning intensive
- 6:40workloads like, you know, games. All of
- 6:42this is to say that it's easy to create
- 6:44experiences that run fine on your
- 6:46development machine and completely tank
- 6:48CPU performance on a smartphone. There
- 6:50are three main culprits here. Scripts,
- 6:52physics, and lighting. Let's start with
- 6:55scripts. Placing code into run
- 6:57service.preder or its deprecated
- 6:59counterpart render step causes it to
- 7:01execute before each and every frame.
- 7:03With a budget of only 16.67 milliseconds
- 7:05per frame in a 60fps experience, even
- 7:08seemingly minor additions to pre-render
- 7:10can have an enormous impact on
- 7:12performance. See here how I was able to
- 7:14bring this experience to a crawl with
- 7:16just a few lines of code by searching
- 7:17the scene every frame and doing a bit of
- 7:19ray casting. This isn't to say that you
- 7:21should never add code to run service.p
- 7:22pre-render. Sometimes it's the best
- 7:24solution, but you should keep it to the
- 7:26bare minimum, such as custom camera
- 7:27updates or other elements that require
- 7:29precise visual synchronization. Whenever
- 7:32possible, write code that runs in
- 7:34response to specific events rather than
- 7:36before every frame. If you want a call
- 7:38back to run on a loop, consider whether
- 7:40it really has to happen every frame or
- 7:42whether it can happen more infrequently.
- 7:44Next, physics. If you see the physics
- 7:46stepped tag in the microprofiler
- 7:48becoming a limiting factor to your frame
- 7:50rate, check which parts in the scene
- 7:52really need to be unanchored. The sheer
- 7:54number of simulated parts is the most
- 7:56common cause of poor physics
- 7:57performance. You should also consider
- 7:59enabling adaptive physics stepping in
- 8:01the workspace, which lets Roblox run
- 8:03certain physics calculations less often.
- 8:06Finally, lighting. Lighting and shadows
- 8:08are critical to the atmosphere of an
- 8:09experience. The client eventually falls
- 8:11back on simplified voxil technology. As
- 8:14graphics quality level decreases, so
- 8:16keeping lighting performance high means
- 8:17that more players get to see the scene
- 8:19as you designed it. Consider setting
- 8:21cast shadow to false on small parts
- 8:23where the shadow would barely be visible
- 8:25anyway. Also, watch out for movement. If
- 8:27you have a large light that's always in
- 8:29motion, the engine has to continuously
- 8:31calculate the effect of that light on
- 8:32its surroundings. See here how CPU
- 8:34performance dips as the lights approach
- 8:37and then improves as they depart. I know
- 8:39what you're thinking, Andrew, no. You
- 8:41didn't find a third performance expert
- 8:42wandering the halls of Roblox, did you?
- 8:44Well, I did. Go for it, Owen. Hi all.
- 8:47One thing Andrew didn't mention is you
- 8:49can actually create your own tags when
- 8:50profiling your experience. Using the
- 8:52debug.profile begin and debug.profile
- 8:55end methods, you can tag a section in
- 8:56your code with an arbitrary string. Then
- 8:58when you pull up the microprofiler, you
- 8:59can look for these tags to reason about
- 9:01the impact of a specific game system.
- 9:03Please remember though, code is supposed
- 9:04to take time to execute. If you're
- 9:06encountering frame rate hitches or your
- 9:08players are complaining about these
- 9:09issues, perhaps low heartbeat, you
- 9:11should definitely dive in and diagnose.
- 9:12But early on in development, you really
- 9:14don't want to spend too long obsessing
- 9:15with how many milliseconds each function
- 9:17in your code takes to run. All that time
- 9:19you'll spend micro optimizing is time
- 9:21you're not spending making your game
- 9:22more fun. And over time, all these micro
- 9:24optimizations you add to your code will
- 9:26add up. You have to stay focused on the
- 9:27big picture. Performance optimization is
- 9:30an all-encompassing, extraordinarily
- 9:32challenging topic, so there's no way we
- 9:33could cover every possible facet in a
- 9:35video. I want to extend a huge thank you
- 9:37to our three experts for joining me
- 9:39today and shedding some additional light
- 9:40on the subject. If you want to dive
- 9:42deeper into performance, including way,
- 9:44way more information on tools, memory
- 9:46usage, streaming, humanoids, rendering,
- 9:47and everything else from this video,
- 9:49check out the documentation at
- 9:52create.roll.com. Thanks for watching.
About this transcript
This page contains the full transcript of How to optimize performance on Roblox by Roblox Creators, generated from the public captions YouTube serves with the video. The transcript has 1,964 words across 303 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.
What you can do with it
Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to choose a caption track available on the video.
Free YouTube transcript tool
YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, caption language selection, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.