Skip to main content

Architecture

Everything works best when using a multi-script architecture. This means there is no centralized framework, and instead code is just modularized and loaded normally. Multiple scripts are allowed on the client and server (just don't be excessive), but they must be in their respective structure folders.

All script, asset, config, and other file names are in pacal case (PascalCase) capitalization.

info

Avoiding a central framework allows for easy onboarding and non-strict development, which decreases hiring costs. Central frameworks tend to overcomplicate codebases, often leading to memory, typechecking, and design problems.

If you want to learn more about our rationale for not using SSA or central frameworks, read here.

File Structure

Here is the recommended file structure for code:

.
└── Project/
├── ReplicatedFirst/
│ └── Modules
├── ServerScriptService/
│ ├── Scripts
│ ├── SharedModules
│ └── ServerData
├── ReplicatedStorage/
│ ├── Modules/
│ │ └── Packages
│ └── Data
└── StarterPlayer/
└── StarterPlayerScripts/
└── Scripts

And this is how other instances should be structured:

.
└── Project/
├── ReplicatedStorage/
│ ├── Assets
│ └── Remotes
└── ServerStorage/
└── ServerAssets

Which results in this final combined structure:

.
└── Project/
├── ReplicatedFirst/
│ └── Modules
├── ServerScriptService/
│ ├── Scripts
│ ├── Modules
│ └── ServerData
├── ReplicatedStorage/
│ ├── SharedModules/
│ │ └── Packages
│ ├── Data
│ ├── Assets
│ └── Remotes
├── StarterPlayer/
│ └── StarterPlayerScripts/
│ └── Scripts
└── ServerStorage/
└── ServerAssets

ReplicatedFirst

Any client-specific modules should go under Modules under ReplicatedFirst. An example of a client-specific module would be an interface component.

StarterPlayerScripts

Any local scripts should go under Scripts inside of StarterPlayerScripts.

ServerScriptService

Any server scripts should go under Scripts under ServerScriptService, and any server-specific modules should go under Modules. An example of a server-specific module would be a datastore wrapper. Server-only config/constant data should go under the ServerData folder.

ReplicatedStorage

Store any common/shared modules in SharedModules (for example, utility modules). Packages is a folder of packages imported by a package manager, such as Wally (and belongs under Modules). Data is a folder used to store modules or other data that is constant (for example, game config). Assets is used to store non-code instances that is used by client or server. Remotes is exclusively for remote events and remote functions.

info

Remotes can either be a folder of remote instances or a module representing remotes from a networking module.

ServerStorage

Store any server-specific assets in ServerAssets. For example, you would store maps here.

Modularization

Modularization is important to make sure that functionality is divided into isolated scopes, either through functions or modules. This makes it easy for team members to navigate a codebase and understand what something does at a glance, but more importantly, it makes it easy to scale.

Functions should be reserved for splitting functionality that is part of a larger picture in a script or module. For example, a weapon might have functions to shoot, reload, etc.

Modules are used to separate bigger things to create libraries, databases, and systems. Some examples of things that are their own modules include:

  • Configurations
  • Utilities
  • Systems
  • Frameworks
  • Classes
  • Etc

Variable modularization is the smallest level of splitting up information into something more digestible. This is something you should eyeball, with the general rule of thumb being "if it's readable, it's good”. Make sure to utilize variables for repeated information.