DataModel

Show Deprecated
not creatable

The DataModel (commonly known as game after the global variable used to access it) is the root of Roblox's parent-child hierarchy. Its direct children are services (such as the Workspace and Lighting) that act as the fundamental components of a Roblox game.

Code Samples

DataModel (game) GetService

-- The DataModel, or 'game', is used to get services such as Workspace and Lighting
local Workspace = game:GetService("Workspace")
local Lighting = game:GetService("Lighting")
-- Examples of modifying properties of these services
Workspace.Gravity = 20
Lighting.ClockTime = 4

Summary

Properties

  • read only
    not replicated
    read parallel

    Describes the ID of the user or group that owns the place.

  • read only
    not replicated
    read parallel

    Describes the Enum.CreatorType of the place, whether the place is owned by a user or a group.

  • read only
    not replicated
    read parallel

    Describes the ID of the experience that the place running on the server belongs to.

  • read only
    not replicated
    read parallel
    deprecated

    Not functional. Historically described the Enum.Genre of the place as set on the Roblox website.

  • read only
    not replicated
    read parallel

    A unique identifier for the running game server instance.

  • read only
    not replicated
    read parallel

    Describes the ID of the place running on the server.

  • read only
    not replicated
    read parallel

    Describes the version of the place the server is running on.

  • read only
    not replicated
    read parallel

    Describes the private server ID of the server, if the server is a private server or a reserved server.

  • read only
    not replicated
    read parallel

    Describes the UserId of the Player that owns the private server if the server is private.

  • read only
    not replicated
    read parallel

    A reference to the Workspace service.

Methods

Methods inherited from ServiceProvider
  • write parallel

    Returns the service specified by the given className if it's already created, errors for an invalid name.

  • Returns the service with the requested class name, creating it if it does not exist.

Events

Events inherited from ServiceProvider

Properties

CreatorId

read only
not replicated
read parallel

This property describes the ID of the user or group that owns the place. If the DataModel.CreatorType property is 'User' then CreatorId will be the Player.UserId of the place's owner. If the DataModel.CreatorType is 'Group' then CreatorId will be the ID of the group that owns the place.

Code Samples

Detect when the place owner joins the game

local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
if game.CreatorType == Enum.CreatorType.User then
if player.UserId == game.CreatorId then
print("The place owner has joined the game!")
end
elseif game.CreatorType == Enum.CreatorType.Group then
if player:IsInGroup(game.CreatorId) then
print("A member of the group that owns the place has joined the game!")
end
end
end)

CreatorType

read only
not replicated
read parallel

This property describes the Enum.CreatorType of the place, whether the place is owned by a user or a group.

If the Enum.CreatorType is 'User', then the DataModel.CreatorId property will describe the UserId of the account that owns the game. If the CreatorType is 'Group', then it will describe the group ID.

Code Samples

Detect when the place owner joins the game

local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
if game.CreatorType == Enum.CreatorType.User then
if player.UserId == game.CreatorId then
print("The place owner has joined the game!")
end
elseif game.CreatorType == Enum.CreatorType.Group then
if player:IsInGroup(game.CreatorId) then
print("A member of the group that owns the place has joined the game!")
end
end
end)

GameId

read only
not replicated
read parallel

This property describes the ID of the experience that the place running on the server belongs to.

This ID can be found in the top right corner of the Asset Manager in Roblox Studio. When using Roblox Studio, if the place has not been published to Roblox then the GameId will correspond with the template being used.

See also:

read only
not replicated
read parallel

This property is broken and should not be used.

This property historically described the Enum.Genre of the place as set on the Roblox website.

This property, along with DataModel.GearGenreSetting, no longer functions correctly due to genres existing on the Roblox website that are not reflected in the Enum.Genre enum. As a result, attempting to read this property may throw an error.

JobId

read only
not replicated
read parallel

This property is a unique identifier for the running game server instance.

The JobId is a universally unique identifier (UUID) meaning that no two servers, past or present, will ever have the same JobId.

JobId defaults to an empty string in Roblox Studio.

See also:

PlaceId

read only
not replicated
read parallel

This property describes the ID of the place running on the server.

If the place has been published to Roblox, this ID can be found in Studio's Asset Manager by right-clicking the place inside of the Places folder and selecting Copy ID to Clipboard.

If the place has not been published to Roblox, this ID will correspond with the template being used.

See Also

  • DataModel.GameId, which describes the ID of the experience that the current place belongs to
  • DataModel.JobId, which is a unique identifier for the server game instance running
  • TeleportService, which is a service that can be used to transport Players between places

PlaceVersion

read only
not replicated
read parallel

This property describes the version of the place the server is running on.

This version number corresponds with the version number shown under the Version History section of the place's settings. It is not the current version of the Roblox client. This property is 0 for all unpublished experiences.

When a server instance is created for a place, it uses the place's current version. If the place is later updated while this server is running, the server will remain at its current version.

This property can be used to display a ScreenGui showing the current version of the game to Players to assist with debugging.

Code Samples

Server version number GUI

local StarterGui = game:GetService("StarterGui")
local versionGui = Instance.new("ScreenGui")
local textLabel = Instance.new("TextLabel")
textLabel.Position = UDim2.new(1, -10, 1, 0)
textLabel.AnchorPoint = Vector2.new(1, 1)
textLabel.Size = UDim2.new(0, 150, 0, 40)
textLabel.BackgroundTransparency = 1
textLabel.TextColor3 = Color3.new(1, 1, 1)
textLabel.TextStrokeTransparency = 0
textLabel.TextXAlignment = Enum.TextXAlignment.Right
textLabel.TextScaled = true
local placeVersion = game.PlaceVersion
textLabel.Text = string.format("Server version: %s", placeVersion)
textLabel.Parent = versionGui
versionGui.Parent = StarterGui

PrivateServerId

read only
not replicated
read parallel

This property describes the private server ID of the server, if the server is a private server.

If the server is not a private server, then this property will be an empty string.

Private servers

Private servers refer to the following:

PrivateServerId vs JobId

The PrivateServerId of a server is different from the DataModel.JobId. The JobId is the unique identifier of the current server instance.

Private servers (private or reserved servers) can have multiple server instances associated with them over time. This is because, although only one server instance can be running at once for a private server, new server instances can open and close as players join and leave the game. For example, no server instance is running when nobody is playing in the server. The PrivateServerId will be consistent across all of these server instances, and the DataModel.JobId will be unique for each one.

See also:

Code Samples

Detecting Private Servers

local function getServerType()
if game.PrivateServerId ~= "" then
if game.PrivateServerOwnerId ~= 0 then
return "VIPServer"
else
return "ReservedServer"
end
else
return "StandardServer"
end
end
print(getServerType())

PrivateServerOwnerId

read only
not replicated
read parallel

This property describes the UserId of the Player that owns the private server if the server is private.

If the server is a standard or reserved server then this property will be set to 0.

This property could be used to identify if a Player is the owner of the private server, for example:


local Players = game:GetService("Players")
-- is this a private server?
if game.PrivateServerId ~= "" and game.PrivateServerOwnerId ~= 0 then
-- listen for new players being added
Players.PlayerAdded:Connect(function(player)
-- check if the player is the server owner
if player.UserId == game.PrivateServerOwnerId then
print("The private server owner has joined the game")
end
end)
end

See also:

Code Samples

Detecting Private Servers

local function getServerType()
if game.PrivateServerId ~= "" then
if game.PrivateServerOwnerId ~= 0 then
return "VIPServer"
else
return "ReservedServer"
end
else
return "StandardServer"
end
end
print(getServerType())

Workspace

read only
not replicated
read parallel

The Workspace property is a reference to the Workspace service.

This property will always point to the Workspace and will never be nil.

The Workspace can also be accessed using the global variable workspace and the ServiceProvider:GetService() function. For example:


workspace -- a global variable
game.Workspace -- a property of the DataModel (game)
game:GetService("Workspace") -- workspace is a service

Methods

BindToClose

void

This function binds a function to be called prior to the game shutting down.

Multiple functions can be bound using BindToClose if it is called repeatedly. The game will wait a maximum of 30 seconds for all bound functions to complete running before shutting down. After 30 seconds, the game will shut down regardless if all bound functions have completed or not.

Bound functions will be called in parallel, meaning they will run at the same time.

You are advised to use RunService:IsStudio() to verify the current session is not Roblox Studio. If this is not done, all bound functions will be required to complete in offline testing sessions.

When using the DataStoreService, best practice is to bind a function saving all unsaved data to DataStores using BindToClose. Otherwise, data may be lost if the game shuts down unexpectedly. For an example of this, refer to the code samples.

See also:

Parameters

function: function

A function to be called prior to the game shutting down.


Returns

void

Code Samples

Saving player data before shutting down

local DataStoreService = game:GetService("DataStoreService")
local RunService = game:GetService("RunService")
local playerDataStore = DataStoreService:GetDataStore("PlayerData")
local allPlayerSessionDataCache = {}
local function savePlayerDataAsync(userId, data)
return playerDataStore:UpdateAsync(userId, function(oldData)
return data
end)
end
local function onServerShutdown()
if RunService:IsStudio() then
-- Avoid writing studio data to production and stalling test session closing
return
end
-- Reference for yielding and resuming later
local mainThread = coroutine.running()
-- Counts up for each new thread, down when the thread finishes. When 0 is reached,
-- the individual thread knows it's the last thread to finish and should resume the main thread
local numThreadsRunning = 0
-- Calling this function later starts on a new thread because of coroutine.wrap
local startSaveThread = coroutine.wrap(function(userId, sessionData)
-- Perform the save operation
local success, result = pcall(savePlayerDataAsync, userId, sessionData)
if not success then
-- Could implement a retry
warn(string.format("Failed to save %d's data: %s", userId, result))
end
-- Thread finished, decrement counter
numThreadsRunning -= 1
if numThreadsRunning == 0 then
-- This was the last thread to finish, resume main thread
coroutine.resume(mainThread)
end
end)
-- This assumes playerData gets cleared from the data table during a final save on PlayerRemoving,
-- so this is iterating over all the data of players still in the game that hasn't been saved
for userId, sessionData in pairs(allPlayerSessionDataCache) do
numThreadsRunning += 1
-- This loop finishes running and counting numThreadsRunning before any of
-- the save threads start because coroutine.wrap has built-in deferral on start
startSaveThread(userId, sessionData)
end
if numThreadsRunning > 0 then
-- Stall shutdown until save threads finish. Resumed by the last save thread when it finishes
coroutine.yield()
end
end
game:BindToClose(onServerShutdown)
Binding to and Handling Game Shutdown

game:BindToClose(function()
print(2 * 2)
task.wait(3)
print("Done")
end)

GetJobsInfo

Returns a table containing basic information about the jobs performed by the task scheduler.

In computing, a task scheduler is a system responsible for executing key tasks at the appropriate intervals.

You can also find live task scheduler statistics in the Task Scheduler window in Roblox Studio.

The first entry in the table returned is a reference dictionary containing the statistics (or headings) available. It is in the following format:


{
["name"] = "name",
["averageDutyCycle"] = "averageDutyCycle",
["averageStepsPerSecond"] = "averageStepsPerSecond",
["averageStepTime"] = "averageStepTime",
["averageError"] = "averageError",
["isRunning"] = "isRunning",
}

The subsequent entries in the table returned are dictionaries containing the above statistics for jobs performed by the task scheduler. For example:


{
["name"] = "Heartbeat",
["averageDutyCycle"] = 0,
["averageStepsPerSecond"] = 0,
["averageStepTime"] = 0,
["averageError"] = 0,
["isRunning"] = false,
}

See also:


Returns

A table containing information about the jobs performed by the task scheduler, see above for the format.

Code Samples

Getting Jobs Info

local jobInfo = game:GetJobsInfo()
local jobTitles = jobInfo[1]
table.remove(jobInfo, 1)
local divider = string.rep("-", 120)
print(divider)
warn("JOB INFO:")
print(divider)
for _, job in pairs(jobInfo) do
for jobIndex, jobValue in pairs(job) do
local jobTitle = jobTitles[jobIndex]
warn(jobTitle, "=", jobValue)
end
print(divider)
end

GetObjects

This method returns an array of Instances associated with the given content URL. It can be used to insert content from the Roblox library. It's not possible to insert Sounds using this method as they do not have an Instance associated with them and have only a content URL.

Unlike InsertService:LoadAsset(), DataModel:GetObjects() does not require an asset to be "trusted," meaning that an asset doesn't need to be owned by the logged in user, or created by Roblox, to be inserted. However, if the asset is not owned by the logged in user it must be freely available.

Due to this function's security context it can only be used by plugins or the command bar. For an alternative that can be used in Scripts and LocalScripts, see InsertService:LoadAsset().

Parameters

url: Content

The given content URL.


Returns

An array of Instances associated with the content URL.

Code Samples

View a plugin's source code

local Selection = game:GetService("Selection")
local WEB_URL = "plugin URL here"
local function downloadPlugin(webURL)
-- get the content URL
local contentID = string.match(webURL, "%d+")
local contentURL = "rbxassetid://" .. contentID
-- download the objects
local objects = game:GetObjects(contentURL)
-- decide where to parent them
local selection = Selection:Get()
local parent = #selection == 1 and selection[1] or workspace
-- parent the objects
for _, object in pairs(objects) do
object.Parent = parent
end
end
downloadPlugin(WEB_URL)
Batch convert decal IDs

local IMAGES = {
-- Insert Decal web URLs in an array here (as strings)
}
-- open the dictionary
local outputString = "textures = {"
-- utility function to add a new entry to the dictionary (as a string)
local function addEntryToDictionary(original, new)
outputString = outputString
.. "\n" -- new line
.. " " -- indent
.. '["'
.. original
.. '"]' -- key
.. ' = "'
.. new
.. '",' -- value
end
print("Starting conversion")
for _, webURL in pairs(IMAGES) do
-- get the content URL
local contentID = string.match(webURL, "%d+")
local contentURL = "rbxassetid://" .. contentID
local success, result = pcall(function()
local objects = game:GetObjects(contentURL)
return objects[1].Texture
end)
if success then
addEntryToDictionary(webURL, result)
else
addEntryToDictionary(webURL, "Error downloading decal")
end
task.wait()
end
print("Conversion complete")
-- close the dictionary
outputString = outputString .. "\n}"
-- print the dictionary
print(outputString)

IsLoaded

This function returns true if the client has finished loading the game for the first time.

When all initial Instances in the game have finished replicating to the client, this function will return true.

Unless they are parented to ReplicatedFirst, LocalScripts will not run while the game has not loaded. The following snippet, ran from a LocalScript in ReplicatedFirst will yield until the game has loaded:


if not game:IsLoaded() then
game.Loaded:Wait()
end

See also:


Returns

Whether the client has finished loading the game for the first time.

Code Samples

Custom Loading Screen

local Players = game:GetService("Players")
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
-- Create a basic loading screen
local screenGui = Instance.new("ScreenGui")
screenGui.IgnoreGuiInset = true
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(1, 0, 1, 0)
textLabel.BackgroundColor3 = Color3.fromRGB(0, 20, 40)
textLabel.Font = Enum.Font.GothamMedium
textLabel.TextColor3 = Color3.new(0.8, 0.8, 0.8)
textLabel.Text = "Loading"
textLabel.TextSize = 28
textLabel.Parent = screenGui
-- Parent entire screen GUI to player GUI
screenGui.Parent = playerGui
-- Remove the default loading screen
ReplicatedFirst:RemoveDefaultLoadingScreen()
--wait(3) -- Optionally force screen to appear for a minimum number of seconds
if not game:IsLoaded() then
game.Loaded:Wait()
end
screenGui:Destroy()

SetPlaceId

void

This function sets the DataModel.PlaceId of the game instance to the given placeId.

Setting the DataModel.PlaceId is required to access the DataStoreService when the place is unpublished (for example a local .rbxl file). See below for an example. This will only work when the 'Enable Studio Access to API Services` option is enabled under game settings.


local DataStoreService = game:GetService("DataStoreService")
-- access DataStore 'Data' as place placeId
game:SetPlaceId(placeId)
local dataStore = DataStoreService:GetDataStore("Data")

You can use DataModel:SetUniverseId() to set the DataModel.GameId of the game instance. However, it is the DataModel.PlaceId that must be set to access the DataStoreService.

Parameters

placeId: number

The ID to set the DataModel.PlaceId to.


Returns

void

SetUniverseId

void

This function sets the DataModel.GameId of the current game instance to the given universeId. This is useful when testing local .rbxl files that have not been published to Roblox.

If you want to access the DataStoreService in an unpublished place, you should use DataModel:SetPlaceId() instead.

Parameters

universeId: number

The ID to set the DataModel.GameId to.


Returns

void

Events

GraphicsQualityChangeRequest

Fires when the user prompts an increase or decrease in graphics quality using the hotkeys.

This event fires under the following conditions:

  • If the user presses F10, this event fires with a betterQuality argument of true
  • If the user presses Shift + F10, this event fires with a betterQuality argument of false

GraphicsQualityChangeRequest does not provide the current graphics quality level or cover all updates to the graphics quality. For example, changes made in the core GUI escape menu are not registered. This event is intended to be used by Roblox Class.CoreScript|Core Scripts to update the graphics quality and display notifications.

You can retrieve a user's Enum.SavedQualitySetting using UserGameSettings with the following snippet:


UserSettings():GetService("UserGameSettings").SavedQualityLevel

If the user's graphics settings are set to automatic then the Enum.SavedQualitySetting will be 'Automatic'. There is currently no way for developers to reliably get the current graphics quality level of a user's machine.

Parameters

betterQuality: bool

Whether the user has prompted an increase (true) or a decrease (false) in graphics quality.


Code Samples

Handling User Changes in Graphics Quality

game.GraphicsQualityChangeRequest:Connect(function(betterQuality)
if betterQuality then
print("The user has requested an increase in graphics quality!")
else
print("The user has requested a decrease in graphics quality!")
end
end)

Loaded

This event fires on the client when the game finishes loading for the first time.

The Loaded event fires when all initial Instances in the game have finished replicating to the client.

Unless they are parented to ReplicatedFirst, LocalScripts will not run prior to this event firing. The following snippet, ran from a LocalScript in ReplicatedFirst, will yield until the game has loaded:


if not game:IsLoaded() then
game.Loaded:Wait()
end

See also: