Introducing SettingsModule, an open-source module to assist you with creating settings in your game.
Notes
-
SettingsModule is designed to help beginner scripters add settings to their games. Although it’s got features for intermediate/advanced scripters too!
-
SettingsModule attempts to replicate Roblox API as closely as possible while also staying simple for beginners.
-
SettingsModule is meant for CLIENT-SIDE usage. Not recommended for use on the server.
Latest Update
API
Methods
Module
SettingsModule.new()
function SettingsModule.new(name: string, value: any)
Description: Creates a new setting. Returns the setting.
SettingsModule:WaitForSetting()
function SettingsModule:WaitForSetting(name: string, timeout: number)
Description: Returns a setting. If it doesn’t exist yet, it will continuously wait until it does and return it. If timeout is specified, it will wait for the setting until the timeout has completed, in which then it will throw a warning and return nothing.
SettingsModule:RetrieveSaveData()
function SettingsModule:RetrieveSaveData()
Description: Returns a JSON encoded string for data storage.
Note: This method will not save certain values, like objects. However it does have built-in conversion for the following data types:
- Enums
SettingsModule:WriteSaveData()
function SettingsModule:WriteSaveData(save: string)
Description: JSON decodes a string returned from :RetrieveSaveData
and sets the resulting table to the settings.
Note: Still has conversion methods listed in RetrieveSaveData()
.
Settings
Setting:Destroy()
function Setting:Destroy()
Description: Permanently destroys a setting. Not recoverable.
Setting:Set() (deprecated)
function Setting:Set(newValue: any)
Description: Sets a setting to a new value.
Deprecation: This method is deprecated, but included for backwards-compatibility. setting.Value = newValue
is favored.
Setting:TweenSet()
function Setting:TweenSet(endValue: any, tweenInfo: TweenInfo)
Description: Will tween a setting to an end value with the provided TweenInfo.
Note: You can currently only tween the following data types:
- Numbers
- Booleans
- CFrames
- Color3s
- Vector3s
Signals
Module
SettingsModule.SettingChanged
SettingsModule.SettingChanged:Connect(function(setting)
Description: Signal that fires whenever any setting is changed. Returns the setting.
SettingsModule.SettingAdded
SettingsModule.SettingAdded:Connect(function(setting)
Description: Signal that fires whenever any setting is added. Returns the setting.
SettingsModule.SettingRemoved
SettingsModule.SettingRemoved:Connect(function(setting)
Description: Signal that fires whenever any setting is removed. Returns the setting.
Settings
Setting.Changed
Setting.Changed:Connect(function(newValue)
Description: Signal that fires whenever the specific setting is changed. Returns its new value.
Setting.Removing
Setting.Changed:Connect(function(oldSetting)
Description: Signal that fires whenever the specific setting is destroyed. Returns itself before destruction.
Objects
Setting
SettingsModule.new(name: string, value: any)
Description: Setting object. Hierarchy and “properties” looks like this:
-
Module (dictionary)
The module (technically classified as a dictionary).
-
Settings (dictionary)
A dictionary containing all existing settings. You can access settings from this but it is recommended to use
:WaitForSetting(name: string)
.-
Setting (object)
The Setting object. This is what is returned when you call
:WaitForSetting(name: string)
,SettingsModule.new(name: string, value: any)
, etc.-
Name (property)
The name of the setting. Read-only.
-
Value (property)
The value of the setting. Can be set.
-
Type (property)
The datatype of the setting’s value. Read-only. Equivalent to using
typeof(Setting.Value)
. -
Changed (signal)
A signal that fires whenever the setting’s value is changed.
-
Removing (signal)
A signal that fires whenever the setting is about to be destroyed.
-
IsConverted (property, internal)
A property used internally to convert objects such as
Enums
into savable data. Read-only. Under no circumstances should you change this property. -
Destroy() (function)
A function that permanently destroys the setting.
-
Set() (function)
A function that sets the setting’s value.
-
"TweenSet() (function)
A function that tweens the setting’s value to the specific goal value.
-
-
-
WARNING: All of these properties, except for
.Value
are READ-ONLY.
WARNING: Setting objects are NOT actual values or instances.
Tutorials
The Basics
The GUI and scripts located in this tutorial are in this free model: SettingsModule | The Basics - Roblox. It can also be found in the place: SettingsModule Tutorial - Roblox
For the basic settings, we will be creating three settings (that work):
- Volume
- Shadows
- FOV
If you follow this tutorial correctly, these three settings will work without any further scripting needed. Now onto the tutorial.
- Create a ScreenGui in StarterGui. Design your settings screen to accommodate those three settings mentioned earlier. Make sure the names of objects are unique and make sense, and aren’t names like “TextButton3”.
My ScreenGui hierarchy looks like this:
- Create a LocalScript in the ScreenGui, as shown in the screenshot above. Inside it, write this script or something similar:
-- Get ReplicatedStorage as a service
local replicatedStorage = game:GetService("ReplicatedStorage")
-- Require SettingsModule so we can use it
local settingsModule = require(replicatedStorage:WaitForChild("SettingsModule"))
-- Create new settings
local volume = settingsModule.new("Volume", 0.5)
local shadows = settingsModule.new("Shadows", true)
local fov = settingsModule.new("FOV", 70)
-- Get all UI objects we need
local settingsGui = script.Parent
local background = settingsGui:WaitForChild("Background")
local volumeFrame = background:WaitForChild("Volume")
local shadowsFrame = background:WaitForChild("Shadows")
local fovFrame = background:WaitForChild("FOV")
local volumeInput = volumeFrame:WaitForChild("Input")
local shadowsToggle = shadowsFrame:WaitForChild("Toggle")
local fovInput = fovFrame:WaitForChild("Input")
-- Function for when the volume input changes
local function volumeChanged()
-- Convert the input to a number
local newVolume = tonumber(volumeInput.Text)
-- Make sure that the new volume exists and isn't just nothing
if newVolume then
-- Make sure the volume isn't set to lower than 0 and higher than 1, set the new volume
volume:Set(math.clamp(newVolume, 0, 1))
end
end
-- Function for when the shadows button is clicked
local function shadowsChanged()
-- If shadows are enabled, then...
if shadows.Value == true then
shadowsToggle.Text = "OFF" -- Set button text to OFF
shadowsToggle.BackgroundColor3 = Color3.new(1, 0, 0) -- Set button color to red
shadows:Set(false) -- Set the new value
-- Else if shadows aren't enabled, then...
else
shadowsToggle.Text = "ON" -- Set button text to ON
shadowsToggle.BackgroundColor3 = Color3.new(0, 2, 0) -- Set button color to green
shadows:Set(true) -- Set the new value
end
end
-- Function for when the FOV input changes
local function fovChanged()
-- Convert the input to a number
local newFov = tonumber(fovInput.Text)
-- Make sure that the new FOV exists and isn't just nothing
if newFov then
-- Make sure the FOV isn't set to lower than 70 and higher than 120, set the new volume
fov:Set(math.clamp(newFov, 70, 120))
end
end
-- Connect the functions to the inputs
volumeInput:GetPropertyChangedSignal("Text"):Connect(volumeChanged)
shadowsToggle.Activated:Connect(shadowsChanged) -- Equivalent to clicking it, but works for mobile
fovInput:GetPropertyChangedSignal("Text"):Connect(fovChanged)
If you copy/paste my script, make sure that all the UI objects you reference are correct.
- Create a new LocalScript in StarterPlayer > StarterPlayerScripts. Inside it, write this or something similar:
-- Get the services we need
local replicatedStorage = game:GetService("ReplicatedStorage")
local lighting = game:GetService("Lighting")
-- Require SettingsModule so we can use it
local settingsModule = require(replicatedStorage:WaitForChild("SettingsModule"))
-- Get the player's camera
local camera = workspace.CurrentCamera
-- Wait for the settings to be created by the Handler script we created before
local volume = settingsModule:WaitForSetting("Volume")
local shadows = settingsModule:WaitForSetting("Shadows")
local fov = settingsModule:WaitForSetting("FOV")
-- Function for when the volume setting is changed
local function volumeChanged(newVolume)
-- Loop through all instances in the game
for _, instance in ipairs(game:GetDescendants()) do
-- Check if the instance is a sound
if instance:IsA("Sound") then
-- Set the sound's volume to the new volume
instance.Volume = newVolume
end
end
end
-- Function for when the shadows setting is changed
local function shadowsChanged(newShadows)
-- Sets shadows to the new value
lighting.GlobalShadows = newShadows
end
-- Function for when the FOV setting is changed
local function fovChanged(newFov)
-- Set the camera's FOV to the new value
camera.FieldOfView = newFov
end
-- Connect the functions to the settings' Changed signals
volume.Changed:Connect(volumeChanged)
shadows.Changed:Connect(shadowsChanged)
fov.Changed:Connect(fovChanged)
Technically, you could merge these two scripts together, but to show you how to access settings from other scripts, I split them in two.
- Test it!
Test out the system. See if any errors or warnings show up in the console. If you can’t seem to get it working, reply to this thread or private message me so we can work it out.
Here’s video footage of my testing for comparison:
The Basics | SettingsModule - Google Drive
Hopefully, this tutorial helps you gain a better understanding of how this module works! The comments in the scripts should be enough for you to understand how they work, but if you have any more questions about it, just ask me.
Good luck!
Tweening
WIP
Data Saving
WIP
Keybinds
WIP
Resources
You can get the model here:
You can get the open-source tutorial place here:
You can get the .RBXM
file here:
SettingsModule v1.1.rbxm (3.8 KB)
GitHub has been closed because I have no idea how to parent modules under modules. Sorry, Rojo users!
License
MIT License
MIT License
Copyright (c) 2023 Fizzitic/Fizzitix
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Read the full document here.
End
If you want, you can create your own variants of this module and release them under your name. The license says so.
Fizzitix