🗺️ My First Roblox Studio Game Episode 6 of 6
🗺️ Episode 6 · Island Quest RPG

Build an Island Quest
RPG Adventure!

Explore a tropical island, talk to NPCs, accept quests, collect loot and face off against a final boss to win. This is the biggest Roblox project yet!

👶 Ages 9+ ⏱ ~2 hours 🔧 Roblox Studio ✨ Free
0 XP
Level 1
🔥0
Your Progress 0 / 14 steps
1
🏝️
Build Your Island World
Create a tropical island with beach, jungle and ruins
Active
🏝️
Goal: A beautiful island to explore

We'll build terrain with sand beaches, a grassy jungle, ancient ruins and a volcano giving players lots of places to discover.

Set Up the World

  1. 1Open Roblox Studio → New → Baseplate
  2. 2In the Explorer, click Workspace → Baseplate and press Delete to remove it
  3. 3Open the Terrain Editor (Home tab → Terrain Editor button)
  4. 4Click Generate and set: Biome = Tropics, Size X = 512, Size Z = 512, then click Generate
  5. 5Use the Paint brush to add sandy beach around the coast (Sand material, large brush)

Add Island Landmarks

  1. 6Insert a SpawnLocation Part on the beach rename it SpawnLocation, set Material = SmoothPlastic, colour white
  2. 7Build a small Village Area: 3–4 stone walls and a floor using Parts (Material = SmoothPlastic, medium grey). Group it as Village
  3. 8Build an Ancient Ruins area inland: crumbled walls, stone pillars, overgrown floor. Group as Ruins
  4. 9Build a Volcano platform at the far end of the island a dark grey wedge hill with a red glowing top (Neon material, BrickRed colour)
💡
Use Ctrl+G to group selected Parts. Rename your groups in Explorer so the hierarchy stays tidy as the project grows.
👋
Grown-up note: The Terrain Generator creates an instant playable island. Kids can spend 10–15 mins painting extra detail, but the generated terrain is enough to continue.
🔢
Put It In Order
+15 XP
Click these steps in the correct order to set up your island world:
Use the Paint brush to add sandy beach around the coast
Open Roblox Studio and create a new Baseplate project
Open the Terrain Editor and Generate a Tropics biome
🧠
Knowledge Check
+15 XP
What is the keyboard shortcut to group selected Parts in Roblox Studio?
ACtrl+D (Duplicate)
BCtrl+Z (Undo)
CCtrl+G (Group)
2
📊
Player Stats Setup
Give every player Gold, XP and a Quest slot on the leaderboard
Locked
📊
Goal: Gold, XP and Quest tracking

We'll use the leaderstats folder so Roblox shows our stats on the leaderboard automatically.

Create PlayerSetup Script

  1. 1In ServerScriptService, insert a new Script, rename it PlayerSetup
  2. 2Paste this code:
ServerScriptService → PlayerSetup (Script)
local Players = game:GetService("Players") Players.PlayerAdded:Connect(function(player) local ls = Instance.new("Folder") ls.Name = "leaderstats" ls.Parent = player local gold = Instance.new("IntValue") gold.Name = "Gold" gold.Value = 0 gold.Parent = ls local xp = Instance.new("IntValue") xp.Name = "XP" xp.Value = 0 xp.Parent = ls -- Track how many quests completed player:SetAttribute("QuestsCompleted", 0) player:SetAttribute("ActiveQuest", "") end)
ℹ️
Attributes let you store extra data on a player that isn't shown in the leaderboard perfect for quest state.
✏️
Fill in the Blanks
+15 XP
To show stats on the Roblox leaderboard, you create a Folder named and parent it to the .
🧠
Knowledge Check
+15 XP
What type of Value object do we use to store Gold and XP as whole numbers?
AStringValue
BIntValue
CBoolValue
3
🧙
Create an NPC
Build the Village Elder who gives out quests
Locked
🧙
Goal: A talking NPC in the village

We'll use a ProximityPrompt so players press E to talk to the Elder and see a dialogue message.

Build the NPC Model

  1. 1In the Toolbox, search "NPC" and insert any free humanoid NPC into the village area
  2. 2Rename the NPC Model to VillageElder
  3. 3In the NPC's HumanoidRootPart, insert a ProximityPrompt
  4. 4Set the ProximityPrompt's ActionText = Talk, ObjectText = Village Elder, KeyboardKeyCode = E
  5. 5In the NPC Model, insert a Script, rename it ElderScript

NPC Dialogue Script

VillageElder → ElderScript (Script)
local prompt = script.Parent.HumanoidRootPart.ProximityPrompt local ReplicatedStorage = game:GetService("ReplicatedStorage") -- Create a RemoteEvent so the server can show dialogue on the client local dialogueEvent = Instance.new("RemoteEvent") dialogueEvent.Name = "ShowDialogue" dialogueEvent.Parent = ReplicatedStorage local lines = { "Welcome, brave adventurer!", "Our island is in danger. A great beast guards the volcano.", "Bring me 5 Ancient Crystals from the Ruins... and I'll show you the way." } prompt.Triggered:Connect(function(player) if player:GetAttribute("ActiveQuest") == "" then player:SetAttribute("ActiveQuest", "CollectCrystals") player:SetAttribute("CrystalsFound", 0) end dialogueEvent:FireClient(player, lines) end)
💡
The NPC won't move on its own that's fine for now. Later you can give it animations from the Toolbox.
💻
Code Challenge
+20 XP
Fill in the blanks to create a RemoteEvent for NPC dialogue:
local dialogueEvent = Instance.new("") dialogueEvent.Name = "ShowDialogue" dialogueEvent.Parent =
💡 Hint: RemoteEvents let the server talk to clients. They live in ReplicatedStorage.
🧠
Knowledge Check
+15 XP
What does a ProximityPrompt do in Roblox?
AShows a prompt when the player walks close to an object and presses a key
BMakes the NPC follow the player around
CTeleports the player to another part of the map
4
💬
Dialogue GUI
Show the Elder's words on screen as a dialogue box
Locked
💬
Goal: A dialogue box that shows NPC speech

A LocalScript on the client listens for the ShowDialogue RemoteEvent and displays each line one at a time.

Build the Dialogue Frame

  1. 1In StarterGui, insert a ScreenGui, rename it DialogueGui
  2. 2Inside it, insert a Frame set: Size = {0.6, 0}{0.18, 0}, Position = {0.2, 0}{0.78, 0}, BackgroundColor = dark navy (21, 31, 48), BackgroundTransparency = 0.1
  3. 3Inside the Frame, add a TextLabel: Size = {1,0}{0.6,0}, Position = {0,0}{0.1,0}, TextColor = white, Font = GothamBold, TextWrapped = true rename DialogueText
  4. 4Add another TextLabel for the NPC name: Size = {0.5,0}{0.3,0}, Position = {0.02,0}{0,0}, TextColor = #38bdf8 (sky blue), rename NPCName, Text = "Village Elder"
  5. 5Set the Frame's Visible = false to start hidden
  6. 6In StarterPlayerScripts, insert a LocalScript, rename DialogueClient
StarterPlayerScripts → DialogueClient (LocalScript)
local RS = game:GetService("ReplicatedStorage") local dialogueEvent = RS:WaitForChild("ShowDialogue") local gui = game.Players.LocalPlayer.PlayerGui:WaitForChild("DialogueGui") local frame = gui.Frame local textLabel = frame.DialogueText dialogueEvent.OnClientEvent:Connect(function(lines) frame.Visible = true for _, line in ipairs(lines) do textLabel.Text = line task.wait(3) end frame.Visible = false end)
🌟
Try it: Press Play, walk up to the Elder and press E the dialogue box should appear and cycle through all 3 lines then vanish!
True or False?
+15 XP
A LocalScript runs on the player's computer, not the server.
RemoteEvents can only send data from client to server, not server to client.
task.wait(3) pauses the script for 3 seconds before showing the next line.
🧠
Knowledge Check
+15 XP
Where should a LocalScript that controls GUI be placed?
AServerScriptService
BStarterPlayerScripts or StarterGui
CWorkspace
5
💎
Collectible Crystals
Scatter 5 glowing crystals in the Ruins for players to find
Locked
💎
Goal: Pick up 5 crystals to complete the quest

Each crystal glows cyan. Touching it adds 1 to the player's CrystalsFound attribute and then disappears.

Build a Crystal Part

  1. 1Insert a Part into the Ruins area set Size = (1.5, 2, 1.5), Material = Neon, Colour = Cyan
  2. 2Add a SpecialMesh inside it set MeshType = Diamond
  3. 3Add a PointLight Brightness = 3, Colour = Cyan, Range = 10
  4. 4Rename the Part Crystal
  5. 5Insert a Script inside the Crystal Part
Crystal → Script
local part = script.Parent local collected = false part.Touched:Connect(function(hit) if collected then return end local player = game.Players:GetPlayerFromCharacter(hit.Parent) if not player then return end if player:GetAttribute("ActiveQuest") ~= "CollectCrystals" then return end collected = true local count = player:GetAttribute("CrystalsFound") + 1 player:SetAttribute("CrystalsFound", count) player.leaderstats.XP.Value += 10 part.Transparency = 1 part.CanCollide = false if count >= 5 then player:SetAttribute("ActiveQuest", "ReturnToElder") end end)
  1. 6Right-click the Crystal in Explorer → Duplicate it 4 times (5 crystals total)
  2. 7Scatter them around the Ruins behind pillars, on ledges, hidden in corners
⚠️
Each Crystal has its own script with its own collected variable, so they work independently. Don't put one shared script outside it won't know which crystal was touched.
💻
Code Challenge
+20 XP
Fill in the blanks to check if the player is on the crystal quest and award XP:
if player:GetAttribute("") ~= "CollectCrystals" then return end player.leaderstats.XP.Value +=
💡 Hint: We check the ActiveQuest attribute and award 10 XP per crystal.
🧠
Knowledge Check
+15 XP
Why does each Crystal have its own script with its own collected variable?
ASo all crystals disappear at the same time
BBecause Roblox only allows one script per model
CSo each crystal tracks independently whether it has been collected
6
📋
Quest Tracker GUI
Show the active quest and crystal count on-screen
Locked
📋
Goal: A quest log in the top-left corner

Players always know what they need to do and how many crystals they've collected.

Build the Quest UI

  1. 1In StarterGui, insert a new ScreenGui, rename QuestGui
  2. 2Add a Frame Position = {0.01,0}{0.01,0}, Size = {0.28,0}{0.12,0}, BackgroundColor = navy, BackgroundTransparency = 0.2, corner radius 12
  3. 3Add a TextLabel for quest title rename QuestTitle, Size = {1,0}{0.4,0}, Text = "📋 Quest", TextColor = sky blue, FontFace = GothamBold
  4. 4Add another TextLabel for quest detail rename QuestDetail, Size = {1,0}{0.5,0}, Position = {0,0}{0.45,0}, TextColor = white, Text = "Talk to the Village Elder"
  5. 5In StarterPlayerScripts, insert a LocalScript, rename QuestTracker
StarterPlayerScripts → QuestTracker (LocalScript)
local player = game.Players.LocalPlayer local gui = player.PlayerGui:WaitForChild("QuestGui") local detail = gui.Frame.QuestDetail local function updateQuest() local quest = player:GetAttribute("ActiveQuest") local found = player:GetAttribute("CrystalsFound") or 0 if quest == "" then detail.Text = "Talk to the Village Elder" elseif quest == "CollectCrystals" then detail.Text = "💎 Crystals: " .. found .. " / 5" elseif quest == "ReturnToElder" then detail.Text = "🧙 Return to the Elder!" elseif quest == "SlayBoss" then detail.Text = "⚔️ Defeat the Volcano Beast!" elseif quest == "Complete" then detail.Text = "✅ Quest Complete! You saved the island!" end end player.AttributeChanged:Connect(updateQuest) updateQuest()
🔮
Predict What Happens
+15 XP
The player has collected 4 crystals. They touch the 5th crystal. The script sets ActiveQuest to "ReturnToElder".

What will the Quest Tracker display?
A"💎 Crystals: 5 / 5"
B"🧙 Return to the Elder!"
C"✅ Quest Complete!"
🧠
Knowledge Check
+15 XP
What event fires the updateQuest function every time a player attribute changes?
Aplayer.AttributeChanged
Bplayer.CharacterAdded
CRunService.Heartbeat
7
🏪
Quest Turn-In & Item Shop
Return crystals to the Elder and buy a sword from the shop
Locked
🏪
Goal: Turn in the crystal quest and buy a weapon

Update the Elder's dialogue for returning players, award Gold, and add a shop NPC that sells a sword tool.

Update ElderScript for Quest Turn-In

Open VillageElder → ElderScript and replace the Triggered function with this updated version:

VillageElder → ElderScript — updated Triggered
prompt.Triggered:Connect(function(player) local quest = player:GetAttribute("ActiveQuest") if quest == "" then player:SetAttribute("ActiveQuest", "CollectCrystals") player:SetAttribute("CrystalsFound", 0) dialogueEvent:FireClient(player, lines) elseif quest == "ReturnToElder" then player.leaderstats.Gold.Value += 100 player:SetAttribute("ActiveQuest", "SlayBoss") local rewardLines = { "You found them all! You are braver than I thought.", "Take this Gold buy a blade from the Merchant.", "Then face the beast at the volcano. Good luck!" } dialogueEvent:FireClient(player, rewardLines) else dialogueEvent:FireClient(player, {"Be brave, adventurer. The beast awaits!"}) end end)

Add a Merchant NPC

  1. 1Insert another NPC from the Toolbox near the village rename it Merchant
  2. 2Add a ProximityPrompt: ActionText = Buy Sword (50G), ObjectText = Merchant
  3. 3Get a free sword from the Toolbox (search "sword") drag it into ServerStorage, rename IslandSword
  4. 4Insert a Script in the Merchant model:
Merchant → Script
local prompt = script.Parent.HumanoidRootPart.ProximityPrompt local sword = game.ServerStorage.IslandSword prompt.Triggered:Connect(function(player) local gold = player.leaderstats.Gold if gold.Value >= 50 then gold.Value -= 50 local clone = sword:Clone() clone.Parent = player.Backpack end end)
💻
Code Challenge
+20 XP
Fill in the blanks for the Merchant's sword shop logic:
if gold.Value >= then gold.Value -= 50 local clone = sword:() clone.Parent = player.Backpack end
💡 Hint: The sword costs 50 Gold. We use Clone() to make a copy of the sword from ServerStorage.
🧠
Knowledge Check
+15 XP
Why do we Clone the sword instead of moving the original from ServerStorage?
ABecause ServerStorage is read-only
BSo the original stays in ServerStorage for other players to buy too
CRoblox doesn't allow moving objects between services
8
🐉
The Boss Fight
Create the Volcano Beast a giant enemy with a health bar
Locked
🐉
Goal: A powerful boss that chases and attacks players

The Volcano Beast has 200 HP, a floating health bar, and hurts players on contact. Defeat it to win the game!

Build the Boss Model

  1. 1On the volcano platform, insert a Part Size = (8, 12, 8), Material = Neon, Colour = Really Red, Anchored = false, rename BossBody
  2. 2Add a Humanoid inside BossBody set MaxHealth = 200, Health = 200
  3. 3Add a BillboardGui inside BossBody: Size = {4,0}{0.8,0}, StudsOffset = (0, 8, 0), AlwaysOnTop = true
  4. 4Inside the BillboardGui, add a Frame (full size, dark bg), then a smaller red Frame named HealthFill
  5. 5Add a TextLabel above: Text = "🐉 Volcano Beast", TextColor = red
  6. 6Group BossBody into a Model named VolcanoBoss, insert a Script:
VolcanoBoss → Script
local boss = script.Parent local body = boss.BossBody local humanoid = body.Humanoid local healthFill = body.BillboardGui.Frame.HealthFill local RS = game:GetService("RunService") local Players = game:GetService("Players") -- Update health bar humanoid.HealthChanged:Connect(function(hp) healthFill.Size = UDim2.new(hp / humanoid.MaxHealth, 0, 1, 0) end) -- Damage players on touch body.Touched:Connect(function(hit) local h = hit.Parent:FindFirstChildOfClass("Humanoid") if h and h ~= humanoid then h.Health -= 25 end end) -- Chase nearest player RS.Heartbeat:Connect(function() local nearest, minDist = nil, math.huge for _, p in ipairs(Players:GetPlayers()) do if p.Character then local d = (body.Position - p.Character.HumanoidRootPart.Position).Magnitude if d < minDist then nearest = p.Character; minDist = d end end end if nearest then humanoid:MoveTo(nearest.HumanoidRootPart.Position) end end)
⚠️
The boss needs a Humanoid to use MoveTo. Without it the movement won't work. Make sure Humanoid is directly inside BossBody (the Part), not in the Model.
True or False?
+15 XP
The boss needs a Humanoid inside BossBody for MoveTo to work.
A BillboardGui is only visible when the player is standing next to the boss.
RunService.Heartbeat runs code every single frame, so the boss constantly chases players.
🧠
Knowledge Check
+15 XP
How does the boss's health bar shrink as it takes damage?
AThe bar's colour changes from green to red
BThe bar disappears completely when hit
CThe HealthFill frame's Size is set to hp / MaxHealth on each HealthChanged event
9
🏆
Win Condition
Detect when the boss dies and show the victory screen
Locked
🏆
Goal: Trigger a win screen when the boss is defeated

When the boss's health reaches zero, we fire a RemoteEvent to every player and show a big victory banner.

Boss Death Detection

Add this at the bottom of VolcanoBoss → Script:

VolcanoBoss → Script add at the bottom
local winEvent = Instance.new("RemoteEvent") winEvent.Name = "BossDefeated" winEvent.Parent = game.ReplicatedStorage humanoid.Died:Connect(function() for _, p in ipairs(Players:GetPlayers()) do p.leaderstats.Gold.Value += 200 p.leaderstats.XP.Value += 100 p:SetAttribute("ActiveQuest", "Complete") end winEvent:FireAllClients() body.Transparency = 1 body.CanCollide = false end)

Victory Screen GUI

  1. 1In StarterGui, insert a ScreenGui, rename WinGui
  2. 2Add a full-screen Frame: Size = {1,0}{1,0}, dark navy background, Transparency = 0.15, Visible = false
  3. 3Add a centre TextLabel: Text = "⚔️ VICTORY! ⚔️", Font = FredokaOne, large text, sky blue
  4. 4Add a sub-label: Text = "You defeated the Volcano Beast and saved the island!"
  5. 5In StarterPlayerScripts, add a LocalScript named WinClient:
StarterPlayerScripts → WinClient (LocalScript)
local RS = game:GetService("ReplicatedStorage") local winEvent = RS:WaitForChild("BossDefeated") local gui = game.Players.LocalPlayer.PlayerGui:WaitForChild("WinGui") winEvent.OnClientEvent:Connect(function() gui.Frame.Visible = true end)
🌟
Test this by pressing Play and attacking the boss with your sword until its health bar empties. The win screen should appear for everyone!
✏️
Fill in the Blanks
+15 XP
When the boss dies, we call on the RemoteEvent to notify every player, and set ActiveQuest to .
🧠
Knowledge Check
+15 XP
What is the difference between FireClient and FireAllClients?
AFireClient sends to one specific player; FireAllClients sends to every player
BThey do the same thing
CFireAllClients only works in Studio, not in a real game
10
🎒
Inventory & Loot Items
Scatter treasure chests with random loot drops
Locked
🎒
Goal: Hidden treasure chests that drop Gold or Potions

Click a chest to open it and get a random loot reward. Potions restore health; Gold goes into the leaderboard.

Build a Treasure Chest

  1. 1Insert a Part Size = (3, 2, 2), Material = Wood, Colour = medium brown. Rename TreasureChest
  2. 2Add a SpecialMesh MeshType = Brick (gives a nice box shape)
  3. 3Add a ClickDetector inside the Part
  4. 4Add a PointLight Colour = Gold, Brightness = 2, Range = 8
  5. 5Insert a Script inside TreasureChest:
TreasureChest → Script
local chest = script.Parent local detector = chest.ClickDetector local opened = false local lootTable = { {type = "Gold", amount = 25}, {type = "Gold", amount = 50}, {type = "Gold", amount = 75}, {type = "Potion", amount = 50}, {type = "XP", amount = 30}, } detector.MouseClick:Connect(function(player) if opened then return end opened = true local loot = lootTable[math.random(#lootTable)] local ls = player.leaderstats if loot.type == "Gold" then ls.Gold.Value += loot.amount elseif loot.type == "Potion" then local char = player.Character if char then char.Humanoid.Health += loot.amount end elseif loot.type == "XP" then ls.XP.Value += loot.amount end -- Open the chest visually chest.BrickColor = BrickColor.new("Bright yellow") chest.Material = Enum.Material.Neon task.wait(2) chest.Transparency = 1 chest.CanCollide = false end)
  1. 6Duplicate the chest 5 times and hide them around the island in caves, behind trees, at the foot of the ruins
🔮
Predict What Happens
+15 XP
A player clicks a treasure chest. The lootTable randomly picks {type = "Potion", amount = 50}.

What happens to the player?
AThey gain 50 Gold on the leaderboard
BThey get a potion tool in their Backpack
CTheir character's Health increases by 50
🧠
Knowledge Check
+15 XP
What does math.random(#lootTable) do?
AAlways returns the first item in the table
BPicks a random number between 1 and the length of the table
CShuffles the table into a random order
11
💾
Save Player Data
Use DataStores so Gold and XP save between sessions
Locked
💾
Goal: Persistent Gold and XP across play sessions

We'll update PlayerSetup to load saved data on join and save it when the player leaves.

⚠️
Enable API Services first: Game Settings → Security → turn on Enable Studio Access to API Services. DataStores won't work without it.

Update PlayerSetup for Saving

Replace the whole PlayerSetup script with this version:

ServerScriptService → PlayerSetup (Script) — full replace
local Players = game:GetService("Players") local DSS = game:GetService("DataStoreService") local store = DSS:GetDataStore("IslandQuestV1") Players.PlayerAdded:Connect(function(player) local ls = Instance.new("Folder") ls.Name = "leaderstats" ls.Parent = player local gold = Instance.new("IntValue") gold.Name = "Gold"; gold.Parent = ls local xp = Instance.new("IntValue") xp.Name = "XP"; xp.Parent = ls player:SetAttribute("QuestsCompleted", 0) player:SetAttribute("ActiveQuest", "") player:SetAttribute("CrystalsFound", 0) -- Load saved data local ok, data = pcall(function() return store:GetAsync("player_" .. player.UserId) end) if ok and data then gold.Value = data.Gold or 0 xp.Value = data.XP or 0 end end) Players.PlayerRemoving:Connect(function(player) pcall(function() store:SetAsync("player_" .. player.UserId, { Gold = player.leaderstats.Gold.Value, XP = player.leaderstats.XP.Value }) end) end)
💻
Code Challenge
+20 XP
Fill in the blanks to save player data when they leave:
Players.PlayerRemoving:Connect(function(player) (function() store:("player_" .. player.UserId, { Gold = player.leaderstats.Gold.Value }) end) end)
💡 Hint: pcall protects against errors. SetAsync saves data to the DataStore.
🧠
Knowledge Check
+15 XP
Why do we wrap DataStore calls in pcall?
ATo make the code run faster
BTo encrypt the player's data
CTo catch errors safely so the script doesn't crash if the DataStore is down
12
🌴
Polish & Atmosphere
Lighting, music and decorations to make the island feel alive
Locked
🌴
Goal: A beautiful, immersive island world

Add ambient sounds, tropical lighting, volcano fire effects and palm tree decorations.

Lighting Setup

  1. 1Click Lighting in Explorer → set: Brightness = 2.5, Ambient = (170, 195, 255) (cool blue sky), OutdoorAmbient = (160, 200, 255)
  2. 2Insert Sky in Lighting set SkyboxBk/Dn/Ft/Lt/Rt/Up = any sky asset IDs from the Toolbox (search "tropical sky")
  3. 3Insert ColorCorrection in Lighting Saturation = 0.1 (makes colours pop), Contrast = 0.05
  4. 4Insert Atmosphere in Lighting Density = 0.2, Haze = 0.5, Glare = 0.2 (gives a warm island haze)

Volcano Fire Effects

  1. 5On the volcano top, insert a Part (flat, red Neon) add a Fire effect inside: Color = orange, Size = 10, Heat = 9
  2. 6Add several PointLights around the rim orange colour, Brightness 3, Range 20

Ambient Sounds

  1. 7In Workspace, insert a Sound search Toolbox for a free "tropical ambient" or "ocean waves" sound, paste the SoundId. Set Looped = true, Volume = 0.4
  2. 8In ServerScriptService, insert a Script:
ServerScriptService → AmbientMusic (Script)
game.Workspace:WaitForChild("Sound"):Play()

Palm Tree Decorations

  1. 9Search the Toolbox for "palm tree" insert 5–8 palm trees along the beach and jungle edge
  2. 10Search for "tropical flowers" or "fern" scatter around the ruins for overgrown atmosphere
💡
Select all your palm trees, right-click → Group them into a Decorations Model so Explorer stays organised.
🔢
Put It In Order
+15 XP
Click these polish steps in a logical order:
Add palm trees and flowers for decoration
Set up Lighting, Sky and Atmosphere properties
Add Fire effects and PointLights to the volcano
Insert ambient ocean sound and play it with a script
🧠
Knowledge Check
+15 XP
What does the Atmosphere object in Lighting do?
AIt changes the gravity of the game world
BIt adds haze, glare and density effects to create a realistic atmospheric look
CIt makes all Parts transparent
13
🧪
Full Playthrough Test
Complete the entire game from start to finish and fix any issues
Locked
🧪
Goal: Make sure the whole game works

Play through every step talk to the Elder, collect crystals, buy the sword, fight the boss — and check for bugs.

Full Playthrough Checklist

  1. 1Click Play in the toolbar to enter the game
  2. 2Walk up to the Village Elder and press E dialogue appears, quest assigned
  3. 3Quest Tracker updates to show "💎 Crystals: 0 / 5"
  4. 4Head to the Ruins and collect all 5 crystals tracker updates each time
  5. 5Return to the Elder get 100 Gold reward, quest changes to "Slay Boss"
  6. 6Go to the Merchant and buy the sword for 50 Gold
  7. 7Head to the Volcano the Volcano Beast chases you
  8. 8Attack the boss with the sword health bar decreases
  9. 9Boss defeated Victory screen appears, Gold and XP awarded
  10. 10Open some Treasure Chests along the way loot drops work
⚠️
Common fixes: If the boss doesn't move check Humanoid is inside BossBody. If the dialogue doesn't appear check ShowDialogue RemoteEvent exists in ReplicatedStorage. If crystals don't collect check the player has talked to the Elder first (ActiveQuest must be set).
👋
Grown-up note: Help your child use the Output window (View → Output) to see script error messages in red. These point to the exact line with the problem.
True or False?
+15 XP
If the NPC dialogue doesn't appear, you should check that the ShowDialogue RemoteEvent exists in ReplicatedStorage.
The Output window (View → Output) shows script error messages in red.
Crystals can be collected even if the player hasn't talked to the Village Elder first.
🧠
Knowledge Check
+15 XP
If the boss doesn't move when you play-test, what is the most likely cause?
AThe PointLight brightness is too low
BThe DataStore is not enabled
CThe Humanoid is missing or not inside BossBody
14
🚀
Publish to Roblox!
Share your island RPG with the world
Locked
🚀
Goal: Get your game live on Roblox

Anyone with the link will be able to explore your island, complete quests and fight the boss!

Publish Your Game

  1. 1Click File → Publish to Roblox As… (or press Ctrl+Shift+P)
  2. 2Give your game a name — something like "Island Quest RPG 🗺️"
  3. 3Write a short description: "Explore a tropical island, complete quests and defeat the Volcano Beast!"
  4. 4Set Genre to Adventure
  5. 5Click Create
  6. 6After publishing, go to Game Settings → Permissions and set to Public
  7. 7Click the Roblox button in the toolbar to open your game page copy the link and share it!
💡
Add a thumbnail: On your game page, upload a screenshot as the game icon. Games with good thumbnails get way more players!
🌟
Ideas to expand your game: Add more NPCs with different quests · Build a second dungeon area · Add a level-up system using XP · Give the boss a ranged fireball attack · Add multiplayer co-op boss events!
👋
Grown-up note: Roblox games are only visible to others when set to Public. Private mode is great for ongoing development. You can always take it public, then back to private if changes are needed.
✏️
Fill in the Blanks
+15 XP
To publish your game, go to File → . To let others play, set Permissions to .
🧠
Final Knowledge Check
+15 XP
Which of these did you NOT build in this workshop?
AA quest system with NPC dialogue
BA vehicle racing system
CA boss fight with a health bar
DA loot and treasure chest system
🗺️ ⚔️ 🏆 🌴 🐉
You Completed Island Quest!

Amazing work! You built a full RPG adventure with NPCs, quests, a loot system and a boss fight. You've finished the entire My First Roblox Studio Game series you're now a real Roblox developer!

0
Total XP
1
Level
0
Best Streak
0%
Accuracy
🎮 Back to the Series Hub ⭐ View My Progress & Certificates

This workshop was free and took many hours to build. If it helped you learn something new, consider supporting the project.

☕ Support on Ko-fi