YouTube2Text

Your Roblox Game LAGS (and how to fix it) — Transcript

by Crusherfire · 7,501 words · 1,076 segments · language en · Watch on YouTube

Full transcript

  1. 0:00If you want to learn how to optimize
  2. 0:01your Roblox game, then look no further.
  3. 0:04In this video, we'll be exploring tons
  4. 0:06of ways to optimize your game and
  5. 0:08squeeze out as much performance as
  6. 0:10possible, especially for your mobile
  7. 0:12players. And speaking of exploring,
  8. 0:14let's explore and learn about today's
  9. 0:16sponsor, Brilliant. Brilliant is an
  10. 0:19online learning platform designed to
  11. 0:20make you a better thinker and problem
  12. 0:23solver. They have thousands of lectures
  13. 0:25across a variety of subjects such as
  14. 0:27math, science, programming, data
  15. 0:29analysis, and artificial intelligence.
  16. 0:31Each lesson is interactive and contains
  17. 0:33hands-on problem solving, allowing you
  18. 0:35to experiment and play with concepts
  19. 0:37instead of watching boring lecture
  20. 0:39videos. This style of learning is
  21. 0:41extremely effective, which allows
  22. 0:43Brilliant to help you build your
  23. 0:44understanding from the ground up. You'll
  24. 0:47start off on the basics of concepts and
  25. 0:49work your way up as Brilliant keeps
  26. 0:50track of your progress and places
  27. 0:52increasingly challenging problems in
  28. 0:54your way to make sure you're still
  29. 0:56learning. As programmers, we often
  30. 0:58neglect to understand the lower level
  31. 1:00processes of computers and how they
  32. 1:02transform our code into usable
  33. 1:04instructions. But thanks to Brilliant's
  34. 1:07new digital circuits course, you can
  35. 1:09gain an incredible understanding of how
  36. 1:11logic gates work, which are one of the
  37. 1:13fundamental components used to perform
  38. 1:15logical operations within a processor.
  39. 1:18I've already started going through the
  40. 1:19digital circuits course, and I love how
  41. 1:21incredibly interactive and simple it is
  42. 1:23to learn about the millions of logic
  43. 1:25gates working behind the scenes in our
  44. 1:27everyday devices. To get started with
  45. 1:29Brilliant, you can go to
  46. 1:30brilliant.org/crusherfire
  47. 1:31org/crusherfire or scan the QR code on
  48. 1:33screen to get 30 days absolutely free.
  49. 1:36You'll also get 20% off an annual
  50. 1:38premium subscription. Thanks to
  51. 1:40Brilliant for sponsoring this video. One
  52. 1:42of the first areas of optimization we're
  53. 1:44going to be taking a look at is how to
  54. 1:45improve the memory usage in your
  55. 1:47experience. And a really easy way to
  56. 1:49improve memory usage in your experience
  57. 1:51is by checking if you have high memory
  58. 1:53usage regarding collisions in your game.
  59. 1:56So if we read the Roblox documentation,
  60. 1:58physics, movement and collision
  61. 1:59detection consumes memory. Mesh parts
  62. 2:02along with constructive solid geometry
  63. 2:04parts have a collision fidelity property
  64. 2:06that determines the approach that used
  65. 2:07to evaluate the collision bounds of the
  66. 2:09mesh. The default and precise collision
  67. 2:12detection modes consumes significantly
  68. 2:14more memory than the other two modes
  69. 2:16with lower fidelity collision shapes. If
  70. 2:18you see high levels of memory
  71. 2:20consumption under physics parts, you
  72. 2:22might need to explore reducing the
  73. 2:23collision fidelity of objects in your
  74. 2:25experience. So, inside of a basic
  75. 2:27default template base plate, if we open
  76. 2:30the developer console by hitting F9 on
  77. 2:33our keyboard, and then we open this tab
  78. 2:35right here and go to memory, and then we
  79. 2:37go and shift this or organize this by
  80. 2:40high memory usage by clicking this. And
  81. 2:43then we're going to skip over this core
  82. 2:44memory area because we don't care about
  83. 2:46any of this internal stuff. We just want
  84. 2:48to go down until we find the place
  85. 2:51memory category right here. And the one
  86. 2:53we're going to be specifically looking
  87. 2:55for is physics parts. This one right
  88. 2:57here. Because this is a basic template
  89. 2:59or a base plate. There are no meshes, no
  90. 3:02parts in this place. So the physics part
  91. 3:04memory is at 1 megabyte, which is just
  92. 3:07probably for my player's character. And
  93. 3:09that's it. Once you start building your
  94. 3:11map and you add more unions and you add
  95. 3:13in meshes and all that stuff, this value
  96. 3:16will slowly start to increase and you
  97. 3:18can fight back against how much memory
  98. 3:20usage goes under this category by
  99. 3:22reducing the collision fidelity of
  100. 3:24meshes and unions in your game. For
  101. 3:26example, here in this game that I'm in,
  102. 3:29it's a project that I've been working
  103. 3:30on. You can see that the physics parts
  104. 3:33memory usage is at about 420 mgby. The
  105. 3:36higher and higher this value gets, let's
  106. 3:38say you get close to a th00and megabytes
  107. 3:40or you go over a thousand megabytes, you
  108. 3:42might want to start worrying about how
  109. 3:44much memory usage is being used for
  110. 3:46collisions in your game. And a way to
  111. 3:49improve the value here is by going
  112. 3:52around to all the meshes and unions in
  113. 3:55your game and checking their collision
  114. 3:56fidelity. There's an easy way to do
  115. 3:58this, a really easy way to do this. If
  116. 4:00you go to this little thingy in the top
  117. 4:02right corner, this little set settings
  118. 4:04cog, and you open that up, you should be
  119. 4:06able to find somewhere in here called
  120. 4:08collision fidelity under physics
  121. 4:10simulation. So, if you enable that,
  122. 4:12you're going to see that your map turns
  123. 4:13a whole bunch of crazy colors if you
  124. 4:15have a bunch of meshes. Otherwise, if
  125. 4:16you have regular parts, they won't
  126. 4:18change. But this specifically colors all
  127. 4:20of the unions and meshes in your game.
  128. 4:23Now, the more colors you see means the
  129. 4:26higher resolution this collision is on.
  130. 4:29for example, this door truck. So, if we
  131. 4:32go down to collision, there's going to
  132. 4:34be a property here called collision
  133. 4:35fidelity. Right now, it's set to default
  134. 4:37for this truck door. And default along
  135. 4:40with precise convex decomposition. These
  136. 4:44ones take up the most memory usage. The
  137. 4:46ones that take up the least memory usage
  138. 4:48is going to be box and hole. And as the
  139. 4:50name suggests for box, it literally just
  140. 4:52creates a bounding box uh collision
  141. 4:55fidelity around the object. It's
  142. 4:57literally just a box. and then whole
  143. 4:58kind of you can imagine it as like a a
  144. 5:00saran wrap or a shrink wrap shrinking
  145. 5:03around the object. These two options are
  146. 5:05what you want to try and aim for most of
  147. 5:07the time because they use the least
  148. 5:08amount of memory. And if you take a look
  149. 5:10at my map, you can see I have a lot of
  150. 5:12these uh box collisions on, for example,
  151. 5:16these are light poles. Now, because
  152. 5:17these light poles actually have
  153. 5:19collisions disabled on them, I disabled
  154. 5:21the can collide property, there's no
  155. 5:23reason for me to be storing a bunch of
  156. 5:25information about the collision of the
  157. 5:27light pole when nothing can collide with
  158. 5:29it. So, I just set the collision
  159. 5:31fidelity to box. Uh, I believe it's
  160. 5:34locked right now. So, let me see if I
  161. 5:35can actually find it or maybe pick a
  162. 5:37different object. For example, right
  163. 5:39here, just by looking at this box, you
  164. 5:41probably would wouldn't be able to
  165. 5:42figure out what this is. But if we
  166. 5:43disable collision fidelity, you see it's
  167. 5:46a fire hydrant. Now, right now, fire
  168. 5:48hydrants have all their collisions
  169. 5:50disabled. And because they have all
  170. 5:51their collisions disabled, it doesn't
  171. 5:53really make any sense for me to store a
  172. 5:55whole bunch of information about the
  173. 5:57collision fidelity of the fire hydrant.
  174. 5:59Like, if I set it to default, you can
  175. 6:01see there's a lot of information being
  176. 6:02stored on here on the collision of the
  177. 6:04fire hydrant, which I don't need cuz you
  178. 6:06can't collide with it. So, I set the
  179. 6:08collision fidelity to box, which takes
  180. 6:10up the least amount of memory usage. And
  181. 6:12when you take a look around my map, you
  182. 6:14can see I've made a lot of these
  183. 6:15optimizations all over the place. You
  184. 6:17can see tons of boxes all over the
  185. 6:19place. You can also see these shapes in
  186. 6:22the distance here, these meshes or these
  187. 6:24mountains. And these have their
  188. 6:25collision fidelity set to whole. And you
  189. 6:27can kind of see how it's like a shrink
  190. 6:29wrap effect over the object. This one
  191. 6:31uses the second least amount of memory
  192. 6:34usage. The box one's the best, but if
  193. 6:36you can't use the box one because it
  194. 6:38just doesn't work for the shapes you
  195. 6:39want. Let me see if there's a good
  196. 6:41example I could find. Like for example,
  197. 6:43if you take a look at these buttons
  198. 6:44here, these buttons are kind of semi-
  199. 6:46cylindrical, but I I don't really want
  200. 6:48to have them set to box. Well, actually,
  201. 6:51they have their collision set to
  202. 6:52nothing, so it probably makes sense to
  203. 6:54set them to box. Let me see if I can
  204. 6:55find a better example. I believe there's
  205. 6:56a trash can in here somewhere. Here it
  206. 6:58is. Okay, we have a trash can that
  207. 7:00players can collide with. Now, because
  208. 7:02the trash can is cylindrical, right, it
  209. 7:05doesn't make sense for it to have a box
  210. 7:07collision group. Because if I were to
  211. 7:08set it to box, you got these corners
  212. 7:11sticking out here and players would
  213. 7:13collide with these corners. And that
  214. 7:15would be kind of weird to have a uh
  215. 7:18trash can like this with that kind of
  216. 7:20boxy collision. So that's why you have
  217. 7:22the hole option for collision fidelity.
  218. 7:26It's pretty good for cylindrical
  219. 7:28objects, spheres, stuff like that. You
  220. 7:30just set it to that and it does a pretty
  221. 7:32good job of shrink wrapping around it
  222. 7:33and using very little memory. Let me see
  223. 7:35if I can find any other example. For
  224. 7:36example, here's a triangle. Uh, this is
  225. 7:38just some kind of prop. Technically, I
  226. 7:40could make this have no collision at all
  227. 7:43and then set the collision fidelity to
  228. 7:44box. But for some reason, let's say you
  229. 7:46have some triangle-shaped thing in your
  230. 7:48game that you want players to be able to
  231. 7:49collide with. If we take a look at this
  232. 7:51thing, that's what that is. If we were
  233. 7:53to set the collision fidelity to
  234. 7:55default, you're going to see that's a
  235. 7:56lot of information being stored for a
  236. 7:58triangle. And if we were to set to box,
  237. 8:01eh, that's maybe not the collision that
  238. 8:04we want on the triangle. So, hole is the
  239. 8:08best option for this one. The explorer
  240. 8:10makes it really easy to search for any
  241. 8:12objects in your game that have different
  242. 8:14collision fidelities cuz all you need to
  243. 8:16do is search for the property collision
  244. 8:18fidelity equal to and then it'll pop up
  245. 8:21with all the options. So, maybe you want
  246. 8:23to see if there's anything in your game
  247. 8:24that has the precise convex
  248. 8:26decomposition. And in my game, there's
  249. 8:28nothing, which is great. If you have a
  250. 8:30bunch of meshes or unions in your game
  251. 8:33that has this property enabled, see if
  252. 8:35you can change the collision fidelity to
  253. 8:37something a bit simpler. And if the
  254. 8:40object is super complex and you need
  255. 8:42complex collision, then you probably
  256. 8:46would rather have the object be
  257. 8:49completely non-colidable, set the
  258. 8:51collision fidelity to box, and then
  259. 8:53manually construct your own collision
  260. 8:55fidelity just using parts. that would be
  261. 8:57a lot better for memory usage and
  262. 8:59performance instead of using the the
  263. 9:02precise option. Another memory
  264. 9:04optimization that we can take a look at
  265. 9:05is this category for sounds. If you
  266. 9:08notice that the value here in megabytes
  267. 9:11is extremely high for sounds. Let's say
  268. 9:12you have like 500 megabytes of memory
  269. 9:14being used for sounds for some reason,
  270. 9:16uh that means you have way too many
  271. 9:18sounds in your game that are loaded and
  272. 9:20just sitting around and doing nothing.
  273. 9:22Typically, this happens if you have a
  274. 9:24whole bunch of stuff in the sound
  275. 9:25service. So, let's say you store all of
  276. 9:27your game sounds inside of the sound
  277. 9:29service and different folders and stuff.
  278. 9:30You have all the music in your game, all
  279. 9:32the ambiance, all the sound effects as
  280. 9:35sound objects. Well, the problem with
  281. 9:37doing it that way by having a whole
  282. 9:39bunch of sound instances in here with
  283. 9:42sound IDs is that all of these sound
  284. 9:45instances and the sounds inside of them
  285. 9:48need to be stored inside of memory. They
  286. 9:50need to be downloaded and then they need
  287. 9:52to be stored in memory. That's kind of a
  288. 9:54waste, especially most of the time
  289. 9:56sounds are just sitting in the sound
  290. 9:58service, not being played, and they only
  291. 9:59play at specific moments. So, what's
  292. 10:02better? What's better is to not store
  293. 10:06any sounds in the sound service, and
  294. 10:08instead store your sounds inside of your
  295. 10:10scripts. So basically just have the
  296. 10:13content ID or the sound ID for your
  297. 10:15sound and then create the sound during
  298. 10:18runtime. Play the sound when you need it
  299. 10:20and then destroy it or clean it up
  300. 10:22afterwards when you don't need it
  301. 10:24anymore. As an example, I have a whole
  302. 10:26bunch of utility functions that I use to
  303. 10:29play sounds. And I do so by just giving
  304. 10:32it a table of sound properties. So this
  305. 10:34can be like the volume, the sound ID, if
  306. 10:36it belongs to a sound group or whatever
  307. 10:38it is. And then it plays it. And then
  308. 10:41when the sound is done playing, it
  309. 10:43destroys it for me. So that way I'm only
  310. 10:46creating and loading the sounds into
  311. 10:47memory when I need them, play them when
  312. 10:50I need them, and then clean them up
  313. 10:51afterwards. You can see that inside of
  314. 10:54this game, my sounds memory usage is
  315. 10:56only at about 58 MGB because I don't
  316. 10:59have a bunch of sound instances stored
  317. 11:01in sound service. I have them stored or
  318. 11:04I have their sound IDs stored inside of
  319. 11:06scripts. I create the sounds when I need
  320. 11:08them and then when I don't need them
  321. 11:09anymore then, you know, I that's it. I
  322. 11:12destroy them. When you open this thing
  323. 11:14up too as well, you could also see all
  324. 11:15of the sound instances that are
  325. 11:17currently loaded into memory and how
  326. 11:19much uh memory they take up, which is
  327. 11:21also pretty cool. So, this can help you
  328. 11:22narrow down like, hey, which sounds are
  329. 11:25taking up a lot of memory and figure
  330. 11:26out, do I really need to store this
  331. 11:28sound inside of the sound service or
  332. 11:31inside of some object somewhere? and
  333. 11:34instead can I just create it during
  334. 11:35runtime and then only play it when I
  335. 11:37need it. Along with storing sounds in
  336. 11:39the sound service, you should also make
  337. 11:42determinations of whether you need
  338. 11:44something to be stored in replicated
  339. 11:46storage or if it can be stored inside of
  340. 11:48server storage. A lot of the times there
  341. 11:51are instances or objects that you can
  342. 11:54move out of replicated storage and store
  343. 11:55it in server storage. For example, let's
  344. 11:57say your game has a bunch of maps. Let's
  345. 11:58say you got 10 different maps on your
  346. 12:00game and the server loads different maps
  347. 12:02at different times. Realistically, a
  348. 12:04client doesn't need to have all 10 10 of
  349. 12:06those maps in a folder stored in
  350. 12:08replicated storage because it needs to
  351. 12:10reserve memory to store information
  352. 12:11about all the instances and everything
  353. 12:13in those maps. If those maps are only
  354. 12:15supposed to show up at a certain point
  355. 12:17in your game, then you should probably
  356. 12:18store them in server storage. By storing
  357. 12:20objects inside of server storage, you're
  358. 12:23preventing the clients from having to
  359. 12:25store all that information inside of
  360. 12:27memory along with having to download it
  361. 12:30when they join the game, which can also
  362. 12:32improve your loading times. Another way
  363. 12:34of improving memory usage is by cleaning
  364. 12:36up connections connected to player
  365. 12:39instances and their character models.
  366. 12:41So, inside of the workspace, if we go to
  367. 12:43the properties window, there's going to
  368. 12:45be a property down here called player
  369. 12:47character destroy behavior. You should
  370. 12:49probably have this set to enable. The
  371. 12:52default is default. And I don't know if
  372. 12:54the default is enabled, but you you
  373. 12:56probably just want to make sure this is
  374. 12:57set to enable because the prior behavior
  375. 12:59with players and their character models
  376. 13:01is that when a character model dies or
  377. 13:03the player left the game, their instance
  378. 13:06would only be parented to nil. But the
  379. 13:08destroy function would not be called on
  380. 13:10the character models or the player
  381. 13:12models. So if you had any connections to
  382. 13:15any events to the player or anything
  383. 13:18inside of the character model, stuff
  384. 13:19like that, those connections would sit
  385. 13:21around in memory. And as more and more
  386. 13:23players join the game, leave the game,
  387. 13:25spawn, and respawn, you would have a
  388. 13:27bunch of memory leaks and building up of
  389. 13:29memory in your game till eventually
  390. 13:31maybe your server would crash, and then
  391. 13:33you'd have to get a new server and start
  392. 13:34the process all over again. So it it's
  393. 13:36just a good idea to have this player
  394. 13:38character destroy behavior set to
  395. 13:40enabled. The next area we're going to be
  396. 13:42taking a look at improving is going to
  397. 13:44be this graphics texture category. If
  398. 13:47you have very high memory usage, let's
  399. 13:49say you have like 500 megabytes or more,
  400. 13:51a thousand megabytes, whatever it is for
  401. 13:53graphics texture, you really need to ask
  402. 13:55yourself, do I need those high
  403. 13:57resolution 1,024x 10,024 pixel textures
  404. 14:01on multiple different objects with all
  405. 14:02their own unique textures, or am I able
  406. 14:05to downsize those textures to something
  407. 14:08smaller like 512 x 512 pixels? And can I
  408. 14:12use things like texture atlases? And can
  409. 14:15I use things such as I believe they're
  410. 14:18called, what are they called? Trim
  411. 14:20sheets. Texture trim sheets. There's a
  412. 14:22bunch of little hacky things that people
  413. 14:23can do with textures to be able to reuse
  414. 14:26them across multiple objects and keep
  415. 14:29this memory usage down. So that way
  416. 14:32you're not having to have a bunch of
  417. 14:34client memory usage being wasted because
  418. 14:36you decided to upload super high
  419. 14:38resolution textures. In fact, if we look
  420. 14:40at the documentation, it says a 1,024x
  421. 14:431024 pixel texture consumes four times
  422. 14:48four times the graphics memory of a 512x
  423. 14:52512 texture. Images uploaded to Roblox
  424. 14:55are transcoded to a fixed format. So,
  425. 14:57there's no memory benefit to uploading
  426. 14:58images in a color model associated with
  427. 15:00fewer bytes per pixel. Similarly,
  428. 15:02compressing images prior to upload or
  429. 15:04removing the alpha channel from images
  430. 15:06that don't need it can decrease image
  431. 15:08size on disk but either doesn't improve
  432. 15:10or only minimally improves memory usage.
  433. 15:13So, as I said, if you can downsize your
  434. 15:16or scale down your textures, do it. If
  435. 15:18you can use texture atlases, do it. If
  436. 15:21you can use trim sheets, do it. This
  437. 15:23will help save memory usage in relation
  438. 15:25to the graphics texture category for
  439. 15:29your game. Another incredibly important
  440. 15:31feature inside of the Roblox game engine
  441. 15:34is going to be streaming enabled. Right
  442. 15:36now, I don't have it enabled in this
  443. 15:37game, but when you enable this, this
  444. 15:39allows you to stream in and out objects
  445. 15:42inside of the workspace, which can help
  446. 15:44improve load times and reduce memory
  447. 15:47usage. I'm not going to go into
  448. 15:48everything about streaming enabled. That
  449. 15:51can be a video on its own that will
  450. 15:54probably be like 20 minutes long, so I'm
  451. 15:56not going to go into it. This will
  452. 15:57probably be a future video, but I will
  453. 15:59leave a link in the description to the
  454. 16:01Roblox documentation all about streaming
  455. 16:04enabled. The next area we're going to be
  456. 16:05taking a look at improving performance
  457. 16:07is going to be frame rate. And what's
  458. 16:09the easiest way you could do that? Well,
  459. 16:11the easiest way you could do that is by
  460. 16:13reducing the number of draw calls
  461. 16:15happening every single frame. So, inside
  462. 16:17of Studio, if you opened this statistics
  463. 16:21menu by hitting control shift and I
  464. 16:23believe it is what is F2? Yes, F2.
  465. 16:25Controll Shift F2, you get this menu
  466. 16:28popping open. And what we're interested
  467. 16:30in is this thing down here that says
  468. 16:32draw counts. And the one that we're most
  469. 16:34interested in is going to be this scene
  470. 16:36draw count. So Mr. Chicken Rocket
  471. 16:39recommends that you should have a budget
  472. 16:42of 500 in scene draw counts and about
  473. 16:45500,000 triangles. I'm a little bit
  474. 16:47above that, 590,000 triangles, but I am
  475. 16:49below the 500 draw call count budget. If
  476. 16:54you have this number or this value of
  477. 16:56scene draw counts in the thousands,
  478. 16:59you've got a problem and you need to
  479. 17:00optimize your game to figure out how to
  480. 17:02make sure your draw counts don't go
  481. 17:04above a thousand or 500 or something
  482. 17:06like that. Usually, it's okay to go
  483. 17:08above 500, but 500 is a a good metric to
  484. 17:11hit, especially for mobile devices. Now,
  485. 17:14Roblox did introduce their occlusion
  486. 17:16calling feature. So when you the camera
  487. 17:19blocks objects from view, you're going
  488. 17:21to notice that the scene draw counts
  489. 17:23reduce because I'm not rendering a bunch
  490. 17:25of stuff. Like if I put my camera into a
  491. 17:27wall, you can see that the draw counts
  492. 17:30reduce. And as I, you know, look around
  493. 17:32at other stuff, you can see that they
  494. 17:33increase because I'm having to draw more
  495. 17:35meshes and triangles and things like
  496. 17:37that. But we could actually see this in
  497. 17:39action. Let me see if I can find it's in
  498. 17:42here. Yes, wireframe. Let's go into
  499. 17:45wireframe mode. So here we can see all
  500. 17:47the triangles being rendered. And if I
  501. 17:49look inside of a wall, you're going to
  502. 17:50notice that very few things are being
  503. 17:52rendered except for for some reason
  504. 17:54there's a fountain over there being
  505. 17:56rendered, which is kind of interesting.
  506. 17:58Character NPC models also don't get cold
  507. 18:00by the occlusion coin. And for some
  508. 18:02reason, grass doesn't either, which is
  509. 18:04pretty interesting. Another thing that
  510. 18:06doesn't get cold by occlusion coin are
  511. 18:08particle emitters and beams and I
  512. 18:11believe trails as well. Oh, you can see
  513. 18:12those trails moving and they don't seem
  514. 18:15to be getting cold. And the crazy thing
  515. 18:16about particle emitters and beams is
  516. 18:18that each particle emitter and each beam
  517. 18:21takes one draw call even if they use the
  518. 18:24same texture. Because typically when you
  519. 18:26have a mesh, for example, this light
  520. 18:29post here, because these light posts all
  521. 18:31use the same mesh IDs, they all get
  522. 18:34batched into a single draw call. So,
  523. 18:36even if I were to look at 100 of these
  524. 18:40light poles in a scene, it only takes
  525. 18:42one draw call to draw all of the light
  526. 18:44poles, which is pretty cool.
  527. 18:46Unfortunately, that doesn't happen with
  528. 18:47particle emitters or beams. They don't
  529. 18:49get cold by occlusion coin. So, that
  530. 18:51means you're kind of left to do it
  531. 18:52yourself or suffer the consequences. For
  532. 18:55example, here are some particles and
  533. 18:57here are some beams being rendered on
  534. 19:00screen. Now, I have a system in place,
  535. 19:02my client fidelity service, which I made
  536. 19:04a video on. you could check it out where
  537. 19:07once the camera or the character gets
  538. 19:09far enough away from these beams or
  539. 19:11particle emitters, I call them or I
  540. 19:14disable them so they're not being
  541. 19:15rendered because realistically if let's
  542. 19:18say I'm all the way over here, let me
  543. 19:20teleport all the way over here. There's
  544. 19:22no reason why I should be rendering
  545. 19:23that. And actually, you could notice
  546. 19:24that they disappeared. They're not being
  547. 19:26rendered anymore because I'm too far
  548. 19:27away. I'm too far away to notice or care
  549. 19:30about those beams or particle emitters.
  550. 19:31So, why do I need to render them? So, I
  551. 19:33disable them. I also do the same thing
  552. 19:35for lights in my game as well. You can
  553. 19:37see when I walk away, you can see those
  554. 19:40lights getting disabled and things like
  555. 19:42that. And if I open the settings of my
  556. 19:44game and I disable high graphics
  557. 19:46fidelity, I also disable shadows and
  558. 19:48global shadows, which also helps with
  559. 19:51the shadow draw count. Though the shadow
  560. 19:53draw count is still pretty high because
  561. 19:56if I go to my lighting service, I am in
  562. 19:58the future lighting technology. If you
  563. 20:00set this to shadow map and you disable
  564. 20:03global shadows, you're going to have
  565. 20:05zero draw counts, which is really good
  566. 20:07for mobile players because they don't
  567. 20:09have to waste time rendering shadows.
  568. 20:10And do mobile players really care about
  569. 20:12shadows? I don't know. I think mobile
  570. 20:14players would actually rather care about
  571. 20:16the game being playable instead of it
  572. 20:19running two frames per second. That's
  573. 20:21just my opinion. As you can see over
  574. 20:23there, I have more particle emitters,
  575. 20:25beams, and even some decals over there.
  576. 20:27Slightly transparent decals. And by the
  577. 20:30way, if you have a whole bunch of
  578. 20:32transparent textures overlapping each
  579. 20:34other, that can cause something called
  580. 20:36high transparency overdraw, which is
  581. 20:37also not great for performance. But
  582. 20:39because I'm on low fidelity mode and I
  583. 20:42go and I walk away from these decals,
  584. 20:45eventually boom, they all disappear.
  585. 20:47They get cold. They get disabled. And
  586. 20:49that helps reduce the amount of draw
  587. 20:51counts happening. and also helps disable
  588. 20:53the issue or mitigate the issue with the
  589. 20:56high transparency overdraw with those
  590. 20:59transparent decals because they aren't
  591. 21:01being rendered. Now, usually the culprit
  592. 21:03of a very high draw count is either one
  593. 21:06of two things that I've seen. One is
  594. 21:08that you have way too many unique meshes
  595. 21:10in your game. And for some reason, you
  596. 21:13might have the same meshes but with
  597. 21:16different mesh IDs which are being
  598. 21:19batched into separate draw calls which
  599. 21:21are increasing your draw call count. Or
  600. 21:23you have a bunch of particle meters in
  601. 21:24your game all over the map that are
  602. 21:26enabled that aren't being called and
  603. 21:28they're just being rendered. It's
  604. 21:29probably one of those two things. As an
  605. 21:31example, if you take a look at this
  606. 21:33foliage, I have some dead trees and I
  607. 21:36have some trees with leaves. Now, these
  608. 21:39trees were actually imported as separate
  609. 21:41meshes. So, originally, this mesh right
  610. 21:44here, despite it being the exact same
  611. 21:46mesh as this one, they're both literally
  612. 21:49the exact same, they both had different
  613. 21:51mesh IDs. Their mesh IDs were different.
  614. 21:53And because of that, that means instead
  615. 21:55of these being batched into the same
  616. 21:57draw call, these are being batched into
  617. 21:59two separate draw calls, which isn't
  618. 22:01great. So, I went in and fixed that by
  619. 22:04replacing all of the I think it was the
  620. 22:08dead trees. I replaced all the dead
  621. 22:09trees to have the same mesh ID as the
  622. 22:12alive trees. And that fixed that draw
  623. 22:14call issue. Another example I could give
  624. 22:16you are the shipping containers over
  625. 22:18here. So, if you take a look at these
  626. 22:20shipping containers, not only do we have
  627. 22:22the body of the shipping container, but
  628. 22:24we have four doors. And you know what's
  629. 22:27interesting about these four doors?
  630. 22:29Well, they're all the same mesh except
  631. 22:31for the fact that they have like flipped
  632. 22:33hinges. So, technically, I should only
  633. 22:36need two draw calls. One for the left
  634. 22:38door and one for the right door. But
  635. 22:40because these were imported with all the
  636. 22:42doors on them, each door had its own
  637. 22:44unique mesh ID. So, I needed to fix that
  638. 22:47as well by just reusing the same doors
  639. 22:50over here and then moving them over here
  640. 22:52and flipping them. And that reduced my
  641. 22:55draw calls for the shipping containers
  642. 22:57by 50%. Those are things that you just
  643. 22:59need to watch out for when you're
  644. 23:01importing meshes. Let me give you
  645. 23:03another example. There should be a truck
  646. 23:05around here somewhere. Let me find a
  647. 23:07truck. This guy should have a truck. Why
  648. 23:09is it Where where did the truck go?
  649. 23:11There were trucks here and now they're
  650. 23:12gone, which is actually quite
  651. 23:14interesting. That That's kind of weird.
  652. 23:16Can I find a different truck somewhere?
  653. 23:17I I'm going to have to fix that. Okay,
  654. 23:19here. Look, there's a truck over here.
  655. 23:21If we look at these wheels on the truck,
  656. 23:23right, they're literally the exact same
  657. 23:25mesh. They're just flipped around. And
  658. 23:28then with the rear tires, these these
  659. 23:30are both the exact same meshes. But
  660. 23:32because this truck was imported together
  661. 23:34with all the wheels on them, each wheel
  662. 23:37or each tire has its own unique mesh ID.
  663. 23:40So, if we look at this one, so the mesh
  664. 23:42ID ends in 714. And if we look at this
  665. 23:45one, the mesh ID ends in 505. So, look
  666. 23:49at that. This is something I need to fix
  667. 23:50because these these tires are the exact
  668. 23:53same, but they're being batched into two
  669. 23:55separate draw calls. Not great. The more
  670. 23:57and more meshes you add into the game
  671. 23:59that have these kind of issues, the more
  672. 24:02and more your draw calls will pile up,
  673. 24:04and eventually you're going to have to
  674. 24:06fix it. Another area of frame rate
  675. 24:08optimization you might want to take a
  676. 24:09peek at for your meshes is going to be a
  677. 24:12property called render fidelity. Now
  678. 24:15typically you'll want to have this
  679. 24:17fidelity set to automatic or you can set
  680. 24:20it to performance on certain meshes.
  681. 24:22Though setting it to performance might
  682. 24:24alter the visual look of meshes in some
  683. 24:27cases. So you might need to play around
  684. 24:28with these properties and see if
  685. 24:30performance would work. Otherwise
  686. 24:32automatic should work for most cases.
  687. 24:34Now, if you have a bunch of meshes in
  688. 24:36your game that have their render
  689. 24:37fidelity set to precise for some reason,
  690. 24:40you probably want to set it to
  691. 24:41automatic. Cuz if we go and we search in
  692. 24:44my game, render fidelity equals 2, and
  693. 24:47we check to see if there's any meshes
  694. 24:48with precise. Actually, we do have some
  695. 24:50meshes with precise, which I'll probably
  696. 24:51want to change and disable. Otherwise,
  697. 24:54the default meshes in here that are set
  698. 24:56to precise are probably character
  699. 24:58models. I think it's only character
  700. 25:00models that have the render fidelity set
  701. 25:02to
  702. 25:04precise. But as you can see, there's
  703. 25:06some meshes here in regards to this card
  704. 25:08scanner. So, I want to make sure all of
  705. 25:10these meshes are set to automatic
  706. 25:14instead of precise because if I'm super
  707. 25:16far away, there's no reason for me to be
  708. 25:18precisely rendering the mesh. If we look
  709. 25:20in the Roblox documentation under the
  710. 25:23meshes section, there's a level of
  711. 25:25detail category and it says you can
  712. 25:27dynamically control a mesh's level of
  713. 25:29detail using its enum render fidelity
  714. 25:32property. The default value is
  715. 25:34automatic, meaning the mesh's details
  716. 25:37based on its distance from the camera as
  717. 25:39outlined in the following table. So,
  718. 25:41this is an LOD system for meshes. If
  719. 25:45you're less than 250 studs away from the
  720. 25:47camera, then it renders it in the
  721. 25:48highest fidelity. If you're about 250 to
  722. 25:51500 studs away, then it renders it in
  723. 25:54medium fidelity. And when you're greater
  724. 25:55than 500 studs away, the mesh is
  725. 25:58rendered in the lowest fidelity. And you
  726. 26:00can kind of see how it gets decomposed
  727. 26:03over time as the rendering becomes less
  728. 26:06precise. Probably the amount of
  729. 26:08triangles gets reduced automatically
  730. 26:10through some internal engine operation.
  731. 26:13But just having all of your meshes set
  732. 26:15to automatic should be good for most
  733. 26:17cases. If there's a way for you to set
  734. 26:19the level of detail to or the rendering
  735. 26:21fidelity to performance, push as much
  736. 26:24performance as possible, then you can
  737. 26:26totally do that. However, it says this
  738. 26:28means that the performance will always
  739. 26:31be excellent, but mesh visuals may be
  740. 26:34affected negatively. So, you need to
  741. 26:36kind of experiment with this. Another
  742. 26:38area you can make with performance
  743. 26:40improvements are humanoids. So, if I
  744. 26:43take a look at one of these humanoids,
  745. 26:46this is a static NPC. It doesn't move
  746. 26:48around. He can't move around. He just
  747. 26:49stands there and you talk to the NPC.
  748. 26:52Now, because of this, it doesn't make
  749. 26:54sense for the humanoid to be calculating
  750. 26:56all of its different states because
  751. 26:59humanoids have a bunch of different
  752. 27:00states like running, sitting, falling
  753. 27:03down, getting up, jumping, all that kind
  754. 27:05of stuff. Why does the humanoid need to
  755. 27:07evaluate for all those different states
  756. 27:09when it's a static NPC? So, what's the
  757. 27:11smart thing to do with your static NPCs
  758. 27:13that have humanoids in them? Go over to
  759. 27:15the humanoid properties and disable
  760. 27:18evaluate state machine. By disabling the
  761. 27:21state machine, you are now no longer
  762. 27:23wasting CPU time calculating all the
  763. 27:26stuff for the humanoid. Now, if you do
  764. 27:29need to have your humanoids move around,
  765. 27:31but let's say they only walk around,
  766. 27:33they don't jump, they don't climb, they
  767. 27:35can't fall over, then you can also go
  768. 27:37through and disable certain humanoid
  769. 27:39states. So that way you're not
  770. 27:41calculating those either. By going
  771. 27:43through and disabling certain humanoid
  772. 27:45states that you're never going to use,
  773. 27:46that will also help improve performance
  774. 27:48with your humanoids. Another area of
  775. 27:51performance improvement is when you have
  776. 27:53a lot of moving objects in your game
  777. 27:55that you're updating every single frame.
  778. 27:57So if you look, I have all of these
  779. 27:59spinners spinning in this kind of obby
  780. 28:02area. I've got those spinners. I got
  781. 28:03these shark spinners. They're all
  782. 28:05spinning around. Now, these are actually
  783. 28:07being uh Cframe updated on the client
  784. 28:10side for every single client. And then
  785. 28:12they're all synced together by using a
  786. 28:14timestamp of when the spinner was
  787. 28:16initialized on the server side. So that
  788. 28:18way all the clients have their spinners
  789. 28:20synced up so they look the same across
  790. 28:22clients, but all of these spinners are
  791. 28:25having their C frames updated every
  792. 28:27single frame. Now, if you were to do
  793. 28:29that individually and let's say you had
  794. 28:31hundreds or thousands of these parts in
  795. 28:33your game, that can take up a lot of CPU
  796. 28:36time. So, a way you can fix that is by
  797. 28:38using bulk C frame updates using a
  798. 28:42method in the workspace. If I go down to
  799. 28:44the command bar here, there's a method
  800. 28:46in here called bulk move to moves a
  801. 28:49table of base parts to a table of C
  802. 28:51frames. And by using this method, it
  803. 28:53allows you to update the C frame
  804. 28:55properties of a crap ton of parts really
  805. 28:58quickly. So inside of my code, every
  806. 29:00single heartbeat, I'm running this obby
  807. 29:03spinner update, and I go through all the
  808. 29:05spinners in my game, and I calculate the
  809. 29:08correct C frame. I get this new C frame,
  810. 29:10and then I simply insert it into a parts
  811. 29:13table and a C frames table. And then
  812. 29:16once I've gone through all the spinners
  813. 29:18in my game, then I do a single bulk move
  814. 29:20to update on all the parts with their
  815. 29:23associated C frames. And that's a lot
  816. 29:25faster if I were to instead of doing
  817. 29:28bulk move to I were to go in here. I
  818. 29:30know I'm in testing mode. I can't make
  819. 29:32any changes. If I were to do spinner C
  820. 29:34frame is equal to new C frame and I just
  821. 29:37did that for every single spinner. This
  822. 29:38will actually take longer than instead
  823. 29:41of just doing bulk move to. If we open
  824. 29:43up the microrofrofiler and then I were
  825. 29:45to pause the microprofiler and then let
  826. 29:47me select some random frame in here like
  827. 29:50this one. And then let's find heartbeat.
  828. 29:52There's heartbeat. There's also another
  829. 29:53heartbeat down here. If we go down into
  830. 29:55heartbeat, there's my obby spinner
  831. 29:57update right there. And it's taking
  832. 30:00approximately 36 milliseconds to update
  833. 30:04all of the spinners inside of my obby.
  834. 30:07Not bad. Now, I've got a new idea. Let's
  835. 30:10go ahead and comment this code out.
  836. 30:12Let's comment this code out. Let's
  837. 30:15comment this code out. And instead of
  838. 30:17doing the bulk update, let's just do
  839. 30:19spinner C frame is equal to new C frame.
  840. 30:23And let's see how much of a difference
  841. 30:25that makes to the frame time. So, we'll
  842. 30:27go ahead and pause the micropriiler.
  843. 30:29We'll select the random frame in here
  844. 30:31like this one. And then there we go.
  845. 30:33Here's our obby spinner update. And it
  846. 30:36is now taking49
  847. 30:39milliseconds instead of the.3 something
  848. 30:42milliseconds. You might be thinking that
  849. 30:44wasn't a lot. And that's right because
  850. 30:46there's not that many spinners being
  851. 30:48updated in here. But when you have a
  852. 30:51crap ton of parts that you need to
  853. 30:52update simultaneously, let's say on a
  854. 30:54per frame basis or maybe even just once,
  855. 30:57using bulk move 2 over individually
  856. 31:00setting all the C frames can be a
  857. 31:02gamecher. And let's actually see if we
  858. 31:04can improve the performance further with
  859. 31:06bulk move 2 by specifying a specific
  860. 31:09event mode. So let me uncomment that.
  861. 31:13Uncomment that. Uncomment this. And
  862. 31:16there's a third parameter we could pass
  863. 31:18here called bulk move mode. So we could
  864. 31:20do enum bulk move mode. And instead of
  865. 31:23firing all events, which I believe is
  866. 31:25the default for this function, let's
  867. 31:26just fire C frame changed. And this
  868. 31:28should also hopefully improve bulk move
  869. 31:31to even further. Let's go ahead and
  870. 31:33pause. Let's pick a random frame. And
  871. 31:36then here is our obby spinner update.
  872. 31:37How long did that take? Look at that. It
  873. 31:39took even less time by just firing the C
  874. 31:42frame changed event. 255 milliseconds.
  875. 31:46So we went from 0.49 down to.255
  876. 31:51just by using bulk move to. And when you
  877. 31:53have a lot of objects in your game, that
  878. 31:57about 50% performance improvement can
  879. 31:59really add up. Now, there are a couple
  880. 32:02more properties inside of the workspace
  881. 32:04that you'll likely benefit from
  882. 32:05enabling. So, if we go back into the
  883. 32:07workspace, there's going to be a
  884. 32:09property in here called client animator
  885. 32:12throttling. Make sure you have that
  886. 32:14enabled. Basically, what this property
  887. 32:16does is that the farther away an
  888. 32:19animator instance is away from the
  889. 32:21player's character or camera or
  890. 32:23something like that, it'll update that
  891. 32:25animation at a slower rate. So, it'll
  892. 32:28only do like intermittent updates to the
  893. 32:30animation when it's far away cuz you
  894. 32:31can't really see it. And any animators
  895. 32:33that are nearby to your camera or your
  896. 32:36character will be updated at their
  897. 32:37normal rate. And this can also just help
  898. 32:40boost performance a little bit with
  899. 32:41animators. Another property is going to
  900. 32:43be called physics stepping method. And
  901. 32:47this will be set to default by default.
  902. 32:49If you set it to the adaptive mode, this
  903. 32:51allows the engine to make some decisions
  904. 32:55on how it wants to do some physics
  905. 32:57calculations and it reduces certain
  906. 32:59amount of physics calculations.
  907. 33:01Basically, just improves performance in
  908. 33:03regards to physics. So, you probably
  909. 33:05want to have this set to adaptive. Last
  910. 33:07area of optimization we're going to be
  911. 33:09focusing on is networking. And
  912. 33:12specifically, you're going to be taking
  913. 33:13a look at this incoming or overall
  914. 33:16incoming network data in kilobytes per
  915. 33:18second. Now, a good baseline, as Mr.
  916. 33:21Chicken Rocket noted, is that you want
  917. 33:23to have this value below 50 kilobytes
  918. 33:26per second on a consistent basis. If you
  919. 33:28see that your overall incoming kilobytes
  920. 33:30per second is above 50 kilobytes per
  921. 33:33second, that likely means you have way
  922. 33:35too many assemblies in your game that
  923. 33:37the server is having to replicate. Now,
  924. 33:39an assembly is basically an unanchored
  925. 33:42conglomeration of physics. So, things
  926. 33:44attached together with physics
  927. 33:46constraints like welds that are
  928. 33:48unanchored with some unanchor point or
  929. 33:50you have character models connected
  930. 33:52together with motor 60s or you have
  931. 33:54different physics constraints like
  932. 33:56hinges and things like that. When you
  933. 33:58have tons of those things in your game,
  934. 33:59the high incoming network usage with
  935. 34:02Roblox physics kind of makes it hard to
  936. 34:04work with, especially if you need
  937. 34:05servers valided physics, which hopefully
  938. 34:08maybe Roblox's servers aurora thing
  939. 34:11they're working on in the future might
  940. 34:12fix this problem, but who knows? But you
  941. 34:14need to make decisions on how many
  942. 34:16things you want in your game to be
  943. 34:17unanchored, how many assemblies you have
  944. 34:19in your game that are moving around, and
  945. 34:20any optimizations you can make around
  946. 34:22those assemblies. Like for example, I
  947. 34:24could have totally opted to make all of
  948. 34:26these spinners use physics constraints.
  949. 34:29I could have had like, I don't know,
  950. 34:31hinges or something in here and had like
  951. 34:33forces applied to have these things
  952. 34:35spinning. That would have tanked or not
  953. 34:37tanked, that would have just made my
  954. 34:39overall incoming kilobytes per second
  955. 34:41like crazy with all these spinners. It
  956. 34:43probably be over 100 kilobytes per
  957. 34:44second or something like that. Not good.
  958. 34:47So, when you can figure out ways to not
  959. 34:49use physics, don't use physics. When it
  960. 34:52comes to players character models,
  961. 34:54that's kind of inevitable because
  962. 34:55players need to run around. And when you
  963. 34:56have NPCs in your game or like AI that
  964. 35:00the server controls that get moved
  965. 35:02around, that's kind of another point of
  966. 35:04friction where you got to figure out,
  967. 35:07okay, maybe I need to make my own
  968. 35:09servers replication system to control
  969. 35:13how much data I send over for stuff.
  970. 35:15It's kind of a complex solution.
  971. 35:17Basically, you just want to make sure
  972. 35:18that you reduce the amount of assemblies
  973. 35:20in your game when possible, like with
  974. 35:21the spinner example. Reduce the amount
  975. 35:23of unanchored parts in your game. And
  976. 35:25then, if you're able, you could also use
  977. 35:28IK control instances or inverse
  978. 35:30kinematics to try and offset the issue
  979. 35:34with overall incoming network data. And
  980. 35:36that'll probably be a future video cuz
  981. 35:38there's actually something really
  982. 35:39powerful with inverse kinematics that
  983. 35:41allows you to animate like objects and
  984. 35:45make them look like they are using
  985. 35:46physics or animation or whatever, but it
  986. 35:48has zero impact on the overall incoming
  987. 35:51data, which is really cool. I'll make a
  988. 35:53future video on it. I promise.
  989. 35:54Otherwise, another point that you have
  990. 35:56with controlling how much overall
  991. 35:58incoming data there is is your remote
  992. 36:00events. So let's say you have something
  993. 36:02very frequently happening in your game
  994. 36:04where you need to constantly send out
  995. 36:05data to players. Maybe you can serialize
  996. 36:08that with buffers. I have an entire
  997. 36:10video about buffers and one of the main
  998. 36:12utilizations of buffers is for your own
  999. 36:14replication systems for compressing down
  1000. 36:16data. In fact, there's this really
  1001. 36:18awesome dev forum post that talks about
  1002. 36:21how these developers reduced bandwidth
  1003. 36:24usage by 60 times in their game. Cuz
  1004. 36:27originally their overall bandwidth usage
  1005. 36:29on the incoming was 300 to 350 kilobytes
  1006. 36:33per second. Not good. And the reason why
  1007. 36:36is because they had a bunch of parts on
  1008. 36:38the server that were moving around and
  1009. 36:40humanoids. And because there's so many
  1010. 36:43of those parts moving around as
  1011. 36:45assemblies that just takes up so much
  1012. 36:48overall bandwidth usage, which is why
  1013. 36:50they had over 300 kilobytes per second.
  1014. 36:52And eventually they came to a point
  1015. 36:54where they decided, hey, we can't do any
  1016. 36:56of this stuff on the server. The server
  1017. 36:57just needs to store positional stuff.
  1018. 36:59And then the clients have to control the
  1019. 37:01visualization of things and linearly
  1020. 37:03interpolate the NPCs and stuff like
  1021. 37:05that. It's a lot of work to fix this
  1022. 37:08kind of replication or bandwidth usage.
  1023. 37:10And it's unfortunately something I'm
  1024. 37:12going to have to do here pretty soon
  1025. 37:14with a system I need to make. kind of
  1026. 37:16sucks that you have to do it this way,
  1027. 37:18but Roblox does provide the tools with
  1028. 37:20buffers and things like that to be able
  1029. 37:22to actually code a system like this and
  1030. 37:24bring your overall bandwidth usage down
  1031. 37:26from 310 to 4.8 to 5.2, which is crazy.
  1032. 37:30Otherwise, a couple other simple ways to
  1033. 37:32avoid having very high overall incoming
  1034. 37:35data is one, don't tween on the server.
  1035. 37:38Never tween on the server. Don't do
  1036. 37:40that. Number two, don't play animations
  1037. 37:42on the server side. If you need to play
  1038. 37:44animations, have the clients play the
  1039. 37:46animations. Tell the clients through
  1040. 37:48remote event or something, hey, I want
  1041. 37:49you to play an animation on this guy and
  1042. 37:51have the clients do it. Because
  1043. 37:52otherwise, if you play twins on the
  1044. 37:54server or you play animations on the
  1045. 37:56server, all of that data has to get
  1046. 37:58replicated to the clients. And that will
  1047. 38:00boost up your overall incoming kilobytes
  1048. 38:02per second. Along with that, making a
  1049. 38:04bunch of C frame updates on the server
  1050. 38:06also impacts the overall incoming data
  1051. 38:09as well. Because for example, with these
  1052. 38:10spinners I've got here, I could have
  1053. 38:12totally simulated the C frame updates
  1054. 38:14for these spinners on the server side.
  1055. 38:17And you know what that would have meant
  1056. 38:18for my overall incoming data? It would
  1057. 38:20have meant disaster because that would
  1058. 38:22be so many C frame updates needing to be
  1059. 38:25sent to all the players in the game when
  1060. 38:27I could just have the players simulate
  1061. 38:30the spinners on the client side instead.
  1062. 38:32Now, there's a whole bunch more stuff I
  1063. 38:34could talk about in regards to
  1064. 38:36performance, but that would make this
  1065. 38:37video way too stinking long. So,
  1066. 38:40instead, I'm going to leave a whole
  1067. 38:41bunch of resources in the description,
  1068. 38:43such as these articles, dev forum posts,
  1069. 38:45dev forum post to Mr. Chicken Rockets
  1070. 38:47post, stuff like that. So, you can go
  1071. 38:48ahead and take a look and read through
  1072. 38:50them and see if there's anything that
  1073. 38:52can be of use to you to improve the
  1074. 38:54performance issues in your games.
  1075. 38:57Otherwise, thank you for watching and I
  1076. 38:59will see you in the next

About this transcript

This page contains the full transcript of Your Roblox Game LAGS (and how to fix it) by Crusherfire, generated from the public captions YouTube serves with the video. The transcript has 7,501 words across 1,076 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.