How to Create a Game Framework

Hello! I’m scripting1st, and today I’ll be teaching you about game Frameworks, how they are used, and how to create a framework.

Note: Most of the functions I will mention will be from AeroGameFramework.

#CHAPTER I: How they are used, their functions, and the framework’s format (Highly debatable, so you can choose the format of your own framework.)

You can see a game framework as a way to organize your game, and to make things simpler. Frameworks usually initialize their modules so that they can have access to the Framework’s Children(Functions, Values, etc). Framework just make programming much easier.

Functions For my Framework (will get into how I write them later)

Initialize: Stated above

ConnectEvent: Connecting Function to Event. The parameters are the function and the name of the Event: (func, name). These are made by the server, and run in the client. They DO NOT create Remote Events, instead they look for them in ReplicatedStorage.

ConnectClientEvent: Self Explanatory. These are made by the client, and run in the server. Cannot Create RemoteEvents.

RegisterEvent: Creates a new RemoteEvent. This has to be called on the server. Parameters: (name)

RegisterFunction: Looks at all functions under “Client” table. We’ll go into that a tiny bit later. After it checks all functions, it creates the RemoteFunction, adding the function onto OnServerInvoke. This is run by the server.

RegisterClientEvent: Same as RegisterFunction, all functions under “Server” Table.

Fire Functions: Three different functions, Fire, FireClient, and FireAllClients. Will go over that later in the post as well.


Ahh, the most debatable topic in this tutorial. Many people have their own ways of doing things, so for the sake of this post I’ll list a couple people who have posted their own formats.


Chapter II: Initialize

For Initialize, It is not that hard. There are two types of them though. New, and Initialize. “New” runs on the module script, but requires you to to a require on the Framework to run it. I’ll give an example of the New Function.

New Framework:

function Framework:New(Table, __type, Name)
	self[Name] = setmetatable(Table, CFramework)
	self[Name].Type = __type

	return self[Name]

Now it’s time for initialize. I’ve improved on this version, so it’s a tiny bit different.

function Framework:Initalize(module)
	local org = require(module) 

	local tab = setmetatable(org, self)
	local _type = self[module.Parent.Name] 

	_type[module.Name] = org

	org._type = module.Parent.Name
	return org 

Basically, “new” is supposed to create a new table that you are able to make functions with and access the Framework. On the contrary, “initialize” is supposed to be used at the end of your module script, or in a server script.


-- Module
local Framework = require("framework blah blah")
local Table = Framework:New({}, "Class", "Table")
Table.__index = Table

local self = setmetatable({}, Table)
print("You studied this yay", self.ValueFromFramework)

return Table

--- Server
local ModuleScript = require("module blah blah")

Example 2:

-- ModuleScript
local Module = {}
Module._type = "Class"
Module.__index = Module

local self = setmetatable({}, Module)

return Module

-- Server
local Framework = require("framework blah")
local module = game.serverScripts:FindFirstChild("module")

local  Mod = Framework:Initalize(Framework)

Chapter III: Functions Involving Remotes.

Note: I’ll only be explaining server functions, because Client Functions are pretty indifferent, and you could search up the client parameters on roblox. If you try and struggle enough, ask questions for small errors, you will be able to recreate these functions. I have a book more to learn too.

ConnectEvent Func: ConnectEvent has two parameters, as you already know. func, and Name. For func, you must have to sub parameters (as you may call it), which is (player, …) the … signifies that you could add as much parameters as you want, so you can add anything you please.

This is what the function consists of;

function Framework:ConnectEvent(func, name)
	local RemoteEvent = Remotes:FindFirstChild(name)

	if RemoteEvent then

And this is how you use it in most cases:

local Service = {}

function Service:Test()
     self:ConnectEvent(function(player, ...)

end, "SayHi")

function Service:Pre()
-- we'll get to register event


-- Client

local clientthing = {}

clientthing:Fire("SayHi", ...)

RegisterEvent basically creates a new RemoteEvent to the server, allowing the Server to use that specific RemoteEvent. Only 1 parameter, and that is, (name). The name of the RemoteEvent is determined by the parameter.

RegisterFunction is similar to RegisterEvent, except that it turns functions from a certain table, called ‘client’, which is supposed to be the table returned in the function.

Here is an example, of course.

local module = {Client = {}}

function module.Client.Test(player, ...)

function module:Init()


local module = {}

function module:Start()
self:Fire("Test"), ---  Should print player.Name from the Client.


The final thing we will be talking about in this post is the “Fire” function. It’s pretty obvious that it fires the event, and that the first parameter is the name of the event/function. However, there is a … next to the name parameter, signifying that the arguments next to player we could’ve added into the second, third, or 50,000th parameter. An example of this is above, of course.

function Framework:Fire(name, ...)
	local Remote = Remotes:FindFirstChild(name)
	if Remote then

	if Remote.ClassName == "RemoteEvent" then
	elseif Remote.ClassName == "RemoteFunction" then


Chapter 4: Sub Tables
Anyways, this version is running on Initalize, but you could always change it if you want. This is how I made my sub tables.
Only Controllers and Services are actually run into the server, and Class/Module serves as a module for the Controller/Service.

local CEngine = {
	Class = {
	Service = {
	Controller = {
	Module = {
	Other = {

If you aren’t aware, what’s happening is that I’m initalizing all Modules that are in a certain Parent, such as ReplicatedStorage.Shared, or ServerStorage. After this is done (basically all the modules are done loading and have all of the original Framework’s functions), I do a in pairs loop for the framework itself, looking for tables, and if I have found a table (has to be one of those 5 types of my framework), I do another in pairs loop to then, do a module:Init() first, and then a module:Start(), starting each module extremely fast.

Good things to know:

RunService.HeartBeat:Wait() is actually much faster than wait() suggest you use RunService Wait instead of wait(). By the way, RunService.Stepped:Wait() works too of course. Anyways, this is the most basic tutorial in my opinion, and this tutorial is more or so a guide on what to do. I highly suggest you try to create your own methods.

Anyways, thank you for reading my tutorial, goodbye.

Also, if you catch any mistakes or inconsistencies please point it out.

Edit: forgot to mention that you are able to access any service from the Framework, the modules are actually put inside the sub tables as soon as they are Initialized (in the Initialized version only, though)

Below is a poll. Highly suggest you to fill it out, and also give me feedback. Thanks.

glitch accidentally occured with polls. as of today the average is 4.

Rate This Tutorial
  • 1
  • 2
  • 3
  • 4
  • 5

0 voters


If you just want the framework, this is a near copy of the AeroGameFramework.
Here’s the link:


Just to mention a few small things of course. The reason why this is a tutorial is because of the different ways people format their code, and the methods they use for their framework. In all honesty, if you just want to start coding using a pre-made framework, then thats more than alright. Though, I hope that you did learn something from this tutorial.


I sure did learn a few things from this. It was actually more towards how your framework is setup. I’ve created a few and this has helped a bit. Appreciate the time you took to post this. Thanks!


Got to admit, this is a good tutorial however: there are a lot of things that could need rewriting.

One of the things is the RegisterFunction section, where if you actually use the code, it won’t work in the slightest.