Skip to content

Roblox Deviations

Gargatuan aims to bring a balance of Roblox familiarity while cleansing technical debt and poor API decisions. Most games written using modern Roblox APIs will run fine.

For Roblox developers looking to port their games into Gargantuan, this is a non-exhaustive list of all deviations from Roblox done in Gargantuan.

Gargantuan provides a Roblox compatibility mode which alters several APIs to match Roblox, eliminating all API deviations.

Enable it in your project.config.json:

{
"name": "My Gargantuan Game",
"compatibility": {
"roblox": {
"enabled": true
}
}
}

Or, enable it in the player CLI using the compat-roblox flag:

Terminal window
gargantuan --compat-roblox --script=src/Main.luau
  • The typenames for RBXScriptSignal and RBXScriptConnection are renamed to Signal and SignalConnection:

    local connection = game.Destroying:Connect(function() end);
    -- with roblox compatibility disabled:
    print(typeof(game.Destroying)) --> "Signal"
    print(typeof(connection)) --> "SignalConnection"
    -- with roblox compatibility enabled:
    print(typeof(game.Destroying)) --> "RBXScriptSignal"
    print(typeof(connection)) --> "RBXScriptConnection"
    -- note that the Signal runtime global stays constant regardless if
    -- roblox compatibility is enabled
    local signal = Signal.new<<string>>()

    It is possible to write code that is compatible with both Gargantuan and Roblox, regardless of the ROblox compatibility mode being enabled:

    -- typenames will return "Signal" and "SignalConnection" in Gargantuan, but
    -- "RBXScriptSignal" and "RBXScriptConnection" in Roblox
    local signalTypeName = typeof(game.Destroying)
    local connection = game.Destroying:Connect(function() end);
    local connectionTypeName = typeof(signal)
    connection:Disconnect()
    -- now you can use them!
    -- you can choose to use Roblox or Gargantuan's signal type definition
    local function validate(x: SignalConnection)
    if typeof(x) == connectionTypeName then
    -- ...
    end
    end
  • There is no workspace global. Import game:GetService("Workspace") yourself.

  • Likewise, there is no plugin global. Import script:FindFirstAncestorOfClass("Plugin") yourself.

  • Many Roblox deprecated APIs, such as Instance:isA, has been unimplemented in Gargantuan. You may find old Roblox codebases being harder to port.

  • Roblox-based asset paths such as rbxassetid:// will not work inside Gargantuan. Include assets yourself inside the project’s directory, then refer to it using project:// paths.

    • The rbx-to-gargantuan toolchain will attempt to fetch Roblox assets, as well provide new builtin assets for your game to use.
    • Tools like Asphalt and Tungsten are redundant as Gargantuan synchronizes assets directly from your project via the filesystem.
  • Packages are unimplemented. Use DirectoryLink to synchronize your packages.

  • task.cancel and coroutine.close cannot be interspersed with task library threads and Lua coroutines. This restriction may be lifted by the 0.1 release.

  • BaseScript, LocalScript, and Enum.RunContext.Legacy have been unimplemented due to redundancy:

    local script = Instance.new("Script")
    print(script:IsA("BaseScript")) --> false
    print(script:IsA("Script")) --> true
    print(script:IsA("LuaSourceContainer")) --> true
    print(Enum.RunContext:GetEnumItems()) --> { Enum.RunContext.Client, Enum.RunContext.Server }
    -- this will now error, as Gargantuan does not use LocalScripts
    Instance.new("LocalScript")
  • Several Roblox features are unimplemented from Gargantuan, including the player controller, gears, CoreGui, et al. so games can implement their own systems such as chat and avatars as deemed fit. Gargantuan provides preset models for you to use as a baseline. You may also reimplement features from scratch using the InstanceClass data type:

    -- TODO: gotta design this to support C++ and Luau classes
    local Humanoid = InstanceClass.new("Humanoid")
    Humanoid.Properties = { ... }
    Humanoid.Methods = { ... }
    Humanoid:Register()
    local humanoid = Instance.new("Humanoid")
    humanoid.Parent = Players.LocalPlayer

    It’s recommended to write a type definition file for your declared classes:

    declare extern type Humanoid: Instance
    Health: number
    -- ...
    end