How PRO Devs Set Up Roblox Games — Transcript
Full transcript
- 0:00Roblox projects fall apart as they grow,
- 0:02not because of bad code, but because of
- 0:03that structure. This video breaks down
- 0:05how professional developers set up their
- 0:07games with organized folders, modular
- 0:09services, scalable UI, and essential
- 0:11packages. This isn't just for big teams.
- 0:13This is the exact structure that I use,
- 0:15and I'm going to walk you through it
- 0:16step by step. Advanced tooling like VS
- 0:18Code and Rojo aren't required, but if
- 0:20you want to dive deeper into tooling,
- 0:22you should check out my previous
- 0:23tutorial video.
- 0:25Let's break down the structure behind
- 0:26the professional-grade Roblox game. Game
- 0:29logic should be broken into services.
- 0:32Each service owns a slice of your game
- 0:33and manages related data and systems.
- 0:36For example, build service would handle
- 0:38placement of parts, while enemy service
- 0:40controls enemy spawning and tracking.
- 0:43Although not always required, each
- 0:45service is typically split into client
- 0:46and server versions with shared
- 0:48functionality or data placed in a
- 0:50utility module.
- 0:52This keeps your logic organized, makes
- 0:54debugging easier, and helps your game
- 0:56scale cleanly as it grows.
- 1:00So, what does this actually look like in
- 1:02Studio? First, we're going to create a
- 1:04shared folder. This will house our
- 1:06shared and client game logic. Inside of
- 1:08shared, create a services folder. Each
- 1:11service will have a dedicated folder
- 1:13assigned to it for easy scalability. In
- 1:15this example, I will create a build
- 1:17service. The client version of each
- 1:19service will live here along with any
- 1:20needed shared utility scripts. We must
- 1:23place the server versions of each
- 1:25service under server script service in
- 1:27order to prevent exploiters from
- 1:29downloading sensitive server code.
- 1:33Our build services hierarchy setup is
- 1:36now complete.
- 1:38Here's an example with multiple
- 1:39services. Like I mentioned earlier, some
- 1:42services don't need client and server
- 1:44versions as you can see with part
- 1:45service here.
- 1:48Ideally, all related code would live
- 1:50together for easy access and navigation.
- 1:52However, the server code must stay
- 1:54within non-replicated containers as
- 1:56mentioned earlier. To remedy this, I
- 1:58created a VS Code tool that
- 2:00automatically maps scripts to their
- 2:01correct container while allowing
- 2:03everything to live together. This tool
- 2:04is available on my GitHub link in the
- 2:06description.
- 2:11Each service is a singleton. We only
- 2:13ever have one build service, one
- 2:15inventory service and so on. That means
- 2:17no new constructor. The module itself is
- 2:20the instance. Most services have an
- 2:22initialize function in it. Here any
- 2:25needed objects can be created or
- 2:27non-yielding startup code can be
- 2:28executed.
- 2:30In this example, we're inside build
- 2:32service client. So the singleton table
- 2:34is named exactly that. Always keep
- 2:37service names explicit to maintain
- 2:38readability.
- 2:40in it creates a model called parts and
- 2:43stores it on the service.
- 2:46The service then exposes the build
- 2:48function. It spawns a part, sets it
- 2:50frame to the pass in parameter and
- 2:52parents it under self.parts.
- 2:57By default, the current Luau type
- 2:59checker struggles to understand the true
- 3:00type of self. In order to fix this, we
- 3:03need to ditch the colon operator and
- 3:05pass self in as the first parameter with
- 3:07our defined type.
- 3:18Member variables can be defined by
- 3:20unionuning a table of our defined
- 3:22variables to the type.
- 3:25Additionally, type cast the return
- 3:27service for proper IntelliSense when
- 3:29used in another script.
- 3:33Now let's use the service we just
- 3:35created. Create a client script inside
- 3:38of starter player scripts and name it
- 3:39client.
- 3:41This contains basic startup logic for
- 3:44our client sided services.
- 3:47For demonstration purposes, I'll use the
- 3:49build function here.
- 3:54Typically, startup scripts will simply
- 3:56initialize all of our services. If order
- 3:59matters or the init function takes any
- 4:01parameters, you can initialize each
- 4:03service manually. Otherwise create a
- 4:06simple loop that calls in it on a
- 4:08recognized services.
- 4:12In order for client and server
- 4:14communication to be possible, we must
- 4:15use remote events and functions.
- 4:18Remote instances should not be created
- 4:20manually. Manual creation leads to messy
- 4:23hierarchy trees, dependency on names,
- 4:25and hard to manage version diffs.
- 4:28Instead, create remotes through code. A
- 4:30simple remote event wrapper can be
- 4:32created in less than 50 lines of code
- 4:33and solves all of these issues. There
- 4:36are plenty of open source solutions such
- 4:37as Biteet, Blink, or Zap. I personally
- 4:40created my own networking solution that
- 4:41I use in all of my games, and I'll be
- 4:43using it for the example shown. Whatever
- 4:46networking library you use or create
- 4:48should be placed into a new folder
- 4:50called packages. Packages are reusable
- 4:52scripts that are not reliant on any
- 4:54specific game logic, meaning they can
- 4:56easily be dropped into any project. If
- 4:58you are using VS Code, I recommend using
- 5:00the Wall-E package manager as I
- 5:02mentioned in my previous tutorial video.
- 5:08Start by mirroring the service setup on
- 5:10the server.
- 5:17Inside of the initialize function,
- 5:18create any needed networking solutions.
- 5:22My networker library is designed for
- 5:24easy communication between either side
- 5:25of the network. Simply create the client
- 5:28and server versions of the networker,
- 5:30define any functions the client has
- 5:31access to call, and use the built-in
- 5:33methods to communicate.
- 5:39I'm not going to go in depth into my
- 5:41specific networking solution as it could
- 5:43vary from yours. If you're interested in
- 5:45mine, there are docs on the GitHub
- 5:46repository in the description.
- 5:50Instead of clients telling the server
- 5:52directly, I built a part here, it should
- 5:54ask, can I build here? The server would
- 5:56then validate the request and
- 5:58potentially send some response if
- 6:00needed.
- 6:01In this example, the client calls the
- 6:03serverowned attempt build function
- 6:05within its build method. In this case,
- 6:08the attempt build validates by creating
- 6:10a 5-second cool down between builds.
- 6:14Don't forget the server startup script
- 6:16inside of server script service.
- 6:22In order to modulize reusable game
- 6:24logic, most professional developers
- 6:26utilize object-oriented programming to
- 6:28create classes. Similarly to the service
- 6:31structure, create dedicated class
- 6:33folders under shared and server script
- 6:35service. This video will not be teaching
- 6:38object-oriented programming. So if
- 6:39you're unfamiliar with this paradigm, I
- 6:41recommend doing some research on your
- 6:42own.
- 6:44Leave a comment if you'd be interested
- 6:45in a separate video covering
- 6:47object-oriented programming in depth.
- 6:50In this example, I will create a spike
- 6:52class.
- 6:53Now, instead of build service creating a
- 6:55new part, it will create a new spike
- 6:57object instead.
- 7:03When a player touches a spike, they'll
- 7:05now be damaged.
- 7:07Custom models, VFX, and other instances
- 7:10should be placed inside of an assets
- 7:11folder under replicated storage. For
- 7:14example, my spike class will now use
- 7:16this custom spike mesh instead of a
- 7:17basic part.
- 7:24For the sake of example and to make
- 7:26things more interesting, I've hooked up
- 7:28the clients build function to call
- 7:30attempt build whenever the mouse is
- 7:31clicked. I initialize this behavior
- 7:33within the init function.
- 7:38Modules provide shared functionality,
- 7:41data or utilities that other scripts can
- 7:43depend on. Follow the same shared versus
- 7:45server rules from before, creating their
- 7:47respective folders.
- 7:50I take module organization a step
- 7:52further by grouping them into clear
- 7:53categories like core, game, math, and
- 7:56platform. This way, it's immediately
- 7:58obvious where any script belongs and
- 8:00where someone should look to find it.
- 8:02Keep modules small and focused. Math
- 8:04helpers, reusable functions, pure data
- 8:06tables, and so on.
- 8:10User interface is one of the easiest
- 8:12places for projects to get messy.
- 8:14Professional teams prevent this by
- 8:15keeping UI modular and scalable.
- 8:18Many developers use declarative UI
- 8:20frameworks for this. React, Fusion, and
- 8:22VID are the main options. I currently
- 8:25use React and I've shipped production
- 8:26games with Fusion as well. With that
- 8:29said, I know many Roblox developers
- 8:31aren't ready to dive into declarative
- 8:32workflow, but here's a middle ground
- 8:34that I recommend. Place all interface
- 8:36code under a tople UI module in
- 8:39replicated storage. This module acts as
- 8:41the UI initializer. Inside, create
- 8:44folders for interface types such as
- 8:45menus or HUD.
- 8:48In this example, I have a left sidebar
- 8:50HUD element and an inventory menu.
- 8:54Each feature gets its own module script
- 8:56that exposes its functionality and an
- 8:58init function if needed.
- 9:06Just like services, the top level UI
- 9:08script should initialize these features.
- 9:15Finally, make sure the UI initializer is
- 9:18called inside your client startup
- 9:19script.
- 9:23This approach keeps the familiar Roblox
- 9:25workflow while still giving you scalable
- 9:27modular UI design.
- 9:32As mentioned earlier, packages are
- 9:33reusable scripts that aren't tied to any
- 9:35specific game logic, which means they
- 9:37can be dropped into any project.
- 9:40Professional developers rely on them to
- 9:41avoid reinventing the wheel and to keep
- 9:43their code base clean. Here are a few
- 9:45core packages that I personally use
- 9:47across all of my projects. Signal, a
- 9:50pure code replacement for bindable
- 9:51events, more efficient, easier to work
- 9:53with, and hands down the one package I
- 9:55wouldn't want to develop without. Charm,
- 9:58an atomic state manager that pairs
- 10:00perfectly with declarative UI
- 10:01frameworks.
- 10:04Sift, a comprehensive table utility
- 10:07library packed with useful functions.
- 10:13Data service, a full persistent data
- 10:16solution with automatic client
- 10:17replication and observable values.
- 10:23Janitor, a lightweight cleanup module
- 10:26that makes managing connections and
- 10:27instances painless.
- 10:32These packages keep your projects
- 10:34modular, predictable, and ready to
- 10:36scale. Like I mentioned earlier, I
- 10:38manage all of these through Wall-E for
- 10:39versioning and easy updates.
- 10:43This is how professionals structure
- 10:44Roblox projects. Services for game
- 10:47logic, clear modules, scalable UI, and
- 10:49reusable packages. Together, they keep
- 10:52projects clean and scalable. Your exact
- 10:54setup may differ slightly, but the
- 10:56principle is the same. Organize early to
- 10:58avoid chaos later. Check the description
- 11:00for relevant links, and drop a comment
- 11:02below the like button if you'd like a
- 11:04deep dive on topics like object-oriented
- 11:06programming or networking.
About this transcript
This page contains the full transcript of How PRO Devs Set Up Roblox Games by Leif, generated from the public captions YouTube serves with the video. The transcript has 1,607 words across 283 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.