Global Framework
Download Plugin | Download Library | Video Tutorial | Discord Server
Features
Global Types "Access types from all other scripts"
Global Variables "Access variables from all other scripts"
Strict Mode "--!strict"
Circler Dependencies "Circler types + circler variables"
Inheritance "Inherit via 2 modes [Clone, Metatable]"
Automatic inherit dependency sorting "No mater what order your scripts run in"
Automatic generic dependency sorting "Global generic types will be listed in the correct order"
Diagnostics "Warnings if you define the same type or variable"
Comments Within Comments "O_O"
Metatable Shortcut "Metatable types are very easy to type"
Style Flexibility "Does not enforce a specific style of writing code"
Modular "Only use parts of the global library you want"
Customizable "Very easy to add/modify/remove framework functions"
Support My Work
If you liked my work and want to donate to me you can do so here
SourceCode
You can get the sourcecode to this plugin/module herePermission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
Quick Start
Step 1
"Make a ModuleScript and give it a attribute called GlobalTypes and set it to true"

Step 2
"Make a Script and require the ModuleScript we just made"

Step 3
"Make a type and block comment it out using --[[type]]"

Step 4
"Add a value into Global and set its type"

Done
"Congratulations you now have a global value that you can access in other scripts"

CLASS WITH METATABLE EXAMPLE
--!strict
--[[type MyGlobalClassType = {
__index: MyGlobalClassType,
new: (name: string, age: number) -> MyGlobalObjectType,
SetName: (self: MyGlobalObjectType, name: string) -> (),
SetAge: (self: MyGlobalObjectType, age: number) -> (),
}]]
--[[type MyGlobalObjectType = {
Name: string,
Age: number,
} MyGlobalClassType]]
local Global = require(game.PathTo.ModuleScript)
local class = Global("MyGlobalIndex") :: Global.MyGlobalClassType
class.__index = class
function class.new(name, age)
local self = setmetatable({}, class)
self.Name = name
self.Age = age
return self
end
function class:SetName(name)
self.Name = name
end
function class:SetAge(age)
self.Age = age
end
CLASS WITHOUT METATABLE EXAMPLE
--!strict
--[[type MyGlobalObjectType = {
Name: string,
Age: number,
new: (name: string, age: number) -> MyGlobalObjectType ,
SetName: (self: MyGlobalObjectType, name: string) -> (),
SetAge: (self: MyGlobalObjectType, age: number) -> (),
}]]
local Global = require(game.PathTo.ModuleScript)
local class = Global("MyGlobalIndex", Global.Metatable()) :: Global.MyGlobalObjectType
function class.new(name, age)
local self = Global.Metatable(class) :: Global.MyGlobalObjectType
self.Name = name
self.Age = age
return self
end
function class:SetName(name)
self.Name = name
end
function class:SetAge(age)
self.Age = age
end
CLASS WITHOUT NEW EXAMPLE
--!strict
--[[type MyGlobalObjectType = {
Name: string,
Age: number,
SetName: (self: MyGlobalObjectType, name: string) -> (),
SetAge: (self: MyGlobalObjectType, age: number) -> (),
}]]
local Global = require(game.PathTo.ModuleScript)
local class = Global.Metatable() :: Global.MyGlobalObjectType
Global("MyGlobalIndex", function(name, age)
local self = Global.Metatable(class) :: Global.MyGlobalObjectType
self.Name = name
self.Age = age
return self
end :: (name: string, age: number) -> Global.MyGlobalObjectType)
function class:SetName(name)
self.Name = name
end
function class:SetAge(age)
self.Age = age
end
Alternative Modules
Wait replaces Initialize with Wait
local exports:any, link:any, threads:any, completed:any, waitingIndex:any, waitingStart:any = {}, {}, {}, {}, {}, {}
link.Previous, link.Next = link, link
local function Register(thread: thread)
local threadData = threads[thread]
if threadData then return threadData end
local threadData = {Thread = thread, Indices = {}, Previous = link.Previous, Next = link}
link.Previous.Next, link.Previous, threads[thread] = threadData, threadData, threadData
return threadData
end
local function End(thread: thread)
local threadData = threads[thread]
if threadData == nil then return end
for index in threadData.Indices do
completed[index] = true
if waitingIndex[index] then
for thread in waitingIndex[index] do task.spawn(thread) end
waitingIndex[index] = nil
end
end
threadData.Previous.Next, threadData.Next.Previous, threads[thread] = threadData.Next, threadData.Previous, nil
end
local function WaitIndex(index: any)
if waitingIndex == nil then return end
if completed[index] then return end
local thread = coroutine.running()
if waitingIndex[index] then waitingIndex[index][thread] = true else waitingIndex[index] = {[thread] = true} end
local threadData = threads[thread]
if threadData then threadData.Previous.Next, threadData.Next.Previous = threadData.Next, threadData.Previous end
coroutine.yield()
if threadData then threadData.Previous, threadData.Next, link.Previous.Next, link.Previous = link.Previous, link, threadData, threadData end
waitingIndex[index][thread] = nil
end
local metatable = {
__call = function(globals: any, index: any, value: any)
if threads then Register(coroutine.running()).Indices[index] = true end
if value == nil then value = {} end
globals[index] = value
return value
end,
__index = {
Wait = function(...: global_indices)
for index, waitingIndex in {...} do WaitIndex(waitingIndex) end
end,
Start = function(func: () -> ()?)
if func then
if waitingStart then table.insert(waitingStart, func) else task.defer(func) end
elseif waitingStart then
local thread = coroutine.running()
End(thread)
table.insert(waitingStart, thread)
coroutine.yield()
end
end,
Export = function(index: any, value: any)
if threads then Register(coroutine.running()).Indices[index] = true end
exports[index] = value
end,
Inherit = function(index: global_indices, destination: any, mode: ("Metatable" | "Clone")?, ...)
WaitIndex(index)
local source = exports[index] or globals[index]
if source then
if mode == "Clone" then
local indices = {...}
if #indices == 0 then
for index, value in source do if destination[index] == nil then destination[index] = value end end
else
for index, value in indices do if destination[value] == nil then destination[value] = source[value] end end
end
else
setmetatable(destination, source)
end
else
local path, line = debug.info(coroutine.running(), 2, "sl")
warn(string.format("%s:%d: Failed to inherit: %s, index not found", path, line, index))
end
end,
Metatable = function(table1: any, table2: any)
if table1 then
return if table2 then setmetatable(table1, table2) else setmetatable({}, table1)
else
table1 = {} table1.__index = table1
return table1
end
end,
},
}
task.defer(function()
local threadData = link.Next
while true do
if link == threadData then
if link.Next == link then break else task.wait() end
elseif coroutine.status(threadData.Thread) == "dead" then
End(threadData.Thread)
end
threadData = threadData.Next
end
for index, threads in waitingIndex do
for thread in threads do
local path, line = debug.info(thread, 3, "sl")
warn(string.format("%s:%d: Infinite yield for index: %s", path, line, index))
end
end
for index, functionOrThread in waitingStart do task.defer(functionOrThread) end
link, threads, completed, waitingIndex, waitingStart = nil, nil, nil, nil, nil
end)
return setmetatable(globals, metatable)
Initialize default
local threads, initializeThreads, initializes, starts, exports, inheritances = {} :: any, {} :: any, {} :: any, {} :: any, {} :: any, {} :: any
local metatable = {
__call = function(globals: any, index: any, value: any)
if threads then threads[coroutine.running()] = true end
if value == nil then value = {} end
globals[index] = value
return value
end,
__index = {
Initialize = function(func: () -> ()?)
if func then
if initializes then table.insert(initializes, func) else task.defer(func) end
elseif initializes then
local thread = coroutine.running()
if threads then threads[thread] = nil end
table.insert(initializes, thread)
coroutine.yield()
end
end,
Start = function(func: () -> ()?)
if func then
if starts then table.insert(starts, func) else task.defer(func) end
elseif starts then
local thread = coroutine.running()
if threads then threads[thread] = nil end
if initializeThreads then initializeThreads[thread] = nil end
table.insert(starts, thread)
coroutine.yield()
end
end,
Export = function(index: any, value: any)
exports[index] = value
end,
Inherit = function(index: global_indices, destination: any, mode: ("Metatable" | "Clone")?, ...)
if inheritances then
local inheritance = inheritances[destination]
if inheritance == nil then inheritance = {} inheritances[destination] = inheritance end
table.insert(inheritance, {index, mode, {...}} :: {any})
else
local source = exports[index] or globals[index]
if source then
if mode == "Clone" then
local indices = {...}
if #indices == 0 then
for index, value in source do if destination[index] == nil then destination[index] = value end end
else
for index, value in indices do if destination[value] == nil then destination[value] = source[value] end end
end
else
setmetatable(destination, source)
end
else
warn(`Failed to inherit '{index}', index not found`)
end
end
end,
Metatable = function(table1: any, table2: any)
if table1 then
return if table2 then setmetatable(table1, table2) else setmetatable({}, table1)
else
table1 = {} table1.__index = table1
return table1
end
end,
},
}
task.defer(function()
-- Wait for all script threads to end
local thread = next(threads)
while thread do
if coroutine.status(thread) == "dead" then threads[thread] = nil else task.wait() end
thread = next(threads)
end
threads = nil
-- Apply all scheduled inheritances
local function Inherit(destination, inheritance)
inheritances[destination] = nil
for index, data in inheritance do
local source = exports[data[1]] or globals[data[1]]
if source then
if data[2] == "Clone" then
local inheritance = inheritances[source]
if inheritance then Inherit(source, inheritance) end
local indices = data[3]
if #indices == 0 then
for index, value in source do if destination[index] == nil then destination[index] = value end end
else
for index, value in indices do if destination[value] == nil then destination[value] = source[value] end end
end
else
setmetatable(destination, source)
end
else
warn(`Failed to inherit '{data[1]}', index not found`)
end
end
end
for destination, inheritance in inheritances do Inherit(destination, inheritance) end
inheritances = nil
-- Defer all initialize functions/threads
for index, functionOrThread in initializes do initializeThreads[task.defer(functionOrThread)] = true end
initializes = nil
task.defer(function()
-- Wait for all initialize threads to end
local thread = next(initializeThreads)
while thread do
if coroutine.status(thread) == "dead" then initializeThreads[thread] = nil else task.wait() end
thread = next(initializeThreads)
end
initializeThreads = nil
-- Defer all start functions/threads
for index, functionOrThread in starts do task.defer(functionOrThread) end
starts = nil
end)
end)
return setmetatable(globals, metatable)
Other Projects
Infinite Terrain
Packet
Suphi’s DataStore Module
Global Framework
Infinite Scripter
Mesh Editor
Quick Math Calculator
Toggle Block Comment
Toggle Decomposition Geometry
Tag Explorer
Suphi’s Linked List Module
Suphi’s Hybrid Linked List Module
Suphi’s RemoteFunction Module
Robux Converter
