Example - ModuleScript as DB
This section provides a beginner-friendly example of using a ModuleScript in Roblox as a simple database for storing and managing game data, demonstrating how to set up, populate, and interact with data in a Roblox game.
Create a new experience in Roblox Studio
Create a ModuleScript in ServerStorage and name it "Items"
Create a new Project in Roda
Create a new Data File Configuration
Pick the Items ModuleScript as the Data File
Set the Table Type to Dict
Add properties to the Data File Settings
Click "Add From Code", paste the following Lua snippet, and click "Parse":
Set the UI Element of image property to "T.Box with Image Selection"
Upload some images (if you don’t have any, find free images on websites like Craftpix)
Insert the images and move them into a Folder
Set this Folder as Image Pool in the Data File Settings
Add some items on the Editor Page
-
Create the scripts, run the game, stop, edit items, run again...
ServerScriptService.Script-- Load the items data from a ModuleScript located in ServerStorage local items = require(game.ServerStorage.Items) -- Create a RemoteEvent for clients to request the items table from the server local GetItems = Instance.new("RemoteEvent") -- Creates a new RemoteEvent object GetItems.Name = "GetItems" -- Names it "GetItems" for identification GetItems.Parent = game.ReplicatedStorage -- Places it in ReplicatedStorage for server-client communication -- Create a new RemoteEvent for notifying clients when an item is collected local ItemCollected = Instance.new("RemoteEvent") -- Creates another RemoteEvent object ItemCollected.Name = "ItemCollected" -- Names it "ItemCollected" for item collection events ItemCollected.Parent = game.ReplicatedStorage -- Places it in ReplicatedStorage for server-client communication -- Handle client requests for the items table GetItems.OnServerEvent:Connect(function(player) -- Listens for when a client fires this event GetItems:FireClient(player, items) -- Sends the items table back to the requesting client end) -- System to spawn spheres with GUIs and handle item collection local spawnAreaSize = 50 -- Defines the size of the 50x50 stud area where spheres spawn local spawnPoint = game.Workspace:WaitForChild("SpawnLocation").Position or Vector3.new(0, 0, 0) -- Gets the position of SpawnLocation or defaults to (0, 0, 0) if not found local maxSpheres = 200 -- Sets the maximum number of spheres allowed in the game at once local sphereCount = 0 -- Tracks the current number of active spheres -- List of colors for the spheres local colors = { Color3.fromRGB(255, 99, 51), -- Bright red-orange Color3.fromRGB(255, 105, 180), -- Hot pink Color3.fromRGB(144, 238, 144), -- Light green Color3.fromRGB(230, 69, 217), -- Bright purple Color3.fromRGB(255, 165, 0), -- Orange Color3.fromRGB(255, 255, 62), -- Bright yellow Color3.fromRGB(30, 51, 240), -- Deep blue Color3.fromRGB(88, 255, 249), -- Cyan } -- Create a table of item names (keys) for random selection from the items dictionary local itemNames = {} -- Initializes an empty table to store item names for name, _ in pairs(items) do -- Loops through the items dictionary to get all keys (item names) table.insert(itemNames, name) -- Adds each item name to the itemNames table end -- Function to spawn a sphere with an invisible outer sphere for touch detection local function spawnSphere() if sphereCount >= maxSpheres then return end -- Stops spawning if the maximum number of spheres is reached local randomItemName = itemNames[math.random(1, #itemNames)] -- Randomly selects an item name from the list local item = items[randomItemName] or error("Item not found: " .. randomItemName) -- Gets the item data or throws an error if not found local shapes = { -- List of possible shapes for the sphere Enum.PartType.Ball, Enum.PartType.Block, Enum.PartType.Cylinder, Enum.PartType.Wedge, Enum.PartType.CornerWedge, } local randomShape = shapes[math.random(1, #shapes)] -- Randomly picks a shape from the list local randomColor = colors[math.random(1, #colors)] -- Randomly picks a color from the colors list -- Create the visible inner sphere (small, colored) local innerSphere = Instance.new("Part") -- Creates a new Part for the visible sphere innerSphere.Shape = randomShape -- Sets the shape to a random type (e.g., Ball, Block) innerSphere.Size = Vector3.new(1, 1, 1) -- Sets a small size for the visible sphere innerSphere.Position = Vector3.new( -- Sets a random position within the spawn area spawnPoint.X + math.random(-spawnAreaSize / 2, spawnAreaSize / 2), -- Random X position spawnPoint.Y + math.random(5, 25), -- Random Y position (5 to 25 studs above ground) for dropping spawnPoint.Z + math.random(-spawnAreaSize / 2, spawnAreaSize / 2) -- Random Z position ) innerSphere.Anchored = false -- Allows the sphere to fall due to physics innerSphere.BrickColor = BrickColor.new(randomColor) -- Applies a random color innerSphere.Parent = game.Workspace -- Places the sphere in the Workspace for visibility -- Create an invisible outer sphere for touch detection (larger, transparent) local outerSphere = Instance.new("Part") -- Creates a new Part for the invisible touch detection outerSphere.Shape = Enum.PartType.Ball -- Uses a Ball shape for consistent touch detection outerSphere.Size = Vector3.new(5, 5, 5) -- Sets a larger size for the touch area outerSphere.Position = innerSphere.Position -- Matches the position of the inner sphere outerSphere.Anchored = false -- Allows falling with the inner sphere outerSphere.Transparency = 1 -- Makes it fully invisible outerSphere.CanCollide = false -- Prevents physical collisions, only allowing touch detection outerSphere.Parent = game.Workspace -- Places it in the Workspace -- Weld the inner and outer spheres together local weld = Instance.new("WeldConstraint") -- Creates a WeldConstraint to connect the spheres weld.Part0 = innerSphere -- Sets the inner sphere as the base part weld.Part1 = outerSphere -- Sets the outer sphere to follow the inner sphere weld.Parent = innerSphere -- Parents the weld to the inner sphere for management -- Add item name as an attribute to the outer sphere (for touch event) outerSphere:SetAttribute("ItemId", item.name) -- Stores the item name as an attribute for identification -- Create a BillboardGui for the item display (attached to the inner sphere) local billboardGui = Instance.new("BillboardGui") -- Creates a GUI that displays above the sphere billboardGui.Size = UDim2.new(3, 0, 3, 0) -- Sets the size of the GUI (3x3 studs) billboardGui.StudsOffset = Vector3.new(0, 3, 0) -- Positions the GUI 3 studs above the inner sphere billboardGui.Adornee = innerSphere -- Attaches the GUI to the inner sphere billboardGui.Parent = innerSphere -- Parents the GUI to the inner sphere -- Add ImageLabel for the item image local imageLabel = Instance.new("ImageLabel") -- Creates an image label for the item’s image imageLabel.Size = UDim2.new(1, 0, 0.7, 0) imageLabel.Position = UDim2.new(0, 0, 0, 0) -- Positions it at the top-left of the GUI imageLabel.Image = item.image -- Sets the image from the item data imageLabel.BackgroundTransparency = 1 -- Makes the background fully transparent imageLabel.ScaleType = Enum.ScaleType.Fit -- Ensures the image fits within the label while maintaining aspect ratio imageLabel.Parent = billboardGui -- Parents it to the BillboardGui -- Add TextLabel for the value local valueLabel = Instance.new("TextLabel") -- Creates a text label for the item’s value valueLabel.Size = UDim2.new(1, 0, 0.3, 0) -- Sets the size to 30% of the GUI height valueLabel.Position = UDim2.new(0, 0, 0.7, 0) -- Positions it below the image (70% down) valueLabel.TextScaled = true -- Scales the text to fit the label valueLabel.Text = "$ " .. tostring(item.value) -- Displays the item’s value with a dollar sign valueLabel.TextColor3 = Color3.new(0.666667, 1, 0) -- Sets the text color to green valueLabel.Font = Enum.Font.Cartoon -- Sets the font to a cartoon style for a playful look valueLabel.BackgroundTransparency = 1 -- Makes the background fully transparent valueLabel.Parent = billboardGui -- Parents it to the BillboardGui -- Handle outer sphere touch to fire event to client and destroy both spheres outerSphere.Touched:Connect(function(hit) -- Detects when the outer sphere is touched local player = game.Players:GetPlayerFromCharacter(hit.Parent) -- Gets the player who touched the sphere if player and outerSphere and outerSphere.Parent then -- Checks if the player and outer sphere exist outerSphere.CanTouch = false -- Prevents the sphere from being touched multiple times local itemId = outerSphere:GetAttribute("ItemId") -- Retrieves the item name from the attribute if itemId then -- Ensures an item ID exists -- Fire the ItemCollected event to the player with the item data ItemCollected:FireClient(player, items[itemId]) -- Sends the item data to the client -- Destroy both spheres immediately if innerSphere and innerSphere.Parent then -- Checks if the inner sphere exists innerSphere:Destroy() -- Removes the visible inner sphere end if outerSphere and outerSphere.Parent then -- Checks if the outer sphere exists outerSphere:Destroy() -- Removes the invisible outer sphere sphereCount = sphereCount - 1 -- Decrements the sphere count end end end end) sphereCount = sphereCount + 1 -- Increments the sphere count for each new sphere end -- Spawn spheres continuously (every 0.25 seconds) up to maxSpheres spawn(function() while true do -- Runs an infinite loop to keep spawning spheres if sphereCount < maxSpheres then -- Checks if we’re below the maximum number of spheres spawnSphere() -- Calls the function to spawn a new sphere end wait(0.25) -- Pauses for 0.25 seconds before spawning the next sphere end end)
StarterPlayer.StarterPlayerScripts.LocalScript-- Get the local player (the player running this script on their client) local player = game.Players.LocalPlayer -- Create a ScreenGui to hold the inventory UI local gui = Instance.new("ScreenGui") -- Creates a new ScreenGui object gui.Name = "InventoryGui" -- Names it "InventoryGui" for identification gui.Parent = player.PlayerGui -- Places it in the player's PlayerGui for client-side UI -- Create a main frame for the inventory GUI local frame = Instance.new("Frame") -- Creates a new Frame object for the GUI container frame.Name = "GuiFrame" -- Names it "GuiFrame" for identification frame.Size = UDim2.new(0.25, 0, 0.75, 0) -- Sets the size to 25% of the screen width and 75% of the screen height frame.Position = UDim2.new(0, 0, 0.25, 0) -- Positions it at the top-left corner (0 from left, 25% from top) frame.BackgroundTransparency = 1 -- Makes the background fully transparent frame.Parent = gui -- Parents it to the ScreenGui -- Create a UIListLayout to organize elements vertically in the frame local layout = Instance.new("UIListLayout") -- Creates a new UIListLayout for layout management layout.FillDirection = Enum.FillDirection.Vertical -- Arranges items vertically layout.HorizontalAlignment = Enum.HorizontalAlignment.Center -- Centers items horizontally layout.VerticalAlignment = Enum.VerticalAlignment.Center -- Centers items vertically layout.SortOrder = Enum.SortOrder.LayoutOrder -- Sorts items based on their LayoutOrder layout.Parent = frame -- Parents it to the frame -- Create cash label at the top of the frame local cashLabel = Instance.new("TextLabel") -- Creates a new TextLabel for displaying cash cashLabel.Name = "CashLabel" -- Names it "CashLabel" for identification cashLabel.Size = UDim2.new(1, 0, 0.2, 0) -- Sets the size to 100% of the frame width and 20% of its height cashLabel.BackgroundTransparency = 1 -- Makes the background fully transparent cashLabel.Text = "Cash: $0" -- Sets the initial text to show zero cash cashLabel.TextColor3 = Color3.new(0.666667, 1, 0) -- Sets the text color to green cashLabel.Font = Enum.Font.Cartoon -- Sets the Font cashLabel.TextScaled = true -- Scales the text to fit the label size cashLabel.LayoutOrder = 1 -- Sets the order for layout cashLabel.Parent = frame -- Parents it to the frame -- Create the main inventory frame (scrollable) inside the GUI frame local scrollingFrame = Instance.new("ScrollingFrame") -- Creates a new ScrollingFrame for scrollable items scrollingFrame.Name = "InventoryFrame" -- Names it "InventoryFrame" for identification scrollingFrame.Size = UDim2.new(1, 0, 0.8, 0) -- Sets the size to 100% of the frame width and 80% of its height scrollingFrame.BackgroundColor3 = Color3.new(0, 0, 0) -- Sets the background color to black scrollingFrame.BackgroundTransparency = 0.5 -- Makes the background semi-transparent (50% opacity) scrollingFrame.ScrollBarThickness = 8 -- Sets the thickness of the scrollbar scrollingFrame.CanvasSize = UDim2.new(0, 0, 0, 0) -- Initial canvas size for scrolling (auto-adjusts) scrollingFrame.AutomaticCanvasSize = Enum.AutomaticSize.Y -- Automatically adjusts the canvas height based on content scrollingFrame.LayoutOrder = 2 -- Sets the order for layout scrollingFrame.Parent = frame -- Parents it to the frame -- Create a layout for scrollable items within the scrolling frame local itemLayout = Instance.new("UIListLayout") -- Creates a new UIListLayout for organizing items itemLayout.Padding = UDim.new(0, 5) -- Adds 5 pixels of padding between items itemLayout.Parent = scrollingFrame -- Parents it to the scrolling frame -- Fetch items from the server local GetItems = game.ReplicatedStorage:WaitForChild("GetItems") -- Gets the GetItems RemoteEvent from ReplicatedStorage local allItems = nil -- Initializes a variable to store the items table GetItems:FireServer() -- Sends a request to the server to get the items GetItems.OnClientEvent:Connect(function(itemsData) -- Listens for the response from the server allItems = itemsData -- Stores the received items table for later use end) local collectSounds = { "rbxassetid://6586979979", --"rbxassetid://.." } -- Create and store sound instances once on the client for item collection local sounds = {} -- Initializes an empty table to store sound instances for _, soundId in pairs(collectSounds) do -- Loops through the list of sound IDs local sound = Instance.new("Sound") -- Creates a new Sound object sound.SoundId = soundId -- Sets the sound ID from the list sound.Parent = player.PlayerGui -- Parents the sound to PlayerGui for client-side playback sound.Looped = false -- Ensures the sound doesn’t loop sound.Volume = 0.5 -- Sets the volume (optional, default is 1) table.insert(sounds, sound) -- Adds the sound to the sounds table end -- Track inventory and cash for the player local inventory = {} -- Initializes an empty table to track collected items local totalCash = 0 -- Initializes the total cash to zero -- Handle item collection from server event local ItemCollected = game.ReplicatedStorage:WaitForChild("ItemCollected") -- Gets the ItemCollected RemoteEvent from ReplicatedStorage ItemCollected.OnClientEvent:Connect(function(item) -- Listens for when an item is collected on the client if item then -- Ensures an item was received local randomSound = sounds[math.random(1, #sounds)] -- Randomly selects a sound from the sounds table randomSound:Play() -- Plays the selected sound for item collection -- Add item to inventory (create GUI elements) local itemFrame = Instance.new("Frame") -- Creates a new Frame for the item in the inventory itemFrame.Size = UDim2.new(1, 0, 0.1, 0) -- Sets the size to 100% of the scrolling frame width and 10% of its height itemFrame.BackgroundColor3 = Color3.new(0.121569, 0.121569, 0.121569) -- Sets the background color to dark gray itemFrame.BackgroundTransparency = 0.6 -- Makes the background semi-transparent (60% opacity) itemFrame.Parent = scrollingFrame -- Parents it to the scrolling frame for display local image = Instance.new("ImageLabel") -- Creates an ImageLabel for the item’s image image.Size = UDim2.new(0.3, 0, 1, 0) -- Sets the size to 30% of the item frame width and 100% of its height image.Position = UDim2.new(0, 0, 0, 0) -- Positions it at the top-left of the item frame image.Image = item.image -- Sets the image from the item data image.BackgroundTransparency = 1 -- Makes the background fully transparent image.ScaleType = Enum.ScaleType.Fit -- Ensures the image fits within the label while maintaining aspect ratio image.Parent = itemFrame -- Parents it to the item frame local nameLabel = Instance.new("TextLabel") -- Creates a TextLabel for the item’s name nameLabel.Size = UDim2.new(0.7, 0, 1, 0) -- Sets the size to 70% of the item frame width, full height nameLabel.Position = UDim2.new(0.3, 0, 0, 0) -- Positions it to the right of the image (30% from left) nameLabel.Text = item.name -- Sets the text to the item’s name nameLabel.TextColor3 = Color3.new(1, 1, 1) -- Sets the text color to white nameLabel.BackgroundTransparency = 1 -- Makes the background fully transparent nameLabel.Font = Enum.Font.Cartoon -- Uses a cartoon-style font for a playful look nameLabel.TextScaled = true -- Scales the text to fit the label size nameLabel.Parent = itemFrame -- Parents it to the item frame -- Track the item in inventory by adding it to the list to prevent duplicates table.insert(inventory, item) -- Adds the item to the inventory table totalCash = totalCash + (item.value or 0) -- Adds the item’s value to the total cash (defaults to 0 if no value) cashLabel.Text = "Cash: $" .. totalCash -- Updates the cash label with the new total end end)